Merge remote-tracking branch 'torvalds/master' into perf/core
[sfrench/cifs-2.6.git] / fs / xfs / xfs_iops.c
index 67c8dc9de8aa47129c138147cd3be87c631c856a..66ebccb5a6fffb64d10e6e15a99757d48c5f4799 100644 (file)
@@ -128,6 +128,7 @@ xfs_cleanup_inode(
 
 STATIC int
 xfs_generic_create(
+       struct user_namespace   *mnt_userns,
        struct inode    *dir,
        struct dentry   *dentry,
        umode_t         mode,
@@ -161,9 +162,10 @@ xfs_generic_create(
                goto out_free_acl;
 
        if (!tmpfile) {
-               error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip);
+               error = xfs_create(mnt_userns, XFS_I(dir), &name, mode, rdev,
+                                  &ip);
        } else {
-               error = xfs_create_tmpfile(XFS_I(dir), mode, &ip);
+               error = xfs_create_tmpfile(mnt_userns, XFS_I(dir), mode, &ip);
        }
        if (unlikely(error))
                goto out_free_acl;
@@ -220,31 +222,35 @@ xfs_generic_create(
 
 STATIC int
 xfs_vn_mknod(
-       struct inode    *dir,
-       struct dentry   *dentry,
-       umode_t         mode,
-       dev_t           rdev)
+       struct user_namespace   *mnt_userns,
+       struct inode            *dir,
+       struct dentry           *dentry,
+       umode_t                 mode,
+       dev_t                   rdev)
 {
-       return xfs_generic_create(dir, dentry, mode, rdev, false);
+       return xfs_generic_create(mnt_userns, dir, dentry, mode, rdev, false);
 }
 
 STATIC int
 xfs_vn_create(
-       struct inode    *dir,
-       struct dentry   *dentry,
-       umode_t         mode,
-       bool            flags)
+       struct user_namespace   *mnt_userns,
+       struct inode            *dir,
+       struct dentry           *dentry,
+       umode_t                 mode,
+       bool                    flags)
 {
-       return xfs_generic_create(dir, dentry, mode, 0, false);
+       return xfs_generic_create(mnt_userns, dir, dentry, mode, 0, false);
 }
 
 STATIC int
 xfs_vn_mkdir(
-       struct inode    *dir,
-       struct dentry   *dentry,
-       umode_t         mode)
+       struct user_namespace   *mnt_userns,
+       struct inode            *dir,
+       struct dentry           *dentry,
+       umode_t                 mode)
 {
-       return xfs_generic_create(dir, dentry, mode | S_IFDIR, 0, false);
+       return xfs_generic_create(mnt_userns, dir, dentry, mode | S_IFDIR, 0,
+                                 false);
 }
 
 STATIC struct dentry *
@@ -361,9 +367,10 @@ xfs_vn_unlink(
 
 STATIC int
 xfs_vn_symlink(
-       struct inode    *dir,
-       struct dentry   *dentry,
-       const char      *symname)
+       struct user_namespace   *mnt_userns,
+       struct inode            *dir,
+       struct dentry           *dentry,
+       const char              *symname)
 {
        struct inode    *inode;
        struct xfs_inode *cip = NULL;
@@ -377,7 +384,7 @@ xfs_vn_symlink(
        if (unlikely(error))
                goto out;
 
-       error = xfs_symlink(XFS_I(dir), &name, symname, mode, &cip);
+       error = xfs_symlink(mnt_userns, XFS_I(dir), &name, symname, mode, &cip);
        if (unlikely(error))
                goto out;
 
@@ -403,11 +410,12 @@ xfs_vn_symlink(
 
 STATIC int
 xfs_vn_rename(
-       struct inode    *odir,
-       struct dentry   *odentry,
-       struct inode    *ndir,
-       struct dentry   *ndentry,
-       unsigned int    flags)
+       struct user_namespace   *mnt_userns,
+       struct inode            *odir,
+       struct dentry           *odentry,
+       struct inode            *ndir,
+       struct dentry           *ndentry,
+       unsigned int            flags)
 {
        struct inode    *new_inode = d_inode(ndentry);
        int             omode = 0;
@@ -431,8 +439,8 @@ xfs_vn_rename(
        if (unlikely(error))
                return error;
 
-       return xfs_rename(XFS_I(odir), &oname, XFS_I(d_inode(odentry)),
-                         XFS_I(ndir), &nname,
+       return xfs_rename(mnt_userns, XFS_I(odir), &oname,
+                         XFS_I(d_inode(odentry)), XFS_I(ndir), &nname,
                          new_inode ? XFS_I(new_inode) : NULL, flags);
 }
 
@@ -529,6 +537,7 @@ xfs_stat_blksize(
 
 STATIC int
 xfs_vn_getattr(
+       struct user_namespace   *mnt_userns,
        const struct path       *path,
        struct kstat            *stat,
        u32                     request_mask,
@@ -547,8 +556,8 @@ xfs_vn_getattr(
        stat->dev = inode->i_sb->s_dev;
        stat->mode = inode->i_mode;
        stat->nlink = inode->i_nlink;
-       stat->uid = inode->i_uid;
-       stat->gid = inode->i_gid;
+       stat->uid = i_uid_into_mnt(mnt_userns, inode);
+       stat->gid = i_gid_into_mnt(mnt_userns, inode);
        stat->ino = ip->i_ino;
        stat->atime = inode->i_atime;
        stat->mtime = inode->i_mtime;
@@ -626,8 +635,9 @@ xfs_setattr_time(
 
 static int
 xfs_vn_change_ok(
-       struct dentry   *dentry,
-       struct iattr    *iattr)
+       struct user_namespace   *mnt_userns,
+       struct dentry           *dentry,
+       struct iattr            *iattr)
 {
        struct xfs_mount        *mp = XFS_I(d_inode(dentry))->i_mount;
 
@@ -637,7 +647,7 @@ xfs_vn_change_ok(
        if (XFS_FORCED_SHUTDOWN(mp))
                return -EIO;
 
-       return setattr_prepare(dentry, iattr);
+       return setattr_prepare(mnt_userns, dentry, iattr);
 }
 
 /*
@@ -648,6 +658,7 @@ xfs_vn_change_ok(
  */
 static int
 xfs_setattr_nonsize(
+       struct user_namespace   *mnt_userns,
        struct xfs_inode        *ip,
        struct iattr            *iattr)
 {
@@ -700,13 +711,11 @@ xfs_setattr_nonsize(
                        return error;
        }
 
-       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
+       error = xfs_trans_alloc_ichange(ip, udqp, gdqp, NULL,
+                       capable(CAP_FOWNER), &tp);
        if (error)
                goto out_dqrele;
 
-       xfs_ilock(ip, XFS_ILOCK_EXCL);
-       xfs_trans_ijoin(tp, ip, 0);
-
        /*
         * Change file ownership.  Must be the owner or privileged.
         */
@@ -722,21 +731,6 @@ xfs_setattr_nonsize(
                gid = (mask & ATTR_GID) ? iattr->ia_gid : igid;
                uid = (mask & ATTR_UID) ? iattr->ia_uid : iuid;
 
-               /*
-                * Do a quota reservation only if uid/gid is actually
-                * going to change.
-                */
-               if (XFS_IS_QUOTA_RUNNING(mp) &&
-                   ((XFS_IS_UQUOTA_ON(mp) && !uid_eq(iuid, uid)) ||
-                    (XFS_IS_GQUOTA_ON(mp) && !gid_eq(igid, gid)))) {
-                       ASSERT(tp);
-                       error = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp,
-                                               NULL, capable(CAP_FOWNER) ?
-                                               XFS_QMOPT_FORCE_RES : 0);
-                       if (error)      /* out of quota */
-                               goto out_cancel;
-               }
-
                /*
                 * CAP_FSETID overrides the following restrictions:
                 *
@@ -786,8 +780,6 @@ xfs_setattr_nonsize(
                xfs_trans_set_sync(tp);
        error = xfs_trans_commit(tp);
 
-       xfs_iunlock(ip, XFS_ILOCK_EXCL);
-
        /*
         * Release any dquot(s) the inode had kept before chown.
         */
@@ -807,16 +799,13 @@ xfs_setattr_nonsize(
         *           Posix ACL code seems to care about this issue either.
         */
        if (mask & ATTR_MODE) {
-               error = posix_acl_chmod(inode, inode->i_mode);
+               error = posix_acl_chmod(mnt_userns, inode, inode->i_mode);
                if (error)
                        return error;
        }
 
        return 0;
 
-out_cancel:
-       xfs_trans_cancel(tp);
-       xfs_iunlock(ip, XFS_ILOCK_EXCL);
 out_dqrele:
        xfs_qm_dqrele(udqp);
        xfs_qm_dqrele(gdqp);
@@ -831,6 +820,7 @@ out_dqrele:
  */
 STATIC int
 xfs_setattr_size(
+       struct user_namespace   *mnt_userns,
        struct xfs_inode        *ip,
        struct iattr            *iattr)
 {
@@ -846,7 +836,7 @@ xfs_setattr_size(
        ASSERT(xfs_isilocked(ip, XFS_MMAPLOCK_EXCL));
        ASSERT(S_ISREG(inode->i_mode));
        ASSERT((iattr->ia_valid & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET|
-               ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0);
+               ATTR_MTIME_SET|ATTR_TIMES_SET)) == 0);
 
        oldsize = inode->i_size;
        newsize = iattr->ia_size;
@@ -862,7 +852,7 @@ xfs_setattr_size(
                 * Use the regular setattr path to update the timestamps.
                 */
                iattr->ia_valid &= ~ATTR_SIZE;
-               return xfs_setattr_nonsize(ip, iattr);
+               return xfs_setattr_nonsize(mnt_userns, ip, iattr);
        }
 
        /*
@@ -1031,6 +1021,7 @@ out_trans_cancel:
 
 int
 xfs_vn_setattr_size(
+       struct user_namespace   *mnt_userns,
        struct dentry           *dentry,
        struct iattr            *iattr)
 {
@@ -1039,14 +1030,15 @@ xfs_vn_setattr_size(
 
        trace_xfs_setattr(ip);
 
-       error = xfs_vn_change_ok(dentry, iattr);
+       error = xfs_vn_change_ok(mnt_userns, dentry, iattr);
        if (error)
                return error;
-       return xfs_setattr_size(ip, iattr);
+       return xfs_setattr_size(mnt_userns, ip, iattr);
 }
 
 STATIC int
 xfs_vn_setattr(
+       struct user_namespace   *mnt_userns,
        struct dentry           *dentry,
        struct iattr            *iattr)
 {
@@ -1066,14 +1058,14 @@ xfs_vn_setattr(
                        return error;
                }
 
-               error = xfs_vn_setattr_size(dentry, iattr);
+               error = xfs_vn_setattr_size(mnt_userns, dentry, iattr);
                xfs_iunlock(ip, XFS_MMAPLOCK_EXCL);
        } else {
                trace_xfs_setattr(ip);
 
-               error = xfs_vn_change_ok(dentry, iattr);
+               error = xfs_vn_change_ok(mnt_userns, dentry, iattr);
                if (!error)
-                       error = xfs_setattr_nonsize(ip, iattr);
+                       error = xfs_setattr_nonsize(mnt_userns, ip, iattr);
        }
 
        return error;
@@ -1144,11 +1136,12 @@ xfs_vn_fiemap(
 
 STATIC int
 xfs_vn_tmpfile(
-       struct inode    *dir,
-       struct dentry   *dentry,
-       umode_t         mode)
+       struct user_namespace   *mnt_userns,
+       struct inode            *dir,
+       struct dentry           *dentry,
+       umode_t                 mode)
 {
-       return xfs_generic_create(dir, dentry, mode, 0, true);
+       return xfs_generic_create(mnt_userns, dir, dentry, mode, 0, true);
 }
 
 static const struct inode_operations xfs_inode_operations = {