diff options
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 33 |
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; |