From: Csaba H. <csa...@cr...> - 2007-06-28 13:28:36
|
Hi Miklos, I've seen your "file as directory" implementation on LKML [ http://groups.google.com/group/linux.kernel/browse_frm/thread/995635ba54bdf192 ]. Neither the inlined kernel patch, nor the referenced fuse-enter.patch seems to include the kernelspace changes for FUSE. Where are those? Csaba |
From: Miklos S. <mi...@sz...> - 2007-06-28 18:46:57
|
> I've seen your "file as directory" implementation on LKML [ > > http://groups.google.com/group/linux.kernel/browse_frm/thread/995635ba54bdf192 > > ]. > > Neither the inlined kernel patch, nor the referenced fuse-enter.patch > seems to include the kernelspace changes for FUSE. > > Where are those? Hmm, maybe I forgot to upload it. Here it is: Index: linux/fs/fuse/dir.c =================================================================== --- linux.orig/fs/fuse/dir.c 2007-05-22 10:38:31.000000000 +0200 +++ linux/fs/fuse/dir.c 2007-05-22 13:18:53.000000000 +0200 @@ -1243,6 +1243,48 @@ static int fuse_removexattr(struct dentr return err; } +static int fuse_enter(struct nameidata *nd, struct path *newpath) +{ + struct inode *inode = nd->dentry->d_inode; + struct fuse_conn *fc = get_fuse_conn(inode); + struct fuse_req *req; + struct fuse_enter_out outarg; + int err; + + if (fc->no_enter) + return -ENOTDIR; + + req = fuse_get_req(fc); + if (IS_ERR(req)) + return PTR_ERR(req); + + req->in.h.opcode = FUSE_ENTER; + req->in.h.nodeid = get_node_id(inode); + req->out.numargs = 1; + req->out.args[0].size = sizeof(outarg); + req->out.args[0].value = &outarg; + request_send(fc, req); + err = req->out.h.error; + fuse_put_request(fc, req); + + if (!err) { + struct file *file = (void *) (long) outarg.fd; + err = -ENOENT; + if (file) { + err = 0; + *newpath = file->f_path; + pathget(newpath); + fput(file); + } + } else if (err == -ENOSYS) { + fc->no_enter = 1; + err = -ENOTDIR; + } + + return err; + +} + static const struct inode_operations fuse_dir_inode_operations = { .lookup = fuse_lookup, .mkdir = fuse_mkdir, @@ -1279,6 +1321,7 @@ static const struct inode_operations fus .getxattr = fuse_getxattr, .listxattr = fuse_listxattr, .removexattr = fuse_removexattr, + .enter = fuse_enter, }; static const struct inode_operations fuse_symlink_inode_operations = { Index: linux/include/linux/fuse.h =================================================================== --- linux.orig/include/linux/fuse.h 2007-05-22 10:38:31.000000000 +0200 +++ linux/include/linux/fuse.h 2007-05-22 13:18:53.000000000 +0200 @@ -134,6 +134,7 @@ enum fuse_opcode { FUSE_INTERRUPT = 36, FUSE_BMAP = 37, FUSE_DESTROY = 38, + FUSE_ENTER = 39, }; /* The read buffer is required to be at least 8k, but may be much larger */ @@ -314,6 +315,10 @@ struct fuse_bmap_out { __u64 block; }; +struct fuse_enter_out { + __u64 fd; +}; + struct fuse_in_header { __u32 len; __u32 opcode; Index: linux/fs/fuse/dev.c =================================================================== --- linux.orig/fs/fuse/dev.c 2007-05-22 10:38:31.000000000 +0200 +++ linux/fs/fuse/dev.c 2007-05-22 13:18:53.000000000 +0200 @@ -226,6 +226,10 @@ static void request_end(struct fuse_conn } fc->num_background--; } + if (req->in.h.opcode == FUSE_ENTER && !req->out.h.error) { + struct fuse_enter_out *outarg = req->out.args[0].value; + outarg->fd = (u64) (long) fget(outarg->fd); + } spin_unlock(&fc->lock); dput(req->dentry); mntput(req->vfsmount); Index: linux/fs/fuse/fuse_i.h =================================================================== --- linux.orig/fs/fuse/fuse_i.h 2007-05-22 10:38:31.000000000 +0200 +++ linux/fs/fuse/fuse_i.h 2007-05-22 13:18:53.000000000 +0200 @@ -345,6 +345,9 @@ struct fuse_conn { /** Is bmap not implemented by fs? */ unsigned no_bmap : 1; + /** Is enter not implemented by fs? */ + unsigned no_enter : 1; + /** The number of requests waiting for completion */ atomic_t num_waiting; |