From: Christoph Hellwig <hch@lst.de>
To: viro@zeniv.linux.org.uk, npiggin@suse.de
Cc: jack@suse.cz, linux-fsdevel@vger.kernel.org
Subject: [PATCH 1/2] always call inode_change_ok early in ->setattr
Date: Tue, 1 Jun 2010 13:39:25 +0200 [thread overview]
Message-ID: <20100601113925.GA4929@lst.de> (raw)
In-Reply-To: <20100601113915.GA4861@lst.de>
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>
Index: linux-2.6/fs/cifs/inode.c
===================================================================
--- linux-2.6.orig/fs/cifs/inode.c 2010-06-01 12:19:48.004255568 +0200
+++ linux-2.6/fs/cifs/inode.c 2010-06-01 12:20:04.402023064 +0200
@@ -1776,14 +1776,12 @@ cifs_setattr_unix(struct dentry *direntr
xid = GetXid();
- if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
- /* check if we have permission to change attrs */
- rc = inode_change_ok(inode, attrs);
- if (rc < 0)
- goto out;
- else
- rc = 0;
- }
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
+ attrs->ia_valid |= ATTR_FORCE;
+
+ rc = inode_change_ok(inode, attrs);
+ if (rc < 0)
+ goto out;
full_path = build_path_from_dentry(direntry);
if (full_path == NULL) {
@@ -1914,14 +1912,13 @@ cifs_setattr_nounix(struct dentry *diren
cFYI(1, "setattr on file %s attrs->iavalid 0x%x",
direntry->d_name.name, attrs->ia_valid);
- if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
- /* check if we have permission to change attrs */
- rc = inode_change_ok(inode, attrs);
- if (rc < 0) {
- FreeXid(xid);
- return rc;
- } else
- rc = 0;
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
+ attrs->ia_valid |= ATTR_FORCE;
+
+ rc = inode_change_ok(inode, attrs);
+ if (rc < 0) {
+ FreeXid(xid);
+ return rc;
}
full_path = build_path_from_dentry(direntry);
Index: linux-2.6/fs/fat/file.c
===================================================================
--- linux-2.6.orig/fs/fat/file.c 2010-06-01 12:19:23.681011749 +0200
+++ linux-2.6/fs/fat/file.c 2010-06-01 12:21:01.134027230 +0200
@@ -387,21 +387,6 @@ int fat_setattr(struct dentry *dentry, s
unsigned int ia_valid;
int error;
- /*
- * Expand the file. Since inode_setattr() updates ->i_size
- * before calling the ->truncate(), but FAT needs to fill the
- * hole before it. XXX: this is no longer true with new truncate
- * sequence.
- */
- if (attr->ia_valid & ATTR_SIZE) {
- if (attr->ia_size > inode->i_size) {
- error = fat_cont_expand(inode, attr->ia_size);
- if (error || attr->ia_valid == ATTR_SIZE)
- goto out;
- attr->ia_valid &= ~ATTR_SIZE;
- }
- }
-
/* Check for setting the inode time. */
ia_valid = attr->ia_valid;
if (ia_valid & TIMES_SET_FLAGS) {
@@ -417,6 +402,21 @@ int fat_setattr(struct dentry *dentry, s
goto out;
}
+ /*
+ * Expand the file. Since inode_setattr() updates ->i_size
+ * before calling the ->truncate(), but FAT needs to fill the
+ * hole before it. XXX: this is no longer true with new truncate
+ * sequence.
+ */
+ if (attr->ia_valid & ATTR_SIZE) {
+ if (attr->ia_size > inode->i_size) {
+ error = fat_cont_expand(inode, attr->ia_size);
+ if (error || attr->ia_valid == ATTR_SIZE)
+ goto out;
+ attr->ia_valid &= ~ATTR_SIZE;
+ }
+ }
+
if (((attr->ia_valid & ATTR_UID) &&
(attr->ia_uid != sbi->options.fs_uid)) ||
((attr->ia_valid & ATTR_GID) &&
Index: linux-2.6/fs/fuse/dir.c
===================================================================
--- linux-2.6.orig/fs/fuse/dir.c 2010-06-01 12:19:23.688003647 +0200
+++ linux-2.6/fs/fuse/dir.c 2010-06-01 12:20:04.409254311 +0200
@@ -1270,11 +1270,12 @@ static int fuse_do_setattr(struct dentry
if (!fuse_allow_task(fc, current))
return -EACCES;
- if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
- err = inode_change_ok(inode, attr);
- if (err)
- return err;
- }
+ if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
+ attr->ia_valid |= ATTR_FORCE;
+
+ err = inode_change_ok(inode, attr);
+ if (err)
+ return err;
if ((attr->ia_valid & ATTR_OPEN) && fc->atomic_o_trunc)
return 0;
Index: linux-2.6/fs/logfs/file.c
===================================================================
--- linux-2.6.orig/fs/logfs/file.c 2010-06-01 12:19:48.056005672 +0200
+++ linux-2.6/fs/logfs/file.c 2010-06-01 12:20:04.412282458 +0200
@@ -232,16 +232,16 @@ static int logfs_setattr(struct dentry *
struct inode *inode = dentry->d_inode;
int err = 0;
+ err = inode_change_ok(inode, attr);
+ if (err)
+ return err;
+
if (attr->ia_valid & ATTR_SIZE) {
err = logfs_truncate(inode, attr->ia_size);
if (err)
return err;
}
- err = inode_change_ok(inode, attr);
- if (err)
- return err;
-
setattr_copy(inode, attr);
mark_inode_dirty(inode);
return 0;
Index: linux-2.6/fs/reiserfs/inode.c
===================================================================
--- linux-2.6.orig/fs/reiserfs/inode.c 2010-06-01 12:19:48.162005532 +0200
+++ linux-2.6/fs/reiserfs/inode.c 2010-06-01 12:20:28.959005660 +0200
@@ -3086,6 +3086,10 @@ int reiserfs_setattr(struct dentry *dent
int depth;
int error;
+ error = inode_change_ok(inode, attr);
+ if (error)
+ return error;
+
/* must be turned off for recursive notify_change calls */
ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID);
@@ -3135,10 +3139,6 @@ int reiserfs_setattr(struct dentry *dent
goto out;
}
- error = inode_change_ok(inode, attr);
- if (error)
- goto out;
-
if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
(ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
struct reiserfs_transaction_handle th;
Index: linux-2.6/mm/shmem.c
===================================================================
--- linux-2.6.orig/mm/shmem.c 2010-06-01 12:19:23.712004415 +0200
+++ linux-2.6/mm/shmem.c 2010-06-01 12:20:04.424255568 +0200
@@ -766,6 +766,10 @@ static int shmem_notify_change(struct de
struct inode *inode = dentry->d_inode;
int error;
+ error = inode_change_ok(inode, attr);
+ if (error)
+ return error;
+
if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) {
loff_t newsize = attr->ia_size;
struct page *page = NULL;
@@ -808,11 +812,9 @@ static int shmem_notify_change(struct de
shmem_truncate_range(inode, newsize, (loff_t)-1);
}
- error = inode_change_ok(inode, attr);
- if (!error)
- setattr_copy(inode, attr);
+ setattr_copy(inode, attr);
#ifdef CONFIG_TMPFS_POSIX_ACL
- if (!error && (attr->ia_valid & ATTR_MODE))
+ if (attr->ia_valid & ATTR_MODE)
error = generic_acl_chmod(inode);
#endif
return error;
next prev parent reply other threads:[~2010-06-01 11:39 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-01 11:39 [PATCH 0/2] new truncate sequence, part3 Christoph Hellwig
2010-06-01 11:39 ` Christoph Hellwig [this message]
2010-06-01 11:39 ` [PATCH 2/2] check ATTR_SIZE contraints in inode_change_ok Christoph Hellwig
2010-06-01 11:49 ` Steven Whitehouse
2010-06-01 11:47 ` Christoph Hellwig
2010-06-09 7:33 ` Nick Piggin
2010-06-09 9:41 ` Jan Kara
2010-06-09 10:06 ` Nick Piggin
2010-06-09 10:07 ` Christoph Hellwig
2010-06-09 10:26 ` Nick Piggin
2010-06-10 8:21 ` Christoph Hellwig
2010-06-09 10:59 ` Steven Whitehouse
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100601113925.GA4929@lst.de \
--to=hch@lst.de \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
--cc=npiggin@suse.de \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).