]> Pileus Git - ~andy/linux/blobdiff - fs/xfs/xfs_trans_dquot.c
fs/proc/task_mmu.c: fix buffer overflow in add_page_map()
[~andy/linux] / fs / xfs / xfs_trans_dquot.c
index 3ba64d5401680ae749e36fdd424c6a139db0bdf9..61407a847b869a6bb0faec7bf2c3279d66aaeb83 100644 (file)
@@ -163,8 +163,10 @@ xfs_trans_mod_dquot_byino(
 
        if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot)
                (void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta);
-       if (XFS_IS_OQUOTA_ON(mp) && ip->i_gdquot)
+       if (XFS_IS_GQUOTA_ON(mp) && ip->i_gdquot)
                (void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta);
+       if (XFS_IS_PQUOTA_ON(mp) && ip->i_pdquot)
+               (void) xfs_trans_mod_dquot(tp, ip->i_pdquot, field, delta);
 }
 
 STATIC struct xfs_dqtrx *
@@ -177,8 +179,12 @@ xfs_trans_get_dqtrx(
 
        if (XFS_QM_ISUDQ(dqp))
                qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_USR];
-       else
+       else if (XFS_QM_ISGDQ(dqp))
                qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_GRP];
+       else if (XFS_QM_ISPDQ(dqp))
+               qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_PRJ];
+       else
+               return NULL;
 
        for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
                if (qa[i].qt_dquot == NULL ||
@@ -291,11 +297,10 @@ xfs_trans_mod_dquot(
 
 
 /*
- * Given an array of dqtrx structures, lock all the dquots associated
- * and join them to the transaction, provided they have been modified.
- * We know that the highest number of dquots (of one type - usr OR grp),
- * involved in a transaction is 2 and that both usr and grp combined - 3.
- * So, we don't attempt to make this very generic.
+ * Given an array of dqtrx structures, lock all the dquots associated and join
+ * them to the transaction, provided they have been modified.  We know that the
+ * highest number of dquots of one type - usr, grp OR prj - involved in a
+ * transaction is 2 so we don't need to make this very generic.
  */
 STATIC void
 xfs_trans_dqlockedjoin(
@@ -728,8 +733,8 @@ error_return:
 
 /*
  * Given dquot(s), make disk block and/or inode reservations against them.
- * The fact that this does the reservation against both the usr and
- * grp/prj quotas is important, because this follows a both-or-nothing
+ * The fact that this does the reservation against user, group and
+ * project quotas is important, because this follows a all-or-nothing
  * approach.
  *
  * flags = XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
@@ -744,6 +749,7 @@ xfs_trans_reserve_quota_bydquots(
        struct xfs_mount        *mp,
        struct xfs_dquot        *udqp,
        struct xfs_dquot        *gdqp,
+       struct xfs_dquot        *pdqp,
        long                    nblks,
        long                    ninos,
        uint                    flags)
@@ -771,11 +777,21 @@ xfs_trans_reserve_quota_bydquots(
                        goto unwind_usr;
        }
 
+       if (pdqp) {
+               error = xfs_trans_dqresv(tp, mp, pdqp, nblks, ninos, flags);
+               if (error)
+                       goto unwind_grp;
+       }
+
        /*
         * Didn't change anything critical, so, no need to log
         */
        return 0;
 
+unwind_grp:
+       flags |= XFS_QMOPT_FORCE_RES;
+       if (gdqp)
+               xfs_trans_dqresv(tp, mp, gdqp, -nblks, -ninos, flags);
 unwind_usr:
        flags |= XFS_QMOPT_FORCE_RES;
        if (udqp)
@@ -817,6 +833,7 @@ xfs_trans_reserve_quota_nblks(
         */
        return xfs_trans_reserve_quota_bydquots(tp, mp,
                                                ip->i_udquot, ip->i_gdquot,
+                                               ip->i_pdquot,
                                                nblks, ninos, flags);
 }