[Tux3] Updates to tux3fuse.c
Tero Roponen
tero.roponen at gmail.com
Mon Oct 20 00:39:13 PDT 2008
Hi,
here are some updates/fixes to tux3fuse.c. I recently got a new laptop,
so this should work somewhat better on 64-bit systems.
diff -r ad2b6e96b08f user/test/tux3fuse.c
--- a/user/test/tux3fuse.c Sun Oct 19 01:51:27 2008 -0700
+++ b/user/test/tux3fuse.c Mon Oct 20 10:34:03 2008 +0300
@@ -49,7 +49,6 @@
#define FUSE_USE_VERSION 27
#include <fuse.h>
#include <fuse/fuse_lowlevel.h>
-#include <fuse/fuse_lowlevel_compat.h>
#define include_inode_c
#include "inode.c"
@@ -59,34 +58,48 @@
static struct sb *sb;
static struct dev *dev;
-static struct inode *ino2inode(fuse_ino_t ino)
+static struct inode *open_fuse_ino(fuse_ino_t ino)
{
- if (ino == 1)
+ struct inode *inode;
+ if (ino == FUSE_ROOT_ID)
return sb->rootdir;
- return (struct inode *)ino;
+
+ inode = new_inode(sb, ino);
+ if (inode) {
+ if (!open_inode(inode))
+ return inode;
+ free_inode(inode);
+ }
+
+ return NULL;
}
static void tux3_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
{
- struct inode *inode = tuxopen(ino2inode(parent), name, strlen(name));
+ fprintf(stderr, "tux3_lookup(%Lx, '%s')\n", (L)parent, name);
+ struct inode *inode = tuxopen(sb->rootdir, name, strlen(name));
- if (inode)
- {
+ if (inode) {
struct fuse_entry_param ep = {
- .attr.st_mode = inode->i_mode,
- .attr.st_atime = inode->i_atime,
- .attr.st_mtime = inode->i_mtime,
- .attr.st_ctime = inode->i_ctime,
- .attr.st_size = inode->i_size,
- .attr.st_uid = inode->i_uid,
- .attr.st_gid = inode->i_gid,
- .attr.st_nlink = inode->i_links,
+ .attr = {
+ .st_ino = inode->inum,
+ .st_mode = inode->i_mode,
+ .st_atime = inode->i_atime,
+ .st_mtime = inode->i_mtime,
+ .st_ctime = inode->i_ctime,
+ .st_size = inode->i_size,
+ .st_uid = inode->i_uid,
+ .st_gid = inode->i_gid,
+ .st_nlink = inode->i_links,
+ },
- .ino = (fuse_ino_t)inode,
+ .ino = inode->inum,
.generation = 1,
- .attr_timeout = 1.0,
- .entry_timeout = 1.0,
+ .attr_timeout = 0.0,
+ .entry_timeout = 0.0,
};
+
+ tuxclose(inode);
fuse_reply_entry(req, &ep);
} else {
@@ -96,17 +109,22 @@
static void tux3_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
{
- printf("---- open file ----\n");
- printf("flags: %i\n", fi->flags);
- fi->flags |= 0666;
- fuse_reply_open(req, fi);
+ fprintf(stderr, "tux3_open(%Lx)\n", (L)ino);
+ struct inode *inode = open_fuse_ino(ino);
+ if (inode) {
+ fi->flags |= 0666;
+ fi->fh = (uint64_t)(unsigned long)inode;
+ fuse_reply_open(req, fi);
+ } else {
+ fuse_reply_err(req, ENOENT);
+ }
}
static void tux3_read(fuse_req_t req, fuse_ino_t ino, size_t size,
off_t offset, struct fuse_file_info *fi)
{
- printf("---- read file ----\n");
- struct inode *inode = ino2inode(ino);
+ fprintf(stderr, "tux3_read(%Lx)\n", (L)ino);
+ struct inode *inode = (struct inode *)(unsigned long)fi->fh;
struct file *file = &(struct file){ .f_inode = inode };
printf("userspace tries to seek to %Li\n", (L)offset);
@@ -143,29 +161,30 @@
static void tux3_create(fuse_req_t req, fuse_ino_t parent, const char *name,
mode_t mode, struct fuse_file_info *fi)
{
- printf("---- create file ----\n");
- struct inode *inode = tuxcreate(ino2inode(parent), name, strlen(name),
+ fprintf(stderr, "tux3_create(%Lx, '%s')\n", (L)parent, name);
+ struct inode *inode = tuxcreate(sb->rootdir, name, strlen(name),
&(struct iattr){ .mode = mode | 0666 });
- if (inode)
- {
+ if (inode) {
struct fuse_entry_param fep = {
- .attr.st_mode = inode->i_mode,
- .attr.st_atime = inode->i_atime,
- .attr.st_mtime = inode->i_mtime,
- .attr.st_ctime = inode->i_ctime,
- .attr.st_size = inode->i_size,
- .attr.st_uid = inode->i_uid,
- .attr.st_gid = inode->i_gid,
- .attr.st_nlink = inode->i_links,
+ .attr = {
+ .st_ino = inode->inum,
+ .st_mode = inode->i_mode,
+ .st_atime = inode->i_atime,
+ .st_mtime = inode->i_mtime,
+ .st_ctime = inode->i_ctime,
+ .st_size = inode->i_size,
+ .st_uid = inode->i_uid,
+ .st_gid = inode->i_gid,
+ .st_nlink = inode->i_links,
+ },
- .ino = (fuse_ino_t)inode,
+ .ino = inode->inum,
.generation = 1,
- .attr_timeout = 1.0,
- .entry_timeout = 1.0,
+ .attr_timeout = 0.0,
+ .entry_timeout = 0.0,
};
- dump_attrs(inode);
-
+ fi->fh = (uint64_t)(unsigned long)inode;
fuse_reply_create(req, &fep, fi);
} else {
fuse_reply_err(req, ENOMEM);
@@ -174,29 +193,14 @@
static void tux3_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode)
{
- printf("---- create directory ----\n");
- struct inode *inode = tuxcreate(ino2inode(parent), name, strlen(name),
- &(struct iattr){ .mode = mode | 0666 });
- if (inode)
- {
- struct fuse_entry_param fep = {
- .ino = (fuse_ino_t)inode,
- .generation = 1,
- .attr.st_mode = mode | 0666,
- .attr_timeout = 1.0,
- .entry_timeout = 1.0,
- };
-
- fuse_reply_entry(req, &fep);
- } else {
- fuse_reply_err(req, ENOMEM);
- }
+ fuse_reply_err(req, ENOSYS);
}
static void tux3_write(fuse_req_t req, fuse_ino_t ino, const char *buf,
size_t size, off_t offset, struct fuse_file_info *fi)
{
- struct inode *inode = ino2inode(ino);
+ fprintf(stderr, "tux3_write(%Lx)\n", (L)ino);
+ struct inode *inode = (struct inode *)(unsigned long)fi->fh;
struct file *file = &(struct file){ .f_inode = inode };
if (offset) {
@@ -225,6 +229,7 @@
static void _tux3_getattr(struct inode *inode, struct stat *st)
{
+ st->st_ino = inode->inum;
st->st_mode = inode->i_mode;
st->st_atime = inode->i_atime;
st->st_mtime = inode->i_mtime;
@@ -237,12 +242,42 @@
static void tux3_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
{
- struct stat st;
- _tux3_getattr(ino2inode(ino), &st);
- fuse_reply_attr(req, &st, 0.0);
+ fprintf(stderr, "tux3_getattr(%Lx)\n", (L)ino);
+ struct inode *inode = open_fuse_ino(ino);
+ if (inode) {
+ struct stat stbuf;
+ _tux3_getattr(inode, &stbuf);
+ fuse_reply_attr(req, &stbuf, 0.0);
+ } else {
+ fuse_reply_err(req, ENOENT);
+ }
}
-struct fillstate { char *dirent; int done; };
+static void tux3_opendir(fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info *fi)
+{
+ fprintf(stderr, "tux3_opendir(%Lx)\n", (L)ino);
+ struct inode *inode = open_fuse_ino(ino);
+ if (inode) {
+ fi->fh = (uint64_t)(unsigned long)inode;
+ fuse_reply_open(req, fi);
+ } else {
+ fuse_reply_err(req, ENOENT);
+ }
+}
+
+static void tux3_releasedir(fuse_req_t req, fuse_ino_t ino,
+ struct fuse_file_info *fi)
+{
+ fprintf(stderr, "tux3_releasedir(%Lx)\n", (L)ino);
+ if (ino != FUSE_ROOT_ID) {
+ struct inode *inode = (struct inode *)(unsigned long)fi->fh;
+ tuxclose(inode);
+ }
+ fuse_reply_err(req, 0); /* Success */
+}
+
+struct fillstate { char *dirent; int done; unsigned inode; unsigned type;};
int tux3_filler(void *info, char *name, unsigned namelen, loff_t offset, unsigned inode, unsigned type)
{
@@ -252,6 +287,8 @@
printf("'%.*s'\n", namelen, name);
memcpy(state->dirent, name, namelen);
state->dirent[namelen] = 0;
+ state->inode = inode;
+ state->type = type;
state->done = 1;
return 0;
}
@@ -260,29 +297,27 @@
static void tux3_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t offset,
struct fuse_file_info *fi)
{
- struct inode *inode = ino2inode(ino);
+ fprintf(stderr, "tux3_readdir(%Lx)\n", (L)ino);
+ struct inode *inode = (struct inode *)(unsigned long)fi->fh;
struct file *dirfile = &(struct file){ .f_inode = inode, .f_pos = offset };
char dirent[EXT2_NAME_LEN + 1];
- char buf[1024]; //XXX
+ char buf[size];
while (dirfile->f_pos < dirfile->f_inode->i_size) {
- if ((errno = -ext2_readdir(dirfile, &(struct fillstate){ .dirent = dirent }, tux3_filler)))
- {
+ struct fillstate fstate = { .dirent = dirent };
+ if ((errno = -ext2_readdir(dirfile, &fstate, tux3_filler))) {
fuse_reply_err(req, errno);
return;
+ } else {
+ size_t len;
+ struct stat stbuf = {
+ .st_ino = fstate.inode,
+ .st_mode = fstate.type,
+ };
+ len = fuse_add_direntry(req, buf, size, dirent, &stbuf, dirfile->f_pos);
+ fuse_reply_buf(req, buf, len);
+ return;
}
-
- struct stat st;
- struct inode *inode2 = tuxopen(inode, dirent, strlen(dirent));
- if (!inode2)
- continue;
-
- _tux3_getattr(inode2, &st);
-
- int len = fuse_dirent_size(strlen(dirent));
- fuse_add_direntry(req, buf, sizeof(buf), dirent, &st, dirfile->f_pos);
- fuse_reply_buf(req, buf, len);
- return;
}
fuse_reply_buf(req, NULL, 0);
@@ -290,12 +325,14 @@
static void tux3_unlink(fuse_req_t req, fuse_ino_t parent, const char *name)
{
- printf("---- delete file ----\n");
+ fprintf(stderr, "tux3_unlink(%Lx, '%s')\n", (L)parent, name);
struct buffer *buffer;
- ext2_dirent *entry = ext2_find_entry(ino2inode(parent), name, strlen(name), &buffer);
+ ext2_dirent *entry = ext2_find_entry(sb->rootdir, name, strlen(name), &buffer);
if (!entry)
goto noent;
- struct inode inode = { .sb = sb, .inum = entry->inum };
+ inum_t inum = entry->inum;
+ //brelse(buffer); //brelse: Failed assertion "buffer->count"!
+ struct inode inode = { .sb = sb, .inum = inum };
if ((errno = -open_inode(&inode)))
goto eek;
@@ -373,19 +410,28 @@
static void tux3_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
int to_set, struct fuse_file_info *fi)
{
- struct inode *inode = ino2inode(ino);
+ fprintf(stderr, "tux3_setattr(%Lx)\n", (L)ino);
+ struct inode *inode = open_fuse_ino(ino);
+ if (!inode) {
+ fuse_reply_err(req, ENOENT);
+ return;
+ }
if (to_set & FUSE_SET_ATTR_MODE) {
printf("Setting mode\n");
+ inode->i_mode = attr->st_mode;
}
if (to_set & FUSE_SET_ATTR_UID) {
printf("Setting uid\n");
+ inode->i_uid = attr->st_uid;
}
if (to_set & FUSE_SET_ATTR_GID) {
printf("Setting gid\n");
+ inode->i_gid = attr->st_gid;
}
if (to_set & FUSE_SET_ATTR_SIZE) {
printf("Setting size\n");
+ inode->i_size = attr->st_size;
}
if (to_set & FUSE_SET_ATTR_ATIME) {
printf("Setting atime to %Lu\n", (L)attr->st_atime);
@@ -395,15 +441,24 @@
if (to_set & FUSE_SET_ATTR_MTIME) {
printf("Setting mtime to %Lu\n", (L)attr->st_mtime);
inode->i_mtime = attr->st_mtime;
- inode->present |= MTIME_ATTR;
+ inode->present |= MTIME_BIT;
}
if (save_inode(inode))
printf("save_inode error\n");
- struct stat st;
- _tux3_getattr(inode, &st);
- fuse_reply_attr(req, &st, 1.0);
+ tuxsync(inode);
+ sync_super(sb);
+
+ struct stat stbuf;
+ _tux3_getattr(inode, &stbuf);
+
+ dump_attrs(inode);
+
+ if (ino != FUSE_ROOT_ID)
+ tuxclose(inode);
+
+ fuse_reply_attr(req, &stbuf, 0.0);
}
static void tux3_readlink(fuse_req_t req, fuse_ino_t ino)
@@ -451,18 +506,6 @@
fuse_reply_err(req, 0);
}
-static void tux3_opendir(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi)
-{
- fuse_reply_open(req, fi); /* Success */
-}
-
-static void tux3_releasedir(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi)
-{
- fuse_reply_err(req, 0); /* Success */
-}
-
static void tux3_fsyncdir(fuse_req_t req, fuse_ino_t ino,
int datasync, struct fuse_file_info *fi)
{
@@ -476,7 +519,11 @@
static void tux3_release(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
{
- fuse_reply_err(req, ENOSYS);
+ if (ino != FUSE_ROOT_ID) {
+ struct inode *inode = (struct inode *)(unsigned long)fi->fh;
+ tuxclose(inode);
+ }
+ fuse_reply_err(req, 0);
}
static void tux3_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
@@ -488,31 +535,46 @@
static void tux3_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
const char *value, size_t size, int flags)
{
- struct inode *inode = ino2inode(ino);
+ fprintf(stderr, "tux3_setxattr(%Lx, '%s'='%s')\n", (L)ino, name, value);
+ struct inode *inode = open_fuse_ino(ino);
+ if (!inode) {
+ fuse_reply_err(req, ENOENT);
+ return;
+ }
+
struct xattr *xattr = get_xattr(inode, (char *)name, strlen(name));
if (flags == XATTR_CREATE && xattr) {
fuse_reply_err(req, EEXIST);
- } else if (flags == XATTR_REPLACE && !xattr) {
- fuse_reply_err(req, ENOENT);
+ } else if (flags == XATTR_REPLACE && !xattr) {
+ fuse_reply_err(req, ENODATA);
} else {
int err;
err = -set_xattr(inode, (char *)name, strlen(name), (void *)value, size);
- if (!err)
- {
+ if (!err) {
tuxsync(inode);
sync_super(sb);
}
fuse_reply_err(req, err);
}
+
+ if (ino != FUSE_ROOT_ID)
+ tuxclose(inode);
}
static void tux3_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name, size_t size)
{
- struct inode *inode = ino2inode(ino);
+ fprintf(stderr, "tux3_getxattr(%Lx, '%s')\n", (L)ino, name);
+ struct inode *inode = open_fuse_ino(ino);
+ if (!inode) {
+ fuse_reply_err(req, ENOENT);
+ return;
+ }
+
struct xattr *xattr = get_xattr(inode, (char *)name, strlen(name));
+
if (!xattr) {
- fuse_reply_err(req, ENOENT);
+ fuse_reply_err(req, ENODATA);
} else if (size == 0) {
fuse_reply_xattr(req, xattr->size);
} else if (size < xattr->size) {
@@ -520,6 +582,9 @@
} else {
fuse_reply_buf(req, xattr->body, xattr->size);
}
+
+ if (ino != FUSE_ROOT_ID)
+ tuxclose(inode);
}
static void tux3_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
_______________________________________________
Tux3 mailing list
Tux3 at tux3.org
http://tux3.org/cgi-bin/mailman/listinfo/tux3
More information about the Tux3
mailing list