aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_vnodeops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
-rw-r--r--fs/xfs/xfs_vnodeops.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 5703783991fa..695978b27497 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -351,21 +351,28 @@ xfs_setattr(
351 * If the IDs do change before we take the ilock, we're covered 351 * If the IDs do change before we take the ilock, we're covered
352 * because the i_*dquot fields will get updated anyway. 352 * because the i_*dquot fields will get updated anyway.
353 */ 353 */
354 if (XFS_IS_QUOTA_ON(mp) && (mask & (XFS_AT_UID|XFS_AT_GID))) { 354 if (XFS_IS_QUOTA_ON(mp) &&
355 (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID))) {
355 uint qflags = 0; 356 uint qflags = 0;
356 357
357 if (mask & XFS_AT_UID) { 358 if ((mask & XFS_AT_UID) && XFS_IS_UQUOTA_ON(mp)) {
358 uid = vap->va_uid; 359 uid = vap->va_uid;
359 qflags |= XFS_QMOPT_UQUOTA; 360 qflags |= XFS_QMOPT_UQUOTA;
360 } else { 361 } else {
361 uid = ip->i_d.di_uid; 362 uid = ip->i_d.di_uid;
362 } 363 }
363 if (mask & XFS_AT_GID) { 364 if ((mask & XFS_AT_GID) && XFS_IS_GQUOTA_ON(mp)) {
364 gid = vap->va_gid; 365 gid = vap->va_gid;
365 qflags |= XFS_QMOPT_GQUOTA; 366 qflags |= XFS_QMOPT_GQUOTA;
366 } else { 367 } else {
367 gid = ip->i_d.di_gid; 368 gid = ip->i_d.di_gid;
368 } 369 }
370 if ((mask & XFS_AT_PROJID) && XFS_IS_PQUOTA_ON(mp)) {
371 projid = vap->va_projid;
372 qflags |= XFS_QMOPT_PQUOTA;
373 } else {
374 projid = ip->i_d.di_projid;
375 }
369 /* 376 /*
370 * We take a reference when we initialize udqp and gdqp, 377 * We take a reference when we initialize udqp and gdqp,
371 * so it is important that we never blindly double trip on 378 * so it is important that we never blindly double trip on
@@ -373,7 +380,8 @@ xfs_setattr(
373 */ 380 */
374 ASSERT(udqp == NULL); 381 ASSERT(udqp == NULL);
375 ASSERT(gdqp == NULL); 382 ASSERT(gdqp == NULL);
376 code = XFS_QM_DQVOPALLOC(mp, ip, uid,gid, qflags, &udqp, &gdqp); 383 code = XFS_QM_DQVOPALLOC(mp, ip, uid, gid, projid, qflags,
384 &udqp, &gdqp);
377 if (code) 385 if (code)
378 return (code); 386 return (code);
379 } 387 }
@@ -510,10 +518,11 @@ xfs_setattr(
510 goto error_return; 518 goto error_return;
511 } 519 }
512 /* 520 /*
513 * Do a quota reservation only if uid or gid is actually 521 * Do a quota reservation only if uid/projid/gid is actually
514 * going to change. 522 * going to change.
515 */ 523 */
516 if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) || 524 if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
525 (XFS_IS_PQUOTA_ON(mp) && iprojid != projid) ||
517 (XFS_IS_GQUOTA_ON(mp) && igid != gid)) { 526 (XFS_IS_GQUOTA_ON(mp) && igid != gid)) {
518 ASSERT(tp); 527 ASSERT(tp);
519 code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp, 528 code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp,
@@ -774,6 +783,7 @@ xfs_setattr(
774 } 783 }
775 if (igid != gid) { 784 if (igid != gid) {
776 if (XFS_IS_GQUOTA_ON(mp)) { 785 if (XFS_IS_GQUOTA_ON(mp)) {
786 ASSERT(!XFS_IS_PQUOTA_ON(mp));
777 ASSERT(mask & XFS_AT_GID); 787 ASSERT(mask & XFS_AT_GID);
778 ASSERT(gdqp); 788 ASSERT(gdqp);
779 olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip, 789 olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
@@ -782,6 +792,13 @@ xfs_setattr(
782 ip->i_d.di_gid = gid; 792 ip->i_d.di_gid = gid;
783 } 793 }
784 if (iprojid != projid) { 794 if (iprojid != projid) {
795 if (XFS_IS_PQUOTA_ON(mp)) {
796 ASSERT(!XFS_IS_GQUOTA_ON(mp));
797 ASSERT(mask & XFS_AT_PROJID);
798 ASSERT(gdqp);
799 olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
800 &ip->i_gdquot, gdqp);
801 }
785 ip->i_d.di_projid = projid; 802 ip->i_d.di_projid = projid;
786 /* 803 /*
787 * We may have to rev the inode as well as 804 * We may have to rev the inode as well as
@@ -1907,7 +1924,7 @@ xfs_create(
1907 * Make sure that we have allocated dquot(s) on disk. 1924 * Make sure that we have allocated dquot(s) on disk.
1908 */ 1925 */
1909 error = XFS_QM_DQVOPALLOC(mp, dp, 1926 error = XFS_QM_DQVOPALLOC(mp, dp,
1910 current_fsuid(credp), current_fsgid(credp), 1927 current_fsuid(credp), current_fsgid(credp), prid,
1911 XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp); 1928 XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp);
1912 if (error) 1929 if (error)
1913 goto std_return; 1930 goto std_return;
@@ -2812,7 +2829,7 @@ xfs_mkdir(
2812 * Make sure that we have allocated dquot(s) on disk. 2829 * Make sure that we have allocated dquot(s) on disk.
2813 */ 2830 */
2814 error = XFS_QM_DQVOPALLOC(mp, dp, 2831 error = XFS_QM_DQVOPALLOC(mp, dp,
2815 current_fsuid(credp), current_fsgid(credp), 2832 current_fsuid(credp), current_fsgid(credp), prid,
2816 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); 2833 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
2817 if (error) 2834 if (error)
2818 goto std_return; 2835 goto std_return;
@@ -3366,7 +3383,7 @@ xfs_symlink(
3366 * Make sure that we have allocated dquot(s) on disk. 3383 * Make sure that we have allocated dquot(s) on disk.
3367 */ 3384 */
3368 error = XFS_QM_DQVOPALLOC(mp, dp, 3385 error = XFS_QM_DQVOPALLOC(mp, dp,
3369 current_fsuid(credp), current_fsgid(credp), 3386 current_fsuid(credp), current_fsgid(credp), prid,
3370 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); 3387 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
3371 if (error) 3388 if (error)
3372 goto std_return; 3389 goto std_return;