aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_qm.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_qm.c')
-rw-r--r--fs/xfs/xfs_qm.c243
1 files changed, 174 insertions, 69 deletions
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 7a3e007b49f4..d320794d03ce 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -137,6 +137,7 @@ xfs_qm_dqpurge(
137 struct xfs_mount *mp = dqp->q_mount; 137 struct xfs_mount *mp = dqp->q_mount;
138 struct xfs_quotainfo *qi = mp->m_quotainfo; 138 struct xfs_quotainfo *qi = mp->m_quotainfo;
139 struct xfs_dquot *gdqp = NULL; 139 struct xfs_dquot *gdqp = NULL;
140 struct xfs_dquot *pdqp = NULL;
140 141
141 xfs_dqlock(dqp); 142 xfs_dqlock(dqp);
142 if ((dqp->dq_flags & XFS_DQ_FREEING) || dqp->q_nrefs != 0) { 143 if ((dqp->dq_flags & XFS_DQ_FREEING) || dqp->q_nrefs != 0) {
@@ -145,8 +146,7 @@ xfs_qm_dqpurge(
145 } 146 }
146 147
147 /* 148 /*
148 * If this quota has a group hint attached, prepare for releasing it 149 * If this quota has a hint attached, prepare for releasing it now.
149 * now.
150 */ 150 */
151 gdqp = dqp->q_gdquot; 151 gdqp = dqp->q_gdquot;
152 if (gdqp) { 152 if (gdqp) {
@@ -154,6 +154,12 @@ xfs_qm_dqpurge(
154 dqp->q_gdquot = NULL; 154 dqp->q_gdquot = NULL;
155 } 155 }
156 156
157 pdqp = dqp->q_pdquot;
158 if (pdqp) {
159 xfs_dqlock(pdqp);
160 dqp->q_pdquot = NULL;
161 }
162
157 dqp->dq_flags |= XFS_DQ_FREEING; 163 dqp->dq_flags |= XFS_DQ_FREEING;
158 164
159 xfs_dqflock(dqp); 165 xfs_dqflock(dqp);
@@ -208,6 +214,8 @@ xfs_qm_dqpurge(
208 214
209 if (gdqp) 215 if (gdqp)
210 xfs_qm_dqput(gdqp); 216 xfs_qm_dqput(gdqp);
217 if (pdqp)
218 xfs_qm_dqput(pdqp);
211 return 0; 219 return 0;
212} 220}
213 221
@@ -364,6 +372,10 @@ xfs_qm_unmount_quotas(
364 IRELE(mp->m_quotainfo->qi_gquotaip); 372 IRELE(mp->m_quotainfo->qi_gquotaip);
365 mp->m_quotainfo->qi_gquotaip = NULL; 373 mp->m_quotainfo->qi_gquotaip = NULL;
366 } 374 }
375 if (mp->m_quotainfo->qi_pquotaip) {
376 IRELE(mp->m_quotainfo->qi_pquotaip);
377 mp->m_quotainfo->qi_pquotaip = NULL;
378 }
367 } 379 }
368} 380}
369 381
@@ -410,7 +422,10 @@ xfs_qm_dqattach_one(
410 * be reclaimed as long as we have a ref from inode and we 422 * be reclaimed as long as we have a ref from inode and we
411 * hold the ilock. 423 * hold the ilock.
412 */ 424 */
413 dqp = udqhint->q_gdquot; 425 if (type == XFS_DQ_GROUP)
426 dqp = udqhint->q_gdquot;
427 else
428 dqp = udqhint->q_pdquot;
414 if (dqp && be32_to_cpu(dqp->q_core.d_id) == id) { 429 if (dqp && be32_to_cpu(dqp->q_core.d_id) == id) {
415 ASSERT(*IO_idqpp == NULL); 430 ASSERT(*IO_idqpp == NULL);
416 431
@@ -453,28 +468,42 @@ xfs_qm_dqattach_one(
453 468
454 469
455/* 470/*
456 * Given a udquot and gdquot, attach a ptr to the group dquot in the 471 * Given a udquot and group/project type, attach the group/project
457 * udquot as a hint for future lookups. 472 * dquot pointer to the udquot as a hint for future lookups.
458 */ 473 */
459STATIC void 474STATIC void
460xfs_qm_dqattach_grouphint( 475xfs_qm_dqattach_hint(
461 xfs_dquot_t *udq, 476 struct xfs_inode *ip,
462 xfs_dquot_t *gdq) 477 int type)
463{ 478{
464 xfs_dquot_t *tmp; 479 struct xfs_dquot **dqhintp;
480 struct xfs_dquot *dqp;
481 struct xfs_dquot *udq = ip->i_udquot;
482
483 ASSERT(type == XFS_DQ_GROUP || type == XFS_DQ_PROJ);
465 484
466 xfs_dqlock(udq); 485 xfs_dqlock(udq);
467 486
468 tmp = udq->q_gdquot; 487 if (type == XFS_DQ_GROUP) {
469 if (tmp) { 488 dqp = ip->i_gdquot;
470 if (tmp == gdq) 489 dqhintp = &udq->q_gdquot;
490 } else {
491 dqp = ip->i_pdquot;
492 dqhintp = &udq->q_pdquot;
493 }
494
495 if (*dqhintp) {
496 struct xfs_dquot *tmp;
497
498 if (*dqhintp == dqp)
471 goto done; 499 goto done;
472 500
473 udq->q_gdquot = NULL; 501 tmp = *dqhintp;
502 *dqhintp = NULL;
474 xfs_qm_dqrele(tmp); 503 xfs_qm_dqrele(tmp);
475 } 504 }
476 505
477 udq->q_gdquot = xfs_qm_dqhold(gdq); 506 *dqhintp = xfs_qm_dqhold(dqp);
478done: 507done:
479 xfs_dqunlock(udq); 508 xfs_dqunlock(udq);
480} 509}
@@ -527,12 +556,8 @@ xfs_qm_dqattach_locked(
527 } 556 }
528 557
529 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 558 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
530 if (XFS_IS_OQUOTA_ON(mp)) { 559 if (XFS_IS_GQUOTA_ON(mp)) {
531 error = XFS_IS_GQUOTA_ON(mp) ? 560 error = xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
532 xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
533 flags & XFS_QMOPT_DQALLOC,
534 ip->i_udquot, &ip->i_gdquot) :
535 xfs_qm_dqattach_one(ip, xfs_get_projid(ip), XFS_DQ_PROJ,
536 flags & XFS_QMOPT_DQALLOC, 561 flags & XFS_QMOPT_DQALLOC,
537 ip->i_udquot, &ip->i_gdquot); 562 ip->i_udquot, &ip->i_gdquot);
538 /* 563 /*
@@ -544,14 +569,28 @@ xfs_qm_dqattach_locked(
544 nquotas++; 569 nquotas++;
545 } 570 }
546 571
572 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
573 if (XFS_IS_PQUOTA_ON(mp)) {
574 error = xfs_qm_dqattach_one(ip, xfs_get_projid(ip), XFS_DQ_PROJ,
575 flags & XFS_QMOPT_DQALLOC,
576 ip->i_udquot, &ip->i_pdquot);
577 /*
578 * Don't worry about the udquot that we may have
579 * attached above. It'll get detached, if not already.
580 */
581 if (error)
582 goto done;
583 nquotas++;
584 }
585
547 /* 586 /*
548 * Attach this group quota to the user quota as a hint. 587 * Attach this group/project quota to the user quota as a hint.
549 * This WON'T, in general, result in a thrash. 588 * This WON'T, in general, result in a thrash.
550 */ 589 */
551 if (nquotas == 2) { 590 if (nquotas > 1 && ip->i_udquot) {
552 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 591 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
553 ASSERT(ip->i_udquot); 592 ASSERT(ip->i_gdquot || !XFS_IS_GQUOTA_ON(mp));
554 ASSERT(ip->i_gdquot); 593 ASSERT(ip->i_pdquot || !XFS_IS_PQUOTA_ON(mp));
555 594
556 /* 595 /*
557 * We do not have i_udquot locked at this point, but this check 596 * We do not have i_udquot locked at this point, but this check
@@ -560,7 +599,10 @@ xfs_qm_dqattach_locked(
560 * succeed in general. 599 * succeed in general.
561 */ 600 */
562 if (ip->i_udquot->q_gdquot != ip->i_gdquot) 601 if (ip->i_udquot->q_gdquot != ip->i_gdquot)
563 xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot); 602 xfs_qm_dqattach_hint(ip, XFS_DQ_GROUP);
603
604 if (ip->i_udquot->q_pdquot != ip->i_pdquot)
605 xfs_qm_dqattach_hint(ip, XFS_DQ_PROJ);
564 } 606 }
565 607
566 done: 608 done:
@@ -568,8 +610,10 @@ xfs_qm_dqattach_locked(
568 if (!error) { 610 if (!error) {
569 if (XFS_IS_UQUOTA_ON(mp)) 611 if (XFS_IS_UQUOTA_ON(mp))
570 ASSERT(ip->i_udquot); 612 ASSERT(ip->i_udquot);
571 if (XFS_IS_OQUOTA_ON(mp)) 613 if (XFS_IS_GQUOTA_ON(mp))
572 ASSERT(ip->i_gdquot); 614 ASSERT(ip->i_gdquot);
615 if (XFS_IS_PQUOTA_ON(mp))
616 ASSERT(ip->i_pdquot);
573 } 617 }
574 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 618 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
575#endif 619#endif
@@ -602,7 +646,7 @@ void
602xfs_qm_dqdetach( 646xfs_qm_dqdetach(
603 xfs_inode_t *ip) 647 xfs_inode_t *ip)
604{ 648{
605 if (!(ip->i_udquot || ip->i_gdquot)) 649 if (!(ip->i_udquot || ip->i_gdquot || ip->i_pdquot))
606 return; 650 return;
607 651
608 trace_xfs_dquot_dqdetach(ip); 652 trace_xfs_dquot_dqdetach(ip);
@@ -616,6 +660,10 @@ xfs_qm_dqdetach(
616 xfs_qm_dqrele(ip->i_gdquot); 660 xfs_qm_dqrele(ip->i_gdquot);
617 ip->i_gdquot = NULL; 661 ip->i_gdquot = NULL;
618 } 662 }
663 if (ip->i_pdquot) {
664 xfs_qm_dqrele(ip->i_pdquot);
665 ip->i_pdquot = NULL;
666 }
619} 667}
620 668
621int 669int
@@ -660,6 +708,7 @@ xfs_qm_init_quotainfo(
660 708
661 INIT_RADIX_TREE(&qinf->qi_uquota_tree, GFP_NOFS); 709 INIT_RADIX_TREE(&qinf->qi_uquota_tree, GFP_NOFS);
662 INIT_RADIX_TREE(&qinf->qi_gquota_tree, GFP_NOFS); 710 INIT_RADIX_TREE(&qinf->qi_gquota_tree, GFP_NOFS);
711 INIT_RADIX_TREE(&qinf->qi_pquota_tree, GFP_NOFS);
663 mutex_init(&qinf->qi_tree_lock); 712 mutex_init(&qinf->qi_tree_lock);
664 713
665 INIT_LIST_HEAD(&qinf->qi_lru_list); 714 INIT_LIST_HEAD(&qinf->qi_lru_list);
@@ -761,6 +810,10 @@ xfs_qm_destroy_quotainfo(
761 IRELE(qi->qi_gquotaip); 810 IRELE(qi->qi_gquotaip);
762 qi->qi_gquotaip = NULL; 811 qi->qi_gquotaip = NULL;
763 } 812 }
813 if (qi->qi_pquotaip) {
814 IRELE(qi->qi_pquotaip);
815 qi->qi_pquotaip = NULL;
816 }
764 mutex_destroy(&qi->qi_quotaofflock); 817 mutex_destroy(&qi->qi_quotaofflock);
765 kmem_free(qi); 818 kmem_free(qi);
766 mp->m_quotainfo = NULL; 819 mp->m_quotainfo = NULL;
@@ -1269,13 +1322,14 @@ xfs_qm_quotacheck(
1269 LIST_HEAD (buffer_list); 1322 LIST_HEAD (buffer_list);
1270 struct xfs_inode *uip = mp->m_quotainfo->qi_uquotaip; 1323 struct xfs_inode *uip = mp->m_quotainfo->qi_uquotaip;
1271 struct xfs_inode *gip = mp->m_quotainfo->qi_gquotaip; 1324 struct xfs_inode *gip = mp->m_quotainfo->qi_gquotaip;
1325 struct xfs_inode *pip = mp->m_quotainfo->qi_pquotaip;
1272 1326
1273 count = INT_MAX; 1327 count = INT_MAX;
1274 structsz = 1; 1328 structsz = 1;
1275 lastino = 0; 1329 lastino = 0;
1276 flags = 0; 1330 flags = 0;
1277 1331
1278 ASSERT(uip || gip); 1332 ASSERT(uip || gip || pip);
1279 ASSERT(XFS_IS_QUOTA_RUNNING(mp)); 1333 ASSERT(XFS_IS_QUOTA_RUNNING(mp));
1280 1334
1281 xfs_notice(mp, "Quotacheck needed: Please wait."); 1335 xfs_notice(mp, "Quotacheck needed: Please wait.");
@@ -1294,13 +1348,19 @@ xfs_qm_quotacheck(
1294 } 1348 }
1295 1349
1296 if (gip) { 1350 if (gip) {
1297 error = xfs_qm_dqiterate(mp, gip, XFS_IS_GQUOTA_ON(mp) ? 1351 error = xfs_qm_dqiterate(mp, gip, XFS_QMOPT_GQUOTA,
1298 XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA,
1299 &buffer_list); 1352 &buffer_list);
1300 if (error) 1353 if (error)
1301 goto error_return; 1354 goto error_return;
1302 flags |= XFS_IS_GQUOTA_ON(mp) ? 1355 flags |= XFS_GQUOTA_CHKD;
1303 XFS_GQUOTA_CHKD : XFS_PQUOTA_CHKD; 1356 }
1357
1358 if (pip) {
1359 error = xfs_qm_dqiterate(mp, pip, XFS_QMOPT_PQUOTA,
1360 &buffer_list);
1361 if (error)
1362 goto error_return;
1363 flags |= XFS_PQUOTA_CHKD;
1304 } 1364 }
1305 1365
1306 do { 1366 do {
@@ -1397,6 +1457,7 @@ xfs_qm_init_quotainos(
1397{ 1457{
1398 struct xfs_inode *uip = NULL; 1458 struct xfs_inode *uip = NULL;
1399 struct xfs_inode *gip = NULL; 1459 struct xfs_inode *gip = NULL;
1460 struct xfs_inode *pip = NULL;
1400 int error; 1461 int error;
1401 __int64_t sbflags = 0; 1462 __int64_t sbflags = 0;
1402 uint flags = 0; 1463 uint flags = 0;
@@ -1415,7 +1476,7 @@ xfs_qm_init_quotainos(
1415 if (error) 1476 if (error)
1416 return XFS_ERROR(error); 1477 return XFS_ERROR(error);
1417 } 1478 }
1418 if (XFS_IS_OQUOTA_ON(mp) && 1479 if (XFS_IS_GQUOTA_ON(mp) &&
1419 mp->m_sb.sb_gquotino != NULLFSINO) { 1480 mp->m_sb.sb_gquotino != NULLFSINO) {
1420 ASSERT(mp->m_sb.sb_gquotino > 0); 1481 ASSERT(mp->m_sb.sb_gquotino > 0);
1421 error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 1482 error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
@@ -1423,6 +1484,15 @@ xfs_qm_init_quotainos(
1423 if (error) 1484 if (error)
1424 goto error_rele; 1485 goto error_rele;
1425 } 1486 }
1487 /* XXX: Use gquotino for now */
1488 if (XFS_IS_PQUOTA_ON(mp) &&
1489 mp->m_sb.sb_gquotino != NULLFSINO) {
1490 ASSERT(mp->m_sb.sb_gquotino > 0);
1491 error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
1492 0, 0, &pip);
1493 if (error)
1494 goto error_rele;
1495 }
1426 } else { 1496 } else {
1427 flags |= XFS_QMOPT_SBVERSION; 1497 flags |= XFS_QMOPT_SBVERSION;
1428 sbflags |= (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | 1498 sbflags |= (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
@@ -1430,7 +1500,7 @@ xfs_qm_init_quotainos(
1430 } 1500 }
1431 1501
1432 /* 1502 /*
1433 * Create the two inodes, if they don't exist already. The changes 1503 * Create the three inodes, if they don't exist already. The changes
1434 * made above will get added to a transaction and logged in one of 1504 * made above will get added to a transaction and logged in one of
1435 * the qino_alloc calls below. If the device is readonly, 1505 * the qino_alloc calls below. If the device is readonly,
1436 * temporarily switch to read-write to do this. 1506 * temporarily switch to read-write to do this.
@@ -1444,17 +1514,27 @@ xfs_qm_init_quotainos(
1444 1514
1445 flags &= ~XFS_QMOPT_SBVERSION; 1515 flags &= ~XFS_QMOPT_SBVERSION;
1446 } 1516 }
1447 if (XFS_IS_OQUOTA_ON(mp) && gip == NULL) { 1517 if (XFS_IS_GQUOTA_ON(mp) && gip == NULL) {
1448 flags |= (XFS_IS_GQUOTA_ON(mp) ?
1449 XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA);
1450 error = xfs_qm_qino_alloc(mp, &gip, 1518 error = xfs_qm_qino_alloc(mp, &gip,
1451 sbflags | XFS_SB_GQUOTINO, flags); 1519 sbflags | XFS_SB_GQUOTINO,
1520 flags | XFS_QMOPT_GQUOTA);
1521 if (error)
1522 goto error_rele;
1523
1524 flags &= ~XFS_QMOPT_SBVERSION;
1525 }
1526 if (XFS_IS_PQUOTA_ON(mp) && pip == NULL) {
1527 /* XXX: Use XFS_SB_GQUOTINO for now */
1528 error = xfs_qm_qino_alloc(mp, &pip,
1529 sbflags | XFS_SB_GQUOTINO,
1530 flags | XFS_QMOPT_PQUOTA);
1452 if (error) 1531 if (error)
1453 goto error_rele; 1532 goto error_rele;
1454 } 1533 }
1455 1534
1456 mp->m_quotainfo->qi_uquotaip = uip; 1535 mp->m_quotainfo->qi_uquotaip = uip;
1457 mp->m_quotainfo->qi_gquotaip = gip; 1536 mp->m_quotainfo->qi_gquotaip = gip;
1537 mp->m_quotainfo->qi_pquotaip = pip;
1458 1538
1459 return 0; 1539 return 0;
1460 1540
@@ -1463,6 +1543,8 @@ error_rele:
1463 IRELE(uip); 1543 IRELE(uip);
1464 if (gip) 1544 if (gip)
1465 IRELE(gip); 1545 IRELE(gip);
1546 if (pip)
1547 IRELE(pip);
1466 return XFS_ERROR(error); 1548 return XFS_ERROR(error);
1467} 1549}
1468 1550
@@ -1657,11 +1739,13 @@ xfs_qm_vop_dqalloc(
1657 prid_t prid, 1739 prid_t prid,
1658 uint flags, 1740 uint flags,
1659 struct xfs_dquot **O_udqpp, 1741 struct xfs_dquot **O_udqpp,
1660 struct xfs_dquot **O_gdqpp) 1742 struct xfs_dquot **O_gdqpp,
1743 struct xfs_dquot **O_pdqpp)
1661{ 1744{
1662 struct xfs_mount *mp = ip->i_mount; 1745 struct xfs_mount *mp = ip->i_mount;
1663 struct xfs_dquot *uq = NULL; 1746 struct xfs_dquot *uq = NULL;
1664 struct xfs_dquot *gq = NULL; 1747 struct xfs_dquot *gq = NULL;
1748 struct xfs_dquot *pq = NULL;
1665 int error; 1749 int error;
1666 uint lockflags; 1750 uint lockflags;
1667 1751
@@ -1741,24 +1825,25 @@ xfs_qm_vop_dqalloc(
1741 ASSERT(ip->i_gdquot); 1825 ASSERT(ip->i_gdquot);
1742 gq = xfs_qm_dqhold(ip->i_gdquot); 1826 gq = xfs_qm_dqhold(ip->i_gdquot);
1743 } 1827 }
1744 } else if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) { 1828 }
1829 if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) {
1745 if (xfs_get_projid(ip) != prid) { 1830 if (xfs_get_projid(ip) != prid) {
1746 xfs_iunlock(ip, lockflags); 1831 xfs_iunlock(ip, lockflags);
1747 error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid, 1832 error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid,
1748 XFS_DQ_PROJ, 1833 XFS_DQ_PROJ,
1749 XFS_QMOPT_DQALLOC | 1834 XFS_QMOPT_DQALLOC |
1750 XFS_QMOPT_DOWARN, 1835 XFS_QMOPT_DOWARN,
1751 &gq); 1836 &pq);
1752 if (error) { 1837 if (error) {
1753 ASSERT(error != ENOENT); 1838 ASSERT(error != ENOENT);
1754 goto error_rele; 1839 goto error_rele;
1755 } 1840 }
1756 xfs_dqunlock(gq); 1841 xfs_dqunlock(pq);
1757 lockflags = XFS_ILOCK_SHARED; 1842 lockflags = XFS_ILOCK_SHARED;
1758 xfs_ilock(ip, lockflags); 1843 xfs_ilock(ip, lockflags);
1759 } else { 1844 } else {
1760 ASSERT(ip->i_gdquot); 1845 ASSERT(ip->i_pdquot);
1761 gq = xfs_qm_dqhold(ip->i_gdquot); 1846 pq = xfs_qm_dqhold(ip->i_pdquot);
1762 } 1847 }
1763 } 1848 }
1764 if (uq) 1849 if (uq)
@@ -1773,9 +1858,15 @@ xfs_qm_vop_dqalloc(
1773 *O_gdqpp = gq; 1858 *O_gdqpp = gq;
1774 else if (gq) 1859 else if (gq)
1775 xfs_qm_dqrele(gq); 1860 xfs_qm_dqrele(gq);
1861 if (O_pdqpp)
1862 *O_pdqpp = pq;
1863 else if (pq)
1864 xfs_qm_dqrele(pq);
1776 return 0; 1865 return 0;
1777 1866
1778error_rele: 1867error_rele:
1868 if (gq)
1869 xfs_qm_dqrele(gq);
1779 if (uq) 1870 if (uq)
1780 xfs_qm_dqrele(uq); 1871 xfs_qm_dqrele(uq);
1781 return error; 1872 return error;
@@ -1830,14 +1921,17 @@ xfs_qm_vop_chown_reserve(
1830 struct xfs_inode *ip, 1921 struct xfs_inode *ip,
1831 struct xfs_dquot *udqp, 1922 struct xfs_dquot *udqp,
1832 struct xfs_dquot *gdqp, 1923 struct xfs_dquot *gdqp,
1924 struct xfs_dquot *pdqp,
1833 uint flags) 1925 uint flags)
1834{ 1926{
1835 struct xfs_mount *mp = ip->i_mount; 1927 struct xfs_mount *mp = ip->i_mount;
1836 uint delblks, blkflags, prjflags = 0; 1928 uint delblks, blkflags, prjflags = 0;
1837 struct xfs_dquot *udq_unres = NULL; 1929 struct xfs_dquot *udq_unres = NULL;
1838 struct xfs_dquot *gdq_unres = NULL; 1930 struct xfs_dquot *gdq_unres = NULL;
1931 struct xfs_dquot *pdq_unres = NULL;
1839 struct xfs_dquot *udq_delblks = NULL; 1932 struct xfs_dquot *udq_delblks = NULL;
1840 struct xfs_dquot *gdq_delblks = NULL; 1933 struct xfs_dquot *gdq_delblks = NULL;
1934 struct xfs_dquot *pdq_delblks = NULL;
1841 int error; 1935 int error;
1842 1936
1843 1937
@@ -1861,24 +1955,28 @@ xfs_qm_vop_chown_reserve(
1861 udq_unres = ip->i_udquot; 1955 udq_unres = ip->i_udquot;
1862 } 1956 }
1863 } 1957 }
1864 if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) { 1958 if (XFS_IS_GQUOTA_ON(ip->i_mount) && gdqp &&
1865 if (XFS_IS_PQUOTA_ON(ip->i_mount) && 1959 ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id)) {
1866 xfs_get_projid(ip) != be32_to_cpu(gdqp->q_core.d_id)) 1960 gdq_delblks = gdqp;
1867 prjflags = XFS_QMOPT_ENOSPC; 1961 if (delblks) {
1868 1962 ASSERT(ip->i_gdquot);
1869 if (prjflags || 1963 gdq_unres = ip->i_gdquot;
1870 (XFS_IS_GQUOTA_ON(ip->i_mount) && 1964 }
1871 ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id))) { 1965 }
1872 gdq_delblks = gdqp; 1966
1873 if (delblks) { 1967 if (XFS_IS_PQUOTA_ON(ip->i_mount) && pdqp &&
1874 ASSERT(ip->i_gdquot); 1968 xfs_get_projid(ip) != be32_to_cpu(pdqp->q_core.d_id)) {
1875 gdq_unres = ip->i_gdquot; 1969 prjflags = XFS_QMOPT_ENOSPC;
1876 } 1970 pdq_delblks = pdqp;
1971 if (delblks) {
1972 ASSERT(ip->i_pdquot);
1973 pdq_unres = ip->i_pdquot;
1877 } 1974 }
1878 } 1975 }
1879 1976
1880 error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount, 1977 error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount,
1881 udq_delblks, gdq_delblks, ip->i_d.di_nblocks, 1, 1978 udq_delblks, gdq_delblks, pdq_delblks,
1979 ip->i_d.di_nblocks, 1,
1882 flags | blkflags | prjflags); 1980 flags | blkflags | prjflags);
1883 if (error) 1981 if (error)
1884 return error; 1982 return error;
@@ -1893,16 +1991,17 @@ xfs_qm_vop_chown_reserve(
1893 /* 1991 /*
1894 * Do the reservations first. Unreservation can't fail. 1992 * Do the reservations first. Unreservation can't fail.
1895 */ 1993 */
1896 ASSERT(udq_delblks || gdq_delblks); 1994 ASSERT(udq_delblks || gdq_delblks || pdq_delblks);
1897 ASSERT(udq_unres || gdq_unres); 1995 ASSERT(udq_unres || gdq_unres || pdq_unres);
1898 error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, 1996 error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
1899 udq_delblks, gdq_delblks, (xfs_qcnt_t)delblks, 0, 1997 udq_delblks, gdq_delblks, pdq_delblks,
1998 (xfs_qcnt_t)delblks, 0,
1900 flags | blkflags | prjflags); 1999 flags | blkflags | prjflags);
1901 if (error) 2000 if (error)
1902 return error; 2001 return error;
1903 xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, 2002 xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
1904 udq_unres, gdq_unres, -((xfs_qcnt_t)delblks), 0, 2003 udq_unres, gdq_unres, pdq_unres,
1905 blkflags); 2004 -((xfs_qcnt_t)delblks), 0, blkflags);
1906 } 2005 }
1907 2006
1908 return (0); 2007 return (0);
@@ -1941,7 +2040,8 @@ xfs_qm_vop_create_dqattach(
1941 struct xfs_trans *tp, 2040 struct xfs_trans *tp,
1942 struct xfs_inode *ip, 2041 struct xfs_inode *ip,
1943 struct xfs_dquot *udqp, 2042 struct xfs_dquot *udqp,
1944 struct xfs_dquot *gdqp) 2043 struct xfs_dquot *gdqp,
2044 struct xfs_dquot *pdqp)
1945{ 2045{
1946 struct xfs_mount *mp = tp->t_mountp; 2046 struct xfs_mount *mp = tp->t_mountp;
1947 2047
@@ -1961,13 +2061,18 @@ xfs_qm_vop_create_dqattach(
1961 } 2061 }
1962 if (gdqp) { 2062 if (gdqp) {
1963 ASSERT(ip->i_gdquot == NULL); 2063 ASSERT(ip->i_gdquot == NULL);
1964 ASSERT(XFS_IS_OQUOTA_ON(mp)); 2064 ASSERT(XFS_IS_GQUOTA_ON(mp));
1965 ASSERT((XFS_IS_GQUOTA_ON(mp) ? 2065 ASSERT(ip->i_d.di_gid == be32_to_cpu(gdqp->q_core.d_id));
1966 ip->i_d.di_gid : xfs_get_projid(ip)) ==
1967 be32_to_cpu(gdqp->q_core.d_id));
1968
1969 ip->i_gdquot = xfs_qm_dqhold(gdqp); 2066 ip->i_gdquot = xfs_qm_dqhold(gdqp);
1970 xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1); 2067 xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1);
1971 } 2068 }
2069 if (pdqp) {
2070 ASSERT(ip->i_pdquot == NULL);
2071 ASSERT(XFS_IS_PQUOTA_ON(mp));
2072 ASSERT(xfs_get_projid(ip) == be32_to_cpu(pdqp->q_core.d_id));
2073
2074 ip->i_pdquot = xfs_qm_dqhold(pdqp);
2075 xfs_trans_mod_dquot(tp, pdqp, XFS_TRANS_DQ_ICOUNT, 1);
2076 }
1972} 2077}
1973 2078