aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2010-06-04 05:30:03 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2010-08-09 16:47:38 -0400
commitdb78b877f7744bec4a9d9f9e7d10da3931d7cd39 (patch)
treefd9ee2fbe0998218b6d90322f85b285887e6fe9d /fs
parent1025774ce411f2bd4b059ad7b53f0003569b74fa (diff)
always call inode_change_ok early in ->setattr
Make sure we call inode_change_ok before doing any changes in ->setattr, and make sure to call it even if our fs wants to ignore normal UNIX permissions, but use the ATTR_FORCE to skip those. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/inode.c29
-rw-r--r--fs/fat/file.c30
-rw-r--r--fs/fuse/dir.c11
-rw-r--r--fs/logfs/file.c8
-rw-r--r--fs/reiserfs/inode.c8
5 files changed, 42 insertions, 44 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 9c6a40f5cc57..b95f4a5af013 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1796,14 +1796,12 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1796 1796
1797 xid = GetXid(); 1797 xid = GetXid();
1798 1798
1799 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) { 1799 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
1800 /* check if we have permission to change attrs */ 1800 attrs->ia_valid |= ATTR_FORCE;
1801 rc = inode_change_ok(inode, attrs); 1801
1802 if (rc < 0) 1802 rc = inode_change_ok(inode, attrs);
1803 goto out; 1803 if (rc < 0)
1804 else 1804 goto out;
1805 rc = 0;
1806 }
1807 1805
1808 full_path = build_path_from_dentry(direntry); 1806 full_path = build_path_from_dentry(direntry);
1809 if (full_path == NULL) { 1807 if (full_path == NULL) {
@@ -1934,14 +1932,13 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
1934 cFYI(1, "setattr on file %s attrs->iavalid 0x%x", 1932 cFYI(1, "setattr on file %s attrs->iavalid 0x%x",
1935 direntry->d_name.name, attrs->ia_valid); 1933 direntry->d_name.name, attrs->ia_valid);
1936 1934
1937 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) { 1935 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
1938 /* check if we have permission to change attrs */ 1936 attrs->ia_valid |= ATTR_FORCE;
1939 rc = inode_change_ok(inode, attrs); 1937
1940 if (rc < 0) { 1938 rc = inode_change_ok(inode, attrs);
1941 FreeXid(xid); 1939 if (rc < 0) {
1942 return rc; 1940 FreeXid(xid);
1943 } else 1941 return rc;
1944 rc = 0;
1945 } 1942 }
1946 1943
1947 full_path = build_path_from_dentry(direntry); 1944 full_path = build_path_from_dentry(direntry);
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 20813d2c7d61..b2eedcee7516 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -387,21 +387,6 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
387 unsigned int ia_valid; 387 unsigned int ia_valid;
388 int error; 388 int error;
389 389
390 /*
391 * Expand the file. Since inode_setattr() updates ->i_size
392 * before calling the ->truncate(), but FAT needs to fill the
393 * hole before it. XXX: this is no longer true with new truncate
394 * sequence.
395 */
396 if (attr->ia_valid & ATTR_SIZE) {
397 if (attr->ia_size > inode->i_size) {
398 error = fat_cont_expand(inode, attr->ia_size);
399 if (error || attr->ia_valid == ATTR_SIZE)
400 goto out;
401 attr->ia_valid &= ~ATTR_SIZE;
402 }
403 }
404
405 /* Check for setting the inode time. */ 390 /* Check for setting the inode time. */
406 ia_valid = attr->ia_valid; 391 ia_valid = attr->ia_valid;
407 if (ia_valid & TIMES_SET_FLAGS) { 392 if (ia_valid & TIMES_SET_FLAGS) {
@@ -417,6 +402,21 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
417 goto out; 402 goto out;
418 } 403 }
419 404
405 /*
406 * Expand the file. Since inode_setattr() updates ->i_size
407 * before calling the ->truncate(), but FAT needs to fill the
408 * hole before it. XXX: this is no longer true with new truncate
409 * sequence.
410 */
411 if (attr->ia_valid & ATTR_SIZE) {
412 if (attr->ia_size > inode->i_size) {
413 error = fat_cont_expand(inode, attr->ia_size);
414 if (error || attr->ia_valid == ATTR_SIZE)
415 goto out;
416 attr->ia_valid &= ~ATTR_SIZE;
417 }
418 }
419
420 if (((attr->ia_valid & ATTR_UID) && 420 if (((attr->ia_valid & ATTR_UID) &&
421 (attr->ia_uid != sbi->options.fs_uid)) || 421 (attr->ia_uid != sbi->options.fs_uid)) ||
422 ((attr->ia_valid & ATTR_GID) && 422 ((attr->ia_valid & ATTR_GID) &&
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 3cdc5f78a406..43a9b3730a98 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1270,11 +1270,12 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
1270 if (!fuse_allow_task(fc, current)) 1270 if (!fuse_allow_task(fc, current))
1271 return -EACCES; 1271 return -EACCES;
1272 1272
1273 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { 1273 if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
1274 err = inode_change_ok(inode, attr); 1274 attr->ia_valid |= ATTR_FORCE;
1275 if (err) 1275
1276 return err; 1276 err = inode_change_ok(inode, attr);
1277 } 1277 if (err)
1278 return err;
1278 1279
1279 if ((attr->ia_valid & ATTR_OPEN) && fc->atomic_o_trunc) 1280 if ((attr->ia_valid & ATTR_OPEN) && fc->atomic_o_trunc)
1280 return 0; 1281 return 0;
diff --git a/fs/logfs/file.c b/fs/logfs/file.c
index 23b4d03bbd26..4dd0f7c06e39 100644
--- a/fs/logfs/file.c
+++ b/fs/logfs/file.c
@@ -232,16 +232,16 @@ static int logfs_setattr(struct dentry *dentry, struct iattr *attr)
232 struct inode *inode = dentry->d_inode; 232 struct inode *inode = dentry->d_inode;
233 int err = 0; 233 int err = 0;
234 234
235 err = inode_change_ok(inode, attr);
236 if (err)
237 return err;
238
235 if (attr->ia_valid & ATTR_SIZE) { 239 if (attr->ia_valid & ATTR_SIZE) {
236 err = logfs_truncate(inode, attr->ia_size); 240 err = logfs_truncate(inode, attr->ia_size);
237 if (err) 241 if (err)
238 return err; 242 return err;
239 } 243 }
240 244
241 err = inode_change_ok(inode, attr);
242 if (err)
243 return err;
244
245 setattr_copy(inode, attr); 245 setattr_copy(inode, attr);
246 mark_inode_dirty(inode); 246 mark_inode_dirty(inode);
247 return 0; 247 return 0;
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 2b8dc5c22867..46ba1cfc2df3 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -3084,6 +3084,10 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
3084 int depth; 3084 int depth;
3085 int error; 3085 int error;
3086 3086
3087 error = inode_change_ok(inode, attr);
3088 if (error)
3089 return error;
3090
3087 /* must be turned off for recursive notify_change calls */ 3091 /* must be turned off for recursive notify_change calls */
3088 ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); 3092 ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID);
3089 3093
@@ -3133,10 +3137,6 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
3133 goto out; 3137 goto out;
3134 } 3138 }
3135 3139
3136 error = inode_change_ok(inode, attr);
3137 if (error)
3138 goto out;
3139
3140 if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || 3140 if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
3141 (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { 3141 (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
3142 struct reiserfs_transaction_handle th; 3142 struct reiserfs_transaction_handle th;