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 /fs | |
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/fuse/dir.c | 28 |
1 files changed, 14 insertions, 14 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; |