diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2007-10-18 06:06:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-18 17:37:30 -0400 |
commit | c79e322f63592c00b25b17af6a1782fad6c6fe6e (patch) | |
tree | d3cbacb295b82c036553f68f5a060c67ae16bfa3 /fs/fuse | |
parent | 1fb69e7817296da8a6824804bb206ca1e7f31425 (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>
Diffstat (limited to 'fs/fuse')
-rw-r--r-- | fs/fuse/dir.c | 37 | ||||
-rw-r--r-- | fs/fuse/inode.c | 2 |
2 files changed, 26 insertions, 13 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index a058b664859..8c5d156284a 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 | ||
708 | static int fuse_do_getattr(struct inode *inode, struct kstat *stat) | 708 | static 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 2167fc4fcab..6ef3973f404 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); |