aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2007-10-18 06:06:59 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-18 17:37:30 -0400
commitc79e322f63592c00b25b17af6a1782fad6c6fe6e (patch)
treed3cbacb295b82c036553f68f5a060c67ae16bfa3
parent1fb69e7817296da8a6824804bb206ca1e7f31425 (diff)
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. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/fuse/dir.c37
-rw-r--r--fs/fuse/inode.c2
-rw-r--r--include/linux/fuse.h23
3 files changed, 47 insertions, 15 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index a058b664859c..8c5d156284a0 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,
705 stat->blksize = (1 << inode->i_blkbits); 705 stat->blksize = (1 << inode->i_blkbits);
706} 706}
707 707
708static int fuse_do_getattr(struct inode *inode, struct kstat *stat) 708static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
709 struct file *file)
709{ 710{
710 int err; 711 int err;
711 struct fuse_attr_out arg; 712 struct fuse_getattr_in inarg;
713 struct fuse_attr_out outarg;
712 struct fuse_conn *fc = get_fuse_conn(inode); 714 struct fuse_conn *fc = get_fuse_conn(inode);
713 struct fuse_req *req; 715 struct fuse_req *req;
714 u64 attr_version; 716 u64 attr_version;
@@ -721,24 +723,35 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat)
721 attr_version = fc->attr_version; 723 attr_version = fc->attr_version;
722 spin_unlock(&fc->lock); 724 spin_unlock(&fc->lock);
723 725
726 memset(&inarg, 0, sizeof(inarg));
727 /* Directories have separate file-handle space */
728 if (file && S_ISREG(inode->i_mode)) {
729 struct fuse_file *ff = file->private_data;
730
731 inarg.getattr_flags |= FUSE_GETATTR_FH;
732 inarg.fh = ff->fh;
733 }
724 req->in.h.opcode = FUSE_GETATTR; 734 req->in.h.opcode = FUSE_GETATTR;
725 req->in.h.nodeid = get_node_id(inode); 735 req->in.h.nodeid = get_node_id(inode);
736 req->in.numargs = 1;
737 req->in.args[0].size = sizeof(inarg);
738 req->in.args[0].value = &inarg;
726 req->out.numargs = 1; 739 req->out.numargs = 1;
727 req->out.args[0].size = sizeof(arg); 740 req->out.args[0].size = sizeof(outarg);
728 req->out.args[0].value = &arg; 741 req->out.args[0].value = &outarg;
729 request_send(fc, req); 742 request_send(fc, req);
730 err = req->out.h.error; 743 err = req->out.h.error;
731 fuse_put_request(fc, req); 744 fuse_put_request(fc, req);
732 if (!err) { 745 if (!err) {
733 if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) { 746 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
734 make_bad_inode(inode); 747 make_bad_inode(inode);
735 err = -EIO; 748 err = -EIO;
736 } else { 749 } else {
737 fuse_change_attributes(inode, &arg.attr, 750 fuse_change_attributes(inode, &outarg.attr,
738 attr_timeout(&arg), 751 attr_timeout(&outarg),
739 attr_version); 752 attr_version);
740 if (stat) 753 if (stat)
741 fuse_fillattr(inode, &arg.attr, stat); 754 fuse_fillattr(inode, &outarg.attr, stat);
742 } 755 }
743 } 756 }
744 return err; 757 return err;
@@ -833,7 +846,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
833 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { 846 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
834 struct fuse_inode *fi = get_fuse_inode(inode); 847 struct fuse_inode *fi = get_fuse_inode(inode);
835 if (fi->i_time < get_jiffies_64()) { 848 if (fi->i_time < get_jiffies_64()) {
836 err = fuse_do_getattr(inode, NULL); 849 err = fuse_do_getattr(inode, NULL, NULL);
837 if (err) 850 if (err)
838 return err; 851 return err;
839 852
@@ -848,7 +861,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
848 attributes. This is also needed, because the root 861 attributes. This is also needed, because the root
849 node will at first have no permissions */ 862 node will at first have no permissions */
850 if (err == -EACCES && !refreshed) { 863 if (err == -EACCES && !refreshed) {
851 err = fuse_do_getattr(inode, NULL); 864 err = fuse_do_getattr(inode, NULL, NULL);
852 if (!err) 865 if (!err)
853 err = generic_permission(inode, mask, NULL); 866 err = generic_permission(inode, mask, NULL);
854 } 867 }
@@ -864,7 +877,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
864 if (refreshed) 877 if (refreshed)
865 return -EACCES; 878 return -EACCES;
866 879
867 err = fuse_do_getattr(inode, NULL); 880 err = fuse_do_getattr(inode, NULL, NULL);
868 if (!err && !(inode->i_mode & S_IXUGO)) 881 if (!err && !(inode->i_mode & S_IXUGO))
869 return -EACCES; 882 return -EACCES;
870 } 883 }
@@ -1107,7 +1120,7 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
1107 return -EACCES; 1120 return -EACCES;
1108 1121
1109 if (fi->i_time < get_jiffies_64()) 1122 if (fi->i_time < get_jiffies_64())
1110 err = fuse_do_getattr(inode, stat); 1123 err = fuse_do_getattr(inode, stat, NULL);
1111 else { 1124 else {
1112 err = 0; 1125 err = 0;
1113 generic_fillattr(inode, stat); 1126 generic_fillattr(inode, stat);
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 2167fc4fcab8..6ef3973f4048 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)
553 arg->major = FUSE_KERNEL_VERSION; 553 arg->major = FUSE_KERNEL_VERSION;
554 arg->minor = FUSE_KERNEL_MINOR_VERSION; 554 arg->minor = FUSE_KERNEL_MINOR_VERSION;
555 arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE; 555 arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
556 arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS; 556 arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_FILE_OPS;
557 req->in.h.opcode = FUSE_INIT; 557 req->in.h.opcode = FUSE_INIT;
558 req->in.numargs = 1; 558 req->in.numargs = 1;
559 req->in.args[0].size = sizeof(*arg); 559 req->in.args[0].size = sizeof(*arg);
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index 9fbe9d258e22..a50d0d9ac7ae 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -6,7 +6,14 @@
6 See the file COPYING. 6 See the file COPYING.
7*/ 7*/
8 8
9/* This file defines the kernel interface of FUSE */ 9/*
10 * This file defines the kernel interface of FUSE
11 *
12 * Protocol changelog:
13 *
14 * 7.9:
15 * - new fuse_getattr_in input argument of GETATTR
16 */
10 17
11#include <asm/types.h> 18#include <asm/types.h>
12#include <linux/major.h> 19#include <linux/major.h>
@@ -15,7 +22,7 @@
15#define FUSE_KERNEL_VERSION 7 22#define FUSE_KERNEL_VERSION 7
16 23
17/** Minor version number of this interface */ 24/** Minor version number of this interface */
18#define FUSE_KERNEL_MINOR_VERSION 8 25#define FUSE_KERNEL_MINOR_VERSION 9
19 26
20/** The node ID of the root inode */ 27/** The node ID of the root inode */
21#define FUSE_ROOT_ID 1 28#define FUSE_ROOT_ID 1
@@ -91,12 +98,18 @@ struct fuse_file_lock {
91 */ 98 */
92#define FUSE_ASYNC_READ (1 << 0) 99#define FUSE_ASYNC_READ (1 << 0)
93#define FUSE_POSIX_LOCKS (1 << 1) 100#define FUSE_POSIX_LOCKS (1 << 1)
101#define FUSE_FILE_OPS (1 << 2)
94 102
95/** 103/**
96 * Release flags 104 * Release flags
97 */ 105 */
98#define FUSE_RELEASE_FLUSH (1 << 0) 106#define FUSE_RELEASE_FLUSH (1 << 0)
99 107
108/**
109 * Getattr flags
110 */
111#define FUSE_GETATTR_FH (1 << 0)
112
100enum fuse_opcode { 113enum fuse_opcode {
101 FUSE_LOOKUP = 1, 114 FUSE_LOOKUP = 1,
102 FUSE_FORGET = 2, /* no reply */ 115 FUSE_FORGET = 2, /* no reply */
@@ -154,6 +167,12 @@ struct fuse_forget_in {
154 __u64 nlookup; 167 __u64 nlookup;
155}; 168};
156 169
170struct fuse_getattr_in {
171 __u32 getattr_flags;
172 __u32 dummy;
173 __u64 fh;
174};
175
157struct fuse_attr_out { 176struct fuse_attr_out {
158 __u64 attr_valid; /* Cache timeout for the attributes */ 177 __u64 attr_valid; /* Cache timeout for the attributes */
159 __u32 attr_valid_nsec; 178 __u32 attr_valid_nsec;