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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.