diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2005-11-07 03:59:52 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-07 10:53:42 -0500 |
commit | befc649c2274a1c35f0cd1e888dd83652cbb0422 (patch) | |
tree | ccbbc9f286c50dd8c9f036408b71acda9f5dd427 | |
parent | fd72faac95d7e47610e981d7ed7b3c1529e55c88 (diff) |
[PATCH] FUSE: pass file handle in setattr
This patch passes the file handle supplied in iattr to userspace, in case the
->setattr() was invoked from sys_ftruncate(). This solves the permission
checking (or lack thereof) in ftruncate() for the class of filesystems served
by an unprivileged userspace process.
Signed-off-by: Miklos Szeredi <miklos@szeredi.hu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | fs/fuse/dir.c | 28 | ||||
-rw-r--r-- | include/linux/fuse.h | 16 |
2 files changed, 29 insertions, 15 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 83be119ef067..c045cc70c749 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -763,29 +763,29 @@ static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync) | |||
763 | return file ? fuse_fsync_common(file, de, datasync, 1) : 0; | 763 | return file ? fuse_fsync_common(file, de, datasync, 1) : 0; |
764 | } | 764 | } |
765 | 765 | ||
766 | static unsigned iattr_to_fattr(struct iattr *iattr, struct fuse_attr *fattr) | 766 | static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg) |
767 | { | 767 | { |
768 | unsigned ivalid = iattr->ia_valid; | 768 | unsigned ivalid = iattr->ia_valid; |
769 | unsigned fvalid = 0; | ||
770 | |||
771 | memset(fattr, 0, sizeof(*fattr)); | ||
772 | 769 | ||
773 | if (ivalid & ATTR_MODE) | 770 | if (ivalid & ATTR_MODE) |
774 | fvalid |= FATTR_MODE, fattr->mode = iattr->ia_mode; | 771 | arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode; |
775 | if (ivalid & ATTR_UID) | 772 | if (ivalid & ATTR_UID) |
776 | fvalid |= FATTR_UID, fattr->uid = iattr->ia_uid; | 773 | arg->valid |= FATTR_UID, arg->uid = iattr->ia_uid; |
777 | if (ivalid & ATTR_GID) | 774 | if (ivalid & ATTR_GID) |
778 | fvalid |= FATTR_GID, fattr->gid = iattr->ia_gid; | 775 | arg->valid |= FATTR_GID, arg->gid = iattr->ia_gid; |
779 | if (ivalid & ATTR_SIZE) | 776 | if (ivalid & ATTR_SIZE) |
780 | fvalid |= FATTR_SIZE, fattr->size = iattr->ia_size; | 777 | arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size; |
781 | /* You can only _set_ these together (they may change by themselves) */ | 778 | /* You can only _set_ these together (they may change by themselves) */ |
782 | if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) { | 779 | if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) { |
783 | fvalid |= FATTR_ATIME | FATTR_MTIME; | 780 | arg->valid |= FATTR_ATIME | FATTR_MTIME; |
784 | fattr->atime = iattr->ia_atime.tv_sec; | 781 | arg->atime = iattr->ia_atime.tv_sec; |
785 | fattr->mtime = iattr->ia_mtime.tv_sec; | 782 | arg->mtime = iattr->ia_mtime.tv_sec; |
783 | } | ||
784 | if (ivalid & ATTR_FILE) { | ||
785 | struct fuse_file *ff = iattr->ia_file->private_data; | ||
786 | arg->valid |= FATTR_FH; | ||
787 | arg->fh = ff->fh; | ||
786 | } | 788 | } |
787 | |||
788 | return fvalid; | ||
789 | } | 789 | } |
790 | 790 | ||
791 | static int fuse_setattr(struct dentry *entry, struct iattr *attr) | 791 | static int fuse_setattr(struct dentry *entry, struct iattr *attr) |
@@ -820,7 +820,7 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) | |||
820 | return -EINTR; | 820 | return -EINTR; |
821 | 821 | ||
822 | memset(&inarg, 0, sizeof(inarg)); | 822 | memset(&inarg, 0, sizeof(inarg)); |
823 | inarg.valid = iattr_to_fattr(attr, &inarg.attr); | 823 | iattr_to_fattr(attr, &inarg); |
824 | req->in.h.opcode = FUSE_SETATTR; | 824 | req->in.h.opcode = FUSE_SETATTR; |
825 | req->in.h.nodeid = get_node_id(inode); | 825 | req->in.h.nodeid = get_node_id(inode); |
826 | req->inode = inode; | 826 | req->inode = inode; |
diff --git a/include/linux/fuse.h b/include/linux/fuse.h index 45c398f08247..b76b558b03d4 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h | |||
@@ -61,6 +61,7 @@ struct fuse_kstatfs { | |||
61 | #define FATTR_SIZE (1 << 3) | 61 | #define FATTR_SIZE (1 << 3) |
62 | #define FATTR_ATIME (1 << 4) | 62 | #define FATTR_ATIME (1 << 4) |
63 | #define FATTR_MTIME (1 << 5) | 63 | #define FATTR_MTIME (1 << 5) |
64 | #define FATTR_FH (1 << 6) | ||
64 | 65 | ||
65 | /** | 66 | /** |
66 | * Flags returned by the OPEN request | 67 | * Flags returned by the OPEN request |
@@ -154,7 +155,20 @@ struct fuse_link_in { | |||
154 | struct fuse_setattr_in { | 155 | struct fuse_setattr_in { |
155 | __u32 valid; | 156 | __u32 valid; |
156 | __u32 padding; | 157 | __u32 padding; |
157 | struct fuse_attr attr; | 158 | __u64 fh; |
159 | __u64 size; | ||
160 | __u64 unused1; | ||
161 | __u64 atime; | ||
162 | __u64 mtime; | ||
163 | __u64 unused2; | ||
164 | __u32 atimensec; | ||
165 | __u32 mtimensec; | ||
166 | __u32 unused3; | ||
167 | __u32 mode; | ||
168 | __u32 unused4; | ||
169 | __u32 uid; | ||
170 | __u32 gid; | ||
171 | __u32 unused5; | ||
158 | }; | 172 | }; |
159 | 173 | ||
160 | struct fuse_open_in { | 174 | struct fuse_open_in { |