Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=c79e322f63592c00b25b17af6a1782fad6c6fe6e
Commit:     c79e322f63592c00b25b17af6a1782fad6c6fe6e
Parent:     1fb69e7817296da8a6824804bb206ca1e7f31425
Author:     Miklos Szeredi <[EMAIL PROTECTED]>
AuthorDate: Thu Oct 18 03:06:59 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Thu Oct 18 14:37:30 2007 -0700

    fuse: add file handle to getattr operation
    
    Add necessary protocol changes for supplying a file handle with the getattr
    operation.  Step the API version to 7.9.
    
    This patch doesn't actually supply the file handle, because that needs some
    kind of VFS support, which we haven't yet been able to agree upon.
    
    [EMAIL PROTECTED]: coding-style fixes]
    Signed-off-by: Miklos Szeredi <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 fs/fuse/dir.c        |   37 +++++++++++++++++++++++++------------
 fs/fuse/inode.c      |    2 +-
 include/linux/fuse.h |   23 +++++++++++++++++++++--
 3 files changed, 47 insertions(+), 15 deletions(-)

diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index a058b66..8c5d156 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -705,10 +705,12 @@ static void fuse_fillattr(struct inode *inode, struct 
fuse_attr *attr,
        stat->blksize = (1 << inode->i_blkbits);
 }
 
-static int fuse_do_getattr(struct inode *inode, struct kstat *stat)
+static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
+                          struct file *file)
 {
        int err;
-       struct fuse_attr_out arg;
+       struct fuse_getattr_in inarg;
+       struct fuse_attr_out outarg;
        struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_req *req;
        u64 attr_version;
@@ -721,24 +723,35 @@ static int fuse_do_getattr(struct inode *inode, struct 
kstat *stat)
        attr_version = fc->attr_version;
        spin_unlock(&fc->lock);
 
+       memset(&inarg, 0, sizeof(inarg));
+       /* Directories have separate file-handle space */
+       if (file && S_ISREG(inode->i_mode)) {
+               struct fuse_file *ff = file->private_data;
+
+               inarg.getattr_flags |= FUSE_GETATTR_FH;
+               inarg.fh = ff->fh;
+       }
        req->in.h.opcode = FUSE_GETATTR;
        req->in.h.nodeid = get_node_id(inode);
+       req->in.numargs = 1;
+       req->in.args[0].size = sizeof(inarg);
+       req->in.args[0].value = &inarg;
        req->out.numargs = 1;
-       req->out.args[0].size = sizeof(arg);
-       req->out.args[0].value = &arg;
+       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) {
-               if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) {
+               if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
                        make_bad_inode(inode);
                        err = -EIO;
                } else {
-                       fuse_change_attributes(inode, &arg.attr,
-                                              attr_timeout(&arg),
+                       fuse_change_attributes(inode, &outarg.attr,
+                                              attr_timeout(&outarg),
                                               attr_version);
                        if (stat)
-                               fuse_fillattr(inode, &arg.attr, stat);
+                               fuse_fillattr(inode, &outarg.attr, stat);
                }
        }
        return err;
@@ -833,7 +846,7 @@ static int fuse_permission(struct inode *inode, int mask, 
struct nameidata *nd)
            ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
                struct fuse_inode *fi = get_fuse_inode(inode);
                if (fi->i_time < get_jiffies_64()) {
-                       err = fuse_do_getattr(inode, NULL);
+                       err = fuse_do_getattr(inode, NULL, NULL);
                        if (err)
                                return err;
 
@@ -848,7 +861,7 @@ static int fuse_permission(struct inode *inode, int mask, 
struct nameidata *nd)
                   attributes.  This is also needed, because the root
                   node will at first have no permissions */
                if (err == -EACCES && !refreshed) {
-                       err = fuse_do_getattr(inode, NULL);
+                       err = fuse_do_getattr(inode, NULL, NULL);
                        if (!err)
                                err = generic_permission(inode, mask, NULL);
                }
@@ -864,7 +877,7 @@ static int fuse_permission(struct inode *inode, int mask, 
struct nameidata *nd)
                        if (refreshed)
                                return -EACCES;
 
-                       err = fuse_do_getattr(inode, NULL);
+                       err = fuse_do_getattr(inode, NULL, NULL);
                        if (!err && !(inode->i_mode & S_IXUGO))
                                return -EACCES;
                }
@@ -1107,7 +1120,7 @@ static int fuse_getattr(struct vfsmount *mnt, struct 
dentry *entry,
                return -EACCES;
 
        if (fi->i_time < get_jiffies_64())
-               err = fuse_do_getattr(inode, stat);
+               err = fuse_do_getattr(inode, stat, NULL);
        else {
                err = 0;
                generic_fillattr(inode, stat);
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 2167fc4..6ef3973 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -553,7 +553,7 @@ static void fuse_send_init(struct fuse_conn *fc, struct 
fuse_req *req)
        arg->major = FUSE_KERNEL_VERSION;
        arg->minor = FUSE_KERNEL_MINOR_VERSION;
        arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
-       arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS;
+       arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_FILE_OPS;
        req->in.h.opcode = FUSE_INIT;
        req->in.numargs = 1;
        req->in.args[0].size = sizeof(*arg);
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index 9fbe9d2..a50d0d9 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -6,7 +6,14 @@
     See the file COPYING.
 */
 
-/* This file defines the kernel interface of FUSE */
+/*
+ * This file defines the kernel interface of FUSE
+ *
+ * Protocol changelog:
+ *
+ * 7.9:
+ *  - new fuse_getattr_in input argument of GETATTR
+ */
 
 #include <asm/types.h>
 #include <linux/major.h>
@@ -15,7 +22,7 @@
 #define FUSE_KERNEL_VERSION 7
 
 /** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 8
+#define FUSE_KERNEL_MINOR_VERSION 9
 
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
@@ -91,12 +98,18 @@ struct fuse_file_lock {
  */
 #define FUSE_ASYNC_READ                (1 << 0)
 #define FUSE_POSIX_LOCKS       (1 << 1)
+#define FUSE_FILE_OPS          (1 << 2)
 
 /**
  * Release flags
  */
 #define FUSE_RELEASE_FLUSH     (1 << 0)
 
+/**
+ * Getattr flags
+ */
+#define FUSE_GETATTR_FH                (1 << 0)
+
 enum fuse_opcode {
        FUSE_LOOKUP        = 1,
        FUSE_FORGET        = 2,  /* no reply */
@@ -154,6 +167,12 @@ struct fuse_forget_in {
        __u64   nlookup;
 };
 
+struct fuse_getattr_in {
+       __u32   getattr_flags;
+       __u32   dummy;
+       __u64   fh;
+};
+
 struct fuse_attr_out {
        __u64   attr_valid;     /* Cache timeout for the attributes */
        __u32   attr_valid_nsec;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to