fs: Give dentry to inode_change_ok() instead of inode
authorJan Kara <jack@suse.cz>
Thu, 26 May 2016 14:55:18 +0000 (16:55 +0200)
committerBen Hutchings <ben@decadent.org.uk>
Sun, 20 Nov 2016 01:01:43 +0000 (01:01 +0000)
commit 31051c85b5e2aaaf6315f74c72a732673632a905 upstream.

inode_change_ok() will be resposible for clearing capabilities and IMA
extended attributes and as such will need dentry. Give it as an argument
to inode_change_ok() instead of an inode. Also rename inode_change_ok()
to setattr_prepare() to better relect that it does also some
modifications in addition to checks.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jan Kara <jack@suse.cz>
[bwh: Backported to 3.2:
 - Drop changes to f2fs, lustre, orangefs, overlayfs
 - Adjust filenames, context
 - In nfsd, pass dentry to nfsd_sanitize_attrs()
 - In xfs, pass dentry to xfs_change_file_space(), xfs_set_mode(),
   xfs_setattr_nonsize(), and xfs_setattr_size()
 - Update ext3 as well
 - Mark pohmelfs as BROKEN; it's long dead upstream]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
54 files changed:
Documentation/filesystems/porting
drivers/staging/pohmelfs/Kconfig
fs/9p/vfs_inode.c
fs/9p/vfs_inode_dotl.c
fs/adfs/inode.c
fs/affs/inode.c
fs/attr.c
fs/btrfs/inode.c
fs/ceph/inode.c
fs/cifs/inode.c
fs/ecryptfs/inode.c
fs/exofs/inode.c
fs/ext2/inode.c
fs/ext3/inode.c
fs/ext4/inode.c
fs/fat/file.c
fs/fuse/dir.c
fs/gfs2/inode.c
fs/hfs/inode.c
fs/hfsplus/inode.c
fs/hostfs/hostfs_kern.c
fs/hpfs/inode.c
fs/hugetlbfs/inode.c
fs/jffs2/fs.c
fs/jfs/file.c
fs/libfs.c
fs/logfs/file.c
fs/minix/file.c
fs/ncpfs/inode.c
fs/nfsd/vfs.c
fs/nilfs2/inode.c
fs/ntfs/inode.c
fs/ocfs2/dlmfs/dlmfs.c
fs/ocfs2/file.c
fs/omfs/file.c
fs/proc/base.c
fs/proc/generic.c
fs/proc/proc_sysctl.c
fs/ramfs/file-nommu.c
fs/reiserfs/inode.c
fs/sysfs/inode.c
fs/sysv/file.c
fs/ubifs/file.c
fs/udf/file.c
fs/ufs/truncate.c
fs/utimes.c
fs/xfs/xfs_acl.c
fs/xfs/xfs_file.c
fs/xfs/xfs_ioctl.c
fs/xfs/xfs_iops.c
fs/xfs/xfs_vnodeops.c
fs/xfs/xfs_vnodeops.h
include/linux/fs.h
mm/shmem.c

index b4a3d76..56a9c6e 100644 (file)
@@ -288,8 +288,8 @@ implementing on-disk size changes.  Start with a copy of the old inode_setattr
 and vmtruncate, and the reorder the vmtruncate + foofs_vmtruncate sequence to
 be in order of zeroing blocks using block_truncate_page or similar helpers,
 size update and on finally on-disk truncation which should not fail.
 and vmtruncate, and the reorder the vmtruncate + foofs_vmtruncate sequence to
 be in order of zeroing blocks using block_truncate_page or similar helpers,
 size update and on finally on-disk truncation which should not fail.
-inode_change_ok now includes the size checks for ATTR_SIZE and must be called
-in the beginning of ->setattr unconditionally.
+setattr_prepare (which used to be inode_change_ok) now includes the size checks
+for ATTR_SIZE and must be called in the beginning of ->setattr unconditionally.
 
 [mandatory]
 
 
 [mandatory]
 
index 8d53b1a..b88769c 100644 (file)
@@ -1,5 +1,6 @@
 config POHMELFS
        tristate "POHMELFS filesystem support"
 config POHMELFS
        tristate "POHMELFS filesystem support"
+       depends on BROKEN
        depends on NET
        select CONNECTOR
        select CRYPTO
        depends on NET
        select CONNECTOR
        select CRYPTO
index adedfd4..34defa1 100644 (file)
@@ -1068,7 +1068,7 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
        struct p9_wstat wstat;
 
        P9_DPRINTK(P9_DEBUG_VFS, "\n");
        struct p9_wstat wstat;
 
        P9_DPRINTK(P9_DEBUG_VFS, "\n");
-       retval = inode_change_ok(dentry->d_inode, iattr);
+       retval = setattr_prepare(dentry, iattr);
        if (retval)
                return retval;
 
        if (retval)
                return retval;
 
index dbbc83f..781e56e 100644 (file)
@@ -538,7 +538,7 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
 
        P9_DPRINTK(P9_DEBUG_VFS, "\n");
 
 
        P9_DPRINTK(P9_DEBUG_VFS, "\n");
 
-       retval = inode_change_ok(dentry->d_inode, iattr);
+       retval = setattr_prepare(dentry, iattr);
        if (retval)
                return retval;
 
        if (retval)
                return retval;
 
index 1dab6a1..c5e42d8 100644 (file)
@@ -298,7 +298,7 @@ adfs_notify_change(struct dentry *dentry, struct iattr *attr)
        unsigned int ia_valid = attr->ia_valid;
        int error;
        
        unsigned int ia_valid = attr->ia_valid;
        int error;
        
-       error = inode_change_ok(inode, attr);
+       error = setattr_prepare(dentry, attr);
 
        /*
         * we can't change the UID or GID of any file -
 
        /*
         * we can't change the UID or GID of any file -
index 88a4b0b..abda0dc 100644 (file)
@@ -222,7 +222,7 @@ affs_notify_change(struct dentry *dentry, struct iattr *attr)
 
        pr_debug("AFFS: notify_change(%lu,0x%x)\n",inode->i_ino,attr->ia_valid);
 
 
        pr_debug("AFFS: notify_change(%lu,0x%x)\n",inode->i_ino,attr->ia_valid);
 
-       error = inode_change_ok(inode,attr);
+       error = setattr_prepare(dentry, attr);
        if (error)
                goto out;
 
        if (error)
                goto out;
 
index b8f55c4..0006fde 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
 #include <linux/evm.h>
 
 /**
 #include <linux/evm.h>
 
 /**
- * inode_change_ok - check if attribute changes to an inode are allowed
- * @inode:     inode to check
+ * setattr_prepare - check if attribute changes to a dentry are allowed
+ * @dentry:    dentry to check
  * @attr:      attributes to change
  *
  * Check if we are allowed to change the attributes contained in @attr
  * @attr:      attributes to change
  *
  * Check if we are allowed to change the attributes contained in @attr
- * in the given inode.  This includes the normal unix access permission
- * checks, as well as checks for rlimits and others.
+ * in the given dentry.  This includes the normal unix access permission
+ * checks, as well as checks for rlimits and others. The function also clears
+ * SGID bit from mode if user is not allowed to set it. Also file capabilities
+ * and IMA extended attributes are cleared if ATTR_KILL_PRIV is set.
  *
  * Should be called as the first thing in ->setattr implementations,
  * possibly after taking additional locks.
  */
  *
  * Should be called as the first thing in ->setattr implementations,
  * possibly after taking additional locks.
  */
-int inode_change_ok(const struct inode *inode, struct iattr *attr)
+int setattr_prepare(struct dentry *dentry, struct iattr *attr)
 {
 {
+       struct inode *inode = dentry->d_inode;
        unsigned int ia_valid = attr->ia_valid;
 
        /*
        unsigned int ia_valid = attr->ia_valid;
 
        /*
@@ -76,7 +79,7 @@ int inode_change_ok(const struct inode *inode, struct iattr *attr)
 
        return 0;
 }
 
        return 0;
 }
-EXPORT_SYMBOL(inode_change_ok);
+EXPORT_SYMBOL(setattr_prepare);
 
 /**
  * inode_newsize_ok - may this inode be truncated to a given size
 
 /**
  * inode_newsize_ok - may this inode be truncated to a given size
index 9a7efbe..d84977d 100644 (file)
@@ -3533,7 +3533,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
        if (btrfs_root_readonly(root))
                return -EROFS;
 
        if (btrfs_root_readonly(root))
                return -EROFS;
 
-       err = inode_change_ok(inode, attr);
+       err = setattr_prepare(dentry, attr);
        if (err)
                return err;
 
        if (err)
                return err;
 
index 8e889b7..6a6c2e3 100644 (file)
@@ -1541,7 +1541,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
 
        __ceph_do_pending_vmtruncate(inode);
 
 
        __ceph_do_pending_vmtruncate(inode);
 
-       err = inode_change_ok(inode, attr);
+       err = setattr_prepare(dentry, attr);
        if (err != 0)
                return err;
 
        if (err != 0)
                return err;
 
index 1dc0af7..91f66c5 100644 (file)
@@ -1948,7 +1948,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
                attrs->ia_valid |= ATTR_FORCE;
 
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
                attrs->ia_valid |= ATTR_FORCE;
 
-       rc = inode_change_ok(inode, attrs);
+       rc = setattr_prepare(direntry, attrs);
        if (rc < 0)
                goto out;
 
        if (rc < 0)
                goto out;
 
@@ -2089,7 +2089,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
                attrs->ia_valid |= ATTR_FORCE;
 
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
                attrs->ia_valid |= ATTR_FORCE;
 
-       rc = inode_change_ok(inode, attrs);
+       rc = setattr_prepare(direntry, attrs);
        if (rc < 0) {
                FreeXid(xid);
                return rc;
        if (rc < 0) {
                FreeXid(xid);
                return rc;
index 782569b..0393579 100644 (file)
@@ -1026,7 +1026,7 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
        }
        mutex_unlock(&crypt_stat->cs_mutex);
 
        }
        mutex_unlock(&crypt_stat->cs_mutex);
 
-       rc = inode_change_ok(inode, ia);
+       rc = setattr_prepare(dentry, ia);
        if (rc)
                goto out;
        if (ia->ia_valid & ATTR_SIZE) {
        if (rc)
                goto out;
        if (ia->ia_valid & ATTR_SIZE) {
index f6dbf77..b438842 100644 (file)
@@ -1018,7 +1018,7 @@ int exofs_setattr(struct dentry *dentry, struct iattr *iattr)
        if (unlikely(error))
                return error;
 
        if (unlikely(error))
                return error;
 
-       error = inode_change_ok(inode, iattr);
+       error = setattr_prepare(dentry, iattr);
        if (unlikely(error))
                return error;
 
        if (unlikely(error))
                return error;
 
index 5a45b8f..0d0f1a6 100644 (file)
@@ -1530,7 +1530,7 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
        struct inode *inode = dentry->d_inode;
        int error;
 
        struct inode *inode = dentry->d_inode;
        int error;
 
-       error = inode_change_ok(inode, iattr);
+       error = setattr_prepare(dentry, iattr);
        if (error)
                return error;
 
        if (error)
                return error;
 
index 71b263f..d12f961 100644 (file)
@@ -3271,7 +3271,7 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr)
        int error, rc = 0;
        const unsigned int ia_valid = attr->ia_valid;
 
        int error, rc = 0;
        const unsigned int ia_valid = attr->ia_valid;
 
-       error = inode_change_ok(inode, attr);
+       error = setattr_prepare(dentry, attr);
        if (error)
                return error;
 
        if (error)
                return error;
 
index 2b534b5..ff2e369 100644 (file)
@@ -4291,7 +4291,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
        int orphan = 0;
        const unsigned int ia_valid = attr->ia_valid;
 
        int orphan = 0;
        const unsigned int ia_valid = attr->ia_valid;
 
-       error = inode_change_ok(inode, attr);
+       error = setattr_prepare(dentry, attr);
        if (error)
                return error;
 
        if (error)
                return error;
 
index c118acf..ef4753e 100644 (file)
@@ -382,7 +382,7 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
                        attr->ia_valid &= ~TIMES_SET_FLAGS;
        }
 
                        attr->ia_valid &= ~TIMES_SET_FLAGS;
        }
 
-       error = inode_change_ok(inode, attr);
+       error = setattr_prepare(dentry, attr);
        attr->ia_valid = ia_valid;
        if (error) {
                if (sbi->options.quiet)
        attr->ia_valid = ia_valid;
        if (error) {
                if (sbi->options.quiet)
index e13558c..15c1d29 100644 (file)
@@ -1298,7 +1298,7 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
        if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
                attr->ia_valid |= ATTR_FORCE;
 
        if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
                attr->ia_valid |= ATTR_FORCE;
 
-       err = inode_change_ok(inode, attr);
+       err = setattr_prepare(entry, attr);
        if (err)
                return err;
 
        if (err)
                return err;
 
index cfd4959..d4f8380 100644 (file)
@@ -1646,7 +1646,7 @@ static int gfs2_setattr(struct dentry *dentry, struct iattr *attr)
        if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
                goto out;
 
        if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
                goto out;
 
-       error = inode_change_ok(inode, attr);
+       error = setattr_prepare(dentry, attr);
        if (error)
                goto out;
 
        if (error)
                goto out;
 
index a1a9fdc..532d6cb 100644 (file)
@@ -588,7 +588,7 @@ int hfs_inode_setattr(struct dentry *dentry, struct iattr * attr)
        struct hfs_sb_info *hsb = HFS_SB(inode->i_sb);
        int error;
 
        struct hfs_sb_info *hsb = HFS_SB(inode->i_sb);
        int error;
 
-       error = inode_change_ok(inode, attr); /* basic permission checks */
+       error = setattr_prepare(dentry, attr); /* basic permission checks */
        if (error)
                return error;
 
        if (error)
                return error;
 
index 40e1413..63a2524 100644 (file)
@@ -292,7 +292,7 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr)
        struct inode *inode = dentry->d_inode;
        int error;
 
        struct inode *inode = dentry->d_inode;
        int error;
 
-       error = inode_change_ok(inode, attr);
+       error = setattr_prepare(dentry, attr);
        if (error)
                return error;
 
        if (error)
                return error;
 
index 066b478..3f3b1bd 100644 (file)
@@ -792,7 +792,7 @@ int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
 
        int fd = HOSTFS_I(inode)->fd;
 
 
        int fd = HOSTFS_I(inode)->fd;
 
-       err = inode_change_ok(inode, attr);
+       err = setattr_prepare(dentry, attr);
        if (err)
                return err;
 
        if (err)
                return err;
 
index 3b2cec2..00fc943 100644 (file)
@@ -268,7 +268,7 @@ int hpfs_setattr(struct dentry *dentry, struct iattr *attr)
        if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size)
                goto out_unlock;
 
        if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size)
                goto out_unlock;
 
-       error = inode_change_ok(inode, attr);
+       error = setattr_prepare(dentry, attr);
        if (error)
                goto out_unlock;
 
        if (error)
                goto out_unlock;
 
index ebab116..5557332 100644 (file)
@@ -422,7 +422,7 @@ static int hugetlbfs_setattr(struct dentry *dentry, struct iattr *attr)
 
        BUG_ON(!inode);
 
 
        BUG_ON(!inode);
 
-       error = inode_change_ok(inode, attr);
+       error = setattr_prepare(dentry, attr);
        if (error)
                return error;
 
        if (error)
                return error;
 
index 4b8afe3..73652b2 100644 (file)
@@ -186,7 +186,7 @@ int jffs2_setattr(struct dentry *dentry, struct iattr *iattr)
 {
        int rc;
 
 {
        int rc;
 
-       rc = inode_change_ok(dentry->d_inode, iattr);
+       rc = setattr_prepare(dentry, iattr);
        if (rc)
                return rc;
 
        if (rc)
                return rc;
 
index 844f946..5ab3a0c 100644 (file)
@@ -102,7 +102,7 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr)
        struct inode *inode = dentry->d_inode;
        int rc;
 
        struct inode *inode = dentry->d_inode;
        int rc;
 
-       rc = inode_change_ok(inode, iattr);
+       rc = setattr_prepare(dentry, iattr);
        if (rc)
                return rc;
 
        if (rc)
                return rc;
 
index ce85edf..d2f43c9 100644 (file)
@@ -364,7 +364,7 @@ int simple_setattr(struct dentry *dentry, struct iattr *iattr)
 
        WARN_ON_ONCE(inode->i_op->truncate);
 
 
        WARN_ON_ONCE(inode->i_op->truncate);
 
-       error = inode_change_ok(inode, iattr);
+       error = setattr_prepare(dentry, iattr);
        if (error)
                return error;
 
        if (error)
                return error;
 
index b548c87..562bbc6 100644 (file)
@@ -241,7 +241,7 @@ static int logfs_setattr(struct dentry *dentry, struct iattr *attr)
        struct inode *inode = dentry->d_inode;
        int err = 0;
 
        struct inode *inode = dentry->d_inode;
        int err = 0;
 
-       err = inode_change_ok(inode, attr);
+       err = setattr_prepare(dentry, attr);
        if (err)
                return err;
 
        if (err)
                return err;
 
index 4493ce6..d23e13c 100644 (file)
@@ -28,7 +28,7 @@ static int minix_setattr(struct dentry *dentry, struct iattr *attr)
        struct inode *inode = dentry->d_inode;
        int error;
 
        struct inode *inode = dentry->d_inode;
        int error;
 
-       error = inode_change_ok(inode, attr);
+       error = setattr_prepare(dentry, attr);
        if (error)
                return error;
 
        if (error)
                return error;
 
index cbd1a61..dce88e9 100644 (file)
@@ -880,7 +880,7 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
        /* ageing the dentry to force validation */
        ncp_age_dentry(server, dentry);
 
        /* ageing the dentry to force validation */
        ncp_age_dentry(server, dentry);
 
-       result = inode_change_ok(inode, attr);
+       result = setattr_prepare(dentry, attr);
        if (result < 0)
                goto out;
 
        if (result < 0)
                goto out;
 
index e2e7914..855e3f8 100644 (file)
@@ -301,17 +301,19 @@ commit_metadata(struct svc_fh *fhp)
  * NFS semantics and what Linux expects.
  */
 static void
  * NFS semantics and what Linux expects.
  */
 static void
-nfsd_sanitize_attrs(struct inode *inode, struct iattr *iap)
+nfsd_sanitize_attrs(struct dentry *dentry, struct iattr *iap)
 {
 {
+       struct inode *inode = dentry->d_inode;
+
        /*
         * NFSv2 does not differentiate between "set-[ac]time-to-now"
         * which only requires access, and "set-[ac]time-to-X" which
         * requires ownership.
         * So if it looks like it might be "set both to the same time which
        /*
         * NFSv2 does not differentiate between "set-[ac]time-to-now"
         * which only requires access, and "set-[ac]time-to-X" which
         * requires ownership.
         * So if it looks like it might be "set both to the same time which
-        * is close to now", and if inode_change_ok fails, then we
+        * is close to now", and if setattr_prepare fails, then we
         * convert to "set to now" instead of "set to explicit time"
         *
         * convert to "set to now" instead of "set to explicit time"
         *
-        * We only call inode_change_ok as the last test as technically
+        * We only call setattr_prepare as the last test as technically
         * it is not an interface that we should be using.
         */
 #define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)
         * it is not an interface that we should be using.
         */
 #define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)
@@ -329,7 +331,7 @@ nfsd_sanitize_attrs(struct inode *inode, struct iattr *iap)
                if (delta < 0)
                        delta = -delta;
                if (delta < MAX_TOUCH_TIME_ERROR &&
                if (delta < 0)
                        delta = -delta;
                if (delta < MAX_TOUCH_TIME_ERROR &&
-                   inode_change_ok(inode, iap) != 0) {
+                   setattr_prepare(dentry, iap) != 0) {
                        /*
                         * Turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME.
                         * This will cause notify_change to set these times
                        /*
                         * Turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME.
                         * This will cause notify_change to set these times
@@ -437,7 +439,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
        if (!iap->ia_valid)
                goto out;
 
        if (!iap->ia_valid)
                goto out;
 
-       nfsd_sanitize_attrs(inode, iap);
+       nfsd_sanitize_attrs(dentry, iap);
 
        /*
         * The size case is special, it changes the file in addition to the
 
        /*
         * The size case is special, it changes the file in addition to the
index b2d8a96..3a70818 100644 (file)
@@ -792,7 +792,7 @@ int nilfs_setattr(struct dentry *dentry, struct iattr *iattr)
        struct super_block *sb = inode->i_sb;
        int err;
 
        struct super_block *sb = inode->i_sb;
        int err;
 
-       err = inode_change_ok(inode, iattr);
+       err = setattr_prepare(dentry, iattr);
        if (err)
                return err;
 
        if (err)
                return err;
 
index 97e2dac..c84f026 100644 (file)
@@ -2890,7 +2890,7 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr)
        int err;
        unsigned int ia_valid = attr->ia_valid;
 
        int err;
        unsigned int ia_valid = attr->ia_valid;
 
-       err = inode_change_ok(vi, attr);
+       err = setattr_prepare(dentry, attr);
        if (err)
                goto out;
        /* We do not support NTFS ACLs yet. */
        if (err)
                goto out;
        /* We do not support NTFS ACLs yet. */
index b420767..d0ab0bf 100644 (file)
@@ -212,7 +212,7 @@ static int dlmfs_file_setattr(struct dentry *dentry, struct iattr *attr)
        struct inode *inode = dentry->d_inode;
 
        attr->ia_valid &= ~ATTR_SIZE;
        struct inode *inode = dentry->d_inode;
 
        attr->ia_valid &= ~ATTR_SIZE;
-       error = inode_change_ok(inode, attr);
+       error = setattr_prepare(dentry, attr);
        if (error)
                return error;
 
        if (error)
                return error;
 
index daf52d5..a678e22 100644 (file)
@@ -1127,7 +1127,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
        if (!(attr->ia_valid & OCFS2_VALID_ATTRS))
                return 0;
 
        if (!(attr->ia_valid & OCFS2_VALID_ATTRS))
                return 0;
 
-       status = inode_change_ok(inode, attr);
+       status = setattr_prepare(dentry, attr);
        if (status)
                return status;
 
        if (status)
                return status;
 
index 2c6d952..26972e7 100644 (file)
@@ -345,7 +345,7 @@ static int omfs_setattr(struct dentry *dentry, struct iattr *attr)
        struct inode *inode = dentry->d_inode;
        int error;
 
        struct inode *inode = dentry->d_inode;
        int error;
 
-       error = inode_change_ok(inode, attr);
+       error = setattr_prepare(dentry, attr);
        if (error)
                return error;
 
        if (error)
                return error;
 
index 402976a..2c38a3e 100644 (file)
@@ -558,7 +558,7 @@ int proc_setattr(struct dentry *dentry, struct iattr *attr)
        if (attr->ia_valid & ATTR_MODE)
                return -EPERM;
 
        if (attr->ia_valid & ATTR_MODE)
                return -EPERM;
 
-       error = inode_change_ok(inode, attr);
+       error = setattr_prepare(dentry, attr);
        if (error)
                return error;
 
        if (error)
                return error;
 
index 10090d9..d0d6bb6 100644 (file)
@@ -257,7 +257,7 @@ static int proc_notify_change(struct dentry *dentry, struct iattr *iattr)
        struct proc_dir_entry *de = PDE(inode);
        int error;
 
        struct proc_dir_entry *de = PDE(inode);
        int error;
 
-       error = inode_change_ok(inode, iattr);
+       error = setattr_prepare(dentry, iattr);
        if (error)
                return error;
 
        if (error)
                return error;
 
index 0be1aa4..ec20595 100644 (file)
@@ -387,7 +387,7 @@ static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr)
        if (attr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
                return -EPERM;
 
        if (attr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
                return -EPERM;
 
-       error = inode_change_ok(inode, attr);
+       error = setattr_prepare(dentry, attr);
        if (error)
                return error;
 
        if (error)
                return error;
 
index d5378d0..b79c545 100644 (file)
@@ -164,7 +164,7 @@ static int ramfs_nommu_setattr(struct dentry *dentry, struct iattr *ia)
        int ret = 0;
 
        /* POSIX UID/GID verification for setting inode attributes */
        int ret = 0;
 
        /* POSIX UID/GID verification for setting inode attributes */
-       ret = inode_change_ok(inode, ia);
+       ret = setattr_prepare(dentry, ia);
        if (ret)
                return ret;
 
        if (ret)
                return ret;
 
index fcb07e5..ff10dda 100644 (file)
@@ -3107,7 +3107,7 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
        int depth;
        int error;
 
        int depth;
        int error;
 
-       error = inode_change_ok(inode, attr);
+       error = setattr_prepare(dentry, attr);
        if (error)
                return error;
 
        if (error)
                return error;
 
index 9db61a4..6f54e62 100644 (file)
@@ -114,7 +114,7 @@ int sysfs_setattr(struct dentry *dentry, struct iattr *iattr)
                return -EINVAL;
 
        mutex_lock(&sysfs_mutex);
                return -EINVAL;
 
        mutex_lock(&sysfs_mutex);
-       error = inode_change_ok(inode, iattr);
+       error = setattr_prepare(dentry, iattr);
        if (error)
                goto out;
 
        if (error)
                goto out;
 
index 0a65939..e48fe25 100644 (file)
@@ -35,7 +35,7 @@ static int sysv_setattr(struct dentry *dentry, struct iattr *attr)
        struct inode *inode = dentry->d_inode;
        int error;
 
        struct inode *inode = dentry->d_inode;
        int error;
 
-       error = inode_change_ok(inode, attr);
+       error = setattr_prepare(dentry, attr);
        if (error)
                return error;
 
        if (error)
                return error;
 
index 9df6217..3cc9067 100644 (file)
@@ -1260,7 +1260,7 @@ int ubifs_setattr(struct dentry *dentry, struct iattr *attr)
 
        dbg_gen("ino %lu, mode %#x, ia_valid %#x",
                inode->i_ino, inode->i_mode, attr->ia_valid);
 
        dbg_gen("ino %lu, mode %#x, ia_valid %#x",
                inode->i_ino, inode->i_mode, attr->ia_valid);
-       err = inode_change_ok(inode, attr);
+       err = setattr_prepare(dentry, attr);
        if (err)
                return err;
 
        if (err)
                return err;
 
index 874c9e3..26f9b52 100644 (file)
@@ -251,7 +251,7 @@ static int udf_setattr(struct dentry *dentry, struct iattr *attr)
        struct inode *inode = dentry->d_inode;
        int error;
 
        struct inode *inode = dentry->d_inode;
        int error;
 
-       error = inode_change_ok(inode, attr);
+       error = setattr_prepare(dentry, attr);
        if (error)
                return error;
 
        if (error)
                return error;
 
index f04f89f..92cde99 100644 (file)
@@ -496,7 +496,7 @@ int ufs_setattr(struct dentry *dentry, struct iattr *attr)
        unsigned int ia_valid = attr->ia_valid;
        int error;
 
        unsigned int ia_valid = attr->ia_valid;
        int error;
 
-       error = inode_change_ok(inode, attr);
+       error = setattr_prepare(dentry, attr);
        if (error)
                return error;
 
        if (error)
                return error;
 
index ba653f3..cc428b2 100644 (file)
@@ -80,7 +80,7 @@ static int utimes_common(struct path *path, struct timespec *times)
                        newattrs.ia_valid |= ATTR_MTIME_SET;
                }
                /*
                        newattrs.ia_valid |= ATTR_MTIME_SET;
                }
                /*
-                * Tell inode_change_ok(), that this is an explicit time
+                * Tell setattr_prepare(), that this is an explicit time
                 * update, even if neither ATTR_ATIME_SET nor ATTR_MTIME_SET
                 * were used.
                 */
                 * update, even if neither ATTR_ATIME_SET nor ATTR_MTIME_SET
                 * were used.
                 */
@@ -89,7 +89,7 @@ static int utimes_common(struct path *path, struct timespec *times)
                /*
                 * If times is NULL (or both times are UTIME_NOW),
                 * then we need to check permissions, because
                /*
                 * If times is NULL (or both times are UTIME_NOW),
                 * then we need to check permissions, because
-                * inode_change_ok() won't do it.
+                * setattr_prepare() won't do it.
                 */
                error = -EACCES;
                 if (IS_IMMUTABLE(inode))
                 */
                error = -EACCES;
                 if (IS_IMMUTABLE(inode))
index ac702a6..f224313 100644 (file)
@@ -223,7 +223,7 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
 }
 
 static int
 }
 
 static int
-xfs_set_mode(struct inode *inode, umode_t mode)
+xfs_set_mode(struct dentry *dentry, struct inode *inode, umode_t mode)
 {
        int error = 0;
 
 {
        int error = 0;
 
@@ -234,7 +234,8 @@ xfs_set_mode(struct inode *inode, umode_t mode)
                iattr.ia_mode = mode;
                iattr.ia_ctime = current_fs_time(inode->i_sb);
 
                iattr.ia_mode = mode;
                iattr.ia_ctime = current_fs_time(inode->i_sb);
 
-               error = -xfs_setattr_nonsize(XFS_I(inode), &iattr, XFS_ATTR_NOACL);
+               error = -xfs_setattr_nonsize(dentry, XFS_I(inode), &iattr,
+                                            XFS_ATTR_NOACL);
        }
 
        return error;
        }
 
        return error;
@@ -290,7 +291,7 @@ xfs_inherit_acl(struct inode *inode, struct posix_acl *acl)
        if (error > 0)
                inherit = 1;
 
        if (error > 0)
                inherit = 1;
 
-       error = xfs_set_mode(inode, mode);
+       error = xfs_set_mode(NULL, inode, mode);
        if (error)
                goto out;
 
        if (error)
                goto out;
 
@@ -394,7 +395,7 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name,
                                return error;
                }
 
                                return error;
                }
 
-               error = xfs_set_mode(inode, mode);
+               error = xfs_set_mode(dentry, inode, mode);
                if (error)
                        goto out_release;
        }
                if (error)
                        goto out_release;
        }
index 8ae937a..ba1d477 100644 (file)
@@ -1026,7 +1026,8 @@ xfs_file_fallocate(
        if (file->f_flags & O_DSYNC)
                attr_flags |= XFS_ATTR_SYNC;
 
        if (file->f_flags & O_DSYNC)
                attr_flags |= XFS_ATTR_SYNC;
 
-       error = -xfs_change_file_space(ip, cmd, &bf, 0, attr_flags);
+       error = -xfs_change_file_space(file->f_dentry, cmd, &bf, 0,
+                                      attr_flags);
        if (error)
                goto out_unlock;
 
        if (error)
                goto out_unlock;
 
@@ -1036,7 +1037,8 @@ xfs_file_fallocate(
 
                iattr.ia_valid = ATTR_SIZE;
                iattr.ia_size = new_size;
 
                iattr.ia_valid = ATTR_SIZE;
                iattr.ia_size = new_size;
-               error = -xfs_setattr_size(ip, &iattr, XFS_ATTR_NOLOCK);
+               error = -xfs_setattr_size(file->f_dentry, &iattr,
+                                         XFS_ATTR_NOLOCK);
        }
 
 out_unlock:
        }
 
 out_unlock:
index eb519de..5a213c9 100644 (file)
@@ -632,7 +632,8 @@ xfs_ioc_space(
        if (ioflags & IO_INVIS)
                attr_flags |= XFS_ATTR_DMI;
 
        if (ioflags & IO_INVIS)
                attr_flags |= XFS_ATTR_DMI;
 
-       error = xfs_change_file_space(ip, cmd, bf, filp->f_pos, attr_flags);
+       error = xfs_change_file_space(filp->f_dentry, cmd, bf, filp->f_pos,
+                                     attr_flags);
        return -error;
 }
 
        return -error;
 }
 
index 1c01f04..a20378e 100644 (file)
@@ -531,6 +531,7 @@ xfs_setattr_mode(
 
 int
 xfs_setattr_nonsize(
 
 int
 xfs_setattr_nonsize(
+       struct dentry           *dentry,
        struct xfs_inode        *ip,
        struct iattr            *iattr,
        int                     flags)
        struct xfs_inode        *ip,
        struct iattr            *iattr,
        int                     flags)
@@ -553,9 +554,15 @@ xfs_setattr_nonsize(
        if (XFS_FORCED_SHUTDOWN(mp))
                return XFS_ERROR(EIO);
 
        if (XFS_FORCED_SHUTDOWN(mp))
                return XFS_ERROR(EIO);
 
-       error = -inode_change_ok(inode, iattr);
-       if (error)
-               return XFS_ERROR(error);
+       /*
+        * dentry can be NULL only when we're called from xfs_inherit_acl(),
+        * in which case no permission checks are needed
+        */
+       if (dentry) {
+               error = -setattr_prepare(dentry, iattr);
+               if (error)
+                       return XFS_ERROR(error);
+       }
 
        ASSERT((mask & ATTR_SIZE) == 0);
 
 
        ASSERT((mask & ATTR_SIZE) == 0);
 
@@ -755,12 +762,13 @@ out_dqrele:
  */
 int
 xfs_setattr_size(
  */
 int
 xfs_setattr_size(
-       struct xfs_inode        *ip,
+       struct dentry           *dentry,
        struct iattr            *iattr,
        int                     flags)
 {
        struct iattr            *iattr,
        int                     flags)
 {
+       struct inode            *inode = dentry->d_inode;
+       struct xfs_inode        *ip = XFS_I(inode);
        struct xfs_mount        *mp = ip->i_mount;
        struct xfs_mount        *mp = ip->i_mount;
-       struct inode            *inode = VFS_I(ip);
        int                     mask = iattr->ia_valid;
        struct xfs_trans        *tp;
        int                     error;
        int                     mask = iattr->ia_valid;
        struct xfs_trans        *tp;
        int                     error;
@@ -776,7 +784,7 @@ xfs_setattr_size(
        if (XFS_FORCED_SHUTDOWN(mp))
                return XFS_ERROR(EIO);
 
        if (XFS_FORCED_SHUTDOWN(mp))
                return XFS_ERROR(EIO);
 
-       error = -inode_change_ok(inode, iattr);
+       error = -setattr_prepare(dentry, iattr);
        if (error)
                return XFS_ERROR(error);
 
        if (error)
                return XFS_ERROR(error);
 
@@ -802,7 +810,7 @@ xfs_setattr_size(
                 */
                xfs_iunlock(ip, lock_flags);
                iattr->ia_valid &= ~ATTR_SIZE;
                 */
                xfs_iunlock(ip, lock_flags);
                iattr->ia_valid &= ~ATTR_SIZE;
-               return xfs_setattr_nonsize(ip, iattr, 0);
+               return xfs_setattr_nonsize(dentry, ip, iattr, 0);
        }
 
        /*
        }
 
        /*
@@ -950,8 +958,8 @@ xfs_vn_setattr(
        struct iattr    *iattr)
 {
        if (iattr->ia_valid & ATTR_SIZE)
        struct iattr    *iattr)
 {
        if (iattr->ia_valid & ATTR_SIZE)
-               return -xfs_setattr_size(XFS_I(dentry->d_inode), iattr, 0);
-       return -xfs_setattr_nonsize(XFS_I(dentry->d_inode), iattr, 0);
+               return -xfs_setattr_size(dentry, iattr, 0);
+       return -xfs_setattr_nonsize(dentry, XFS_I(dentry->d_inode), iattr, 0);
 }
 
 #define XFS_FIEMAP_FLAGS       (FIEMAP_FLAG_SYNC|FIEMAP_FLAG_XATTR)
 }
 
 #define XFS_FIEMAP_FLAGS       (FIEMAP_FLAG_SYNC|FIEMAP_FLAG_XATTR)
index ee98d0b..feb9e75 100644 (file)
@@ -2234,12 +2234,13 @@ xfs_free_file_space(
  */
 int
 xfs_change_file_space(
  */
 int
 xfs_change_file_space(
-       xfs_inode_t     *ip,
+       struct dentry   *dentry,
        int             cmd,
        xfs_flock64_t   *bf,
        xfs_off_t       offset,
        int             attr_flags)
 {
        int             cmd,
        xfs_flock64_t   *bf,
        xfs_off_t       offset,
        int             attr_flags)
 {
+       xfs_inode_t     *ip = XFS_I(dentry->d_inode);
        xfs_mount_t     *mp = ip->i_mount;
        int             clrprealloc;
        int             error;
        xfs_mount_t     *mp = ip->i_mount;
        int             clrprealloc;
        int             error;
@@ -2329,7 +2330,7 @@ xfs_change_file_space(
                iattr.ia_valid = ATTR_SIZE;
                iattr.ia_size = startoffset;
 
                iattr.ia_valid = ATTR_SIZE;
                iattr.ia_size = startoffset;
 
-               error = xfs_setattr_size(ip, &iattr, attr_flags);
+               error = xfs_setattr_size(dentry, &iattr, attr_flags);
 
                if (error)
                        return error;
 
                if (error)
                        return error;
index c0f7714..938c426 100644 (file)
@@ -13,8 +13,9 @@ struct xfs_inode;
 struct xfs_iomap;
 
 
 struct xfs_iomap;
 
 
-int xfs_setattr_nonsize(struct xfs_inode *ip, struct iattr *vap, int flags);
-int xfs_setattr_size(struct xfs_inode *ip, struct iattr *vap, int flags);
+int xfs_setattr_nonsize(struct dentry *dentry, struct xfs_inode *ip,
+                       struct iattr *vap, int flags);
+int xfs_setattr_size(struct dentry *dentry, struct iattr *vap, int flags);
 #define        XFS_ATTR_DMI            0x01    /* invocation from a DMI function */
 #define        XFS_ATTR_NONBLOCK       0x02    /* return EAGAIN if operation would block */
 #define XFS_ATTR_NOLOCK                0x04    /* Don't grab any conflicting locks */
 #define        XFS_ATTR_DMI            0x01    /* invocation from a DMI function */
 #define        XFS_ATTR_NONBLOCK       0x02    /* return EAGAIN if operation would block */
 #define XFS_ATTR_NOLOCK                0x04    /* Don't grab any conflicting locks */
@@ -37,7 +38,7 @@ int xfs_readdir(struct xfs_inode      *dp, void *dirent, size_t bufsize,
 int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name,
                const char *target_path, mode_t mode, struct xfs_inode **ipp);
 int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state);
 int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name,
                const char *target_path, mode_t mode, struct xfs_inode **ipp);
 int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state);
-int xfs_change_file_space(struct xfs_inode *ip, int cmd,
+int xfs_change_file_space(struct dentry *dentry, int cmd,
                xfs_flock64_t *bf, xfs_off_t offset, int attr_flags);
 int xfs_rename(struct xfs_inode *src_dp, struct xfs_name *src_name,
                struct xfs_inode *src_ip, struct xfs_inode *target_dp,
                xfs_flock64_t *bf, xfs_off_t offset, int attr_flags);
 int xfs_rename(struct xfs_inode *src_dp, struct xfs_name *src_name,
                struct xfs_inode *src_ip, struct xfs_inode *target_dp,
index a509bee..8c63ec5 100644 (file)
@@ -2615,7 +2615,7 @@ extern int buffer_migrate_page(struct address_space *,
 #define buffer_migrate_page NULL
 #endif
 
 #define buffer_migrate_page NULL
 #endif
 
-extern int inode_change_ok(const struct inode *, struct iattr *);
+extern int setattr_prepare(struct dentry *, struct iattr *);
 extern int inode_newsize_ok(const struct inode *, loff_t offset);
 extern void setattr_copy(struct inode *inode, const struct iattr *attr);
 
 extern int inode_newsize_ok(const struct inode *, loff_t offset);
 extern void setattr_copy(struct inode *inode, const struct iattr *attr);
 
index 83efac6..0a9d891 100644 (file)
@@ -562,7 +562,7 @@ static int shmem_setattr(struct dentry *dentry, struct iattr *attr)
        struct inode *inode = dentry->d_inode;
        int error;
 
        struct inode *inode = dentry->d_inode;
        int error;
 
-       error = inode_change_ok(inode, attr);
+       error = setattr_prepare(dentry, attr);
        if (error)
                return error;
 
        if (error)
                return error;