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.c394
1 files changed, 254 insertions, 140 deletions
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index b75c9bb6e71e..d320794d03ce 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -70,7 +70,7 @@ xfs_qm_dquot_walk(
70 void *data) 70 void *data)
71{ 71{
72 struct xfs_quotainfo *qi = mp->m_quotainfo; 72 struct xfs_quotainfo *qi = mp->m_quotainfo;
73 struct radix_tree_root *tree = XFS_DQUOT_TREE(qi, type); 73 struct radix_tree_root *tree = xfs_dquot_tree(qi, type);
74 uint32_t next_index; 74 uint32_t next_index;
75 int last_error = 0; 75 int last_error = 0;
76 int skipped; 76 int skipped;
@@ -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);
@@ -189,7 +195,7 @@ xfs_qm_dqpurge(
189 xfs_dqfunlock(dqp); 195 xfs_dqfunlock(dqp);
190 xfs_dqunlock(dqp); 196 xfs_dqunlock(dqp);
191 197
192 radix_tree_delete(XFS_DQUOT_TREE(qi, dqp->q_core.d_flags), 198 radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags),
193 be32_to_cpu(dqp->q_core.d_id)); 199 be32_to_cpu(dqp->q_core.d_id));
194 qi->qi_dquots--; 200 qi->qi_dquots--;
195 201
@@ -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
@@ -299,8 +307,10 @@ xfs_qm_mount_quotas(
299 */ 307 */
300 if (!XFS_IS_UQUOTA_ON(mp)) 308 if (!XFS_IS_UQUOTA_ON(mp))
301 mp->m_qflags &= ~XFS_UQUOTA_CHKD; 309 mp->m_qflags &= ~XFS_UQUOTA_CHKD;
302 if (!(XFS_IS_GQUOTA_ON(mp) || XFS_IS_PQUOTA_ON(mp))) 310 if (!XFS_IS_GQUOTA_ON(mp))
303 mp->m_qflags &= ~XFS_OQUOTA_CHKD; 311 mp->m_qflags &= ~XFS_GQUOTA_CHKD;
312 if (!XFS_IS_PQUOTA_ON(mp))
313 mp->m_qflags &= ~XFS_PQUOTA_CHKD;
304 314
305 write_changes: 315 write_changes:
306 /* 316 /*
@@ -362,6 +372,10 @@ xfs_qm_unmount_quotas(
362 IRELE(mp->m_quotainfo->qi_gquotaip); 372 IRELE(mp->m_quotainfo->qi_gquotaip);
363 mp->m_quotainfo->qi_gquotaip = NULL; 373 mp->m_quotainfo->qi_gquotaip = NULL;
364 } 374 }
375 if (mp->m_quotainfo->qi_pquotaip) {
376 IRELE(mp->m_quotainfo->qi_pquotaip);
377 mp->m_quotainfo->qi_pquotaip = NULL;
378 }
365 } 379 }
366} 380}
367 381
@@ -408,7 +422,10 @@ xfs_qm_dqattach_one(
408 * 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
409 * hold the ilock. 423 * hold the ilock.
410 */ 424 */
411 dqp = udqhint->q_gdquot; 425 if (type == XFS_DQ_GROUP)
426 dqp = udqhint->q_gdquot;
427 else
428 dqp = udqhint->q_pdquot;
412 if (dqp && be32_to_cpu(dqp->q_core.d_id) == id) { 429 if (dqp && be32_to_cpu(dqp->q_core.d_id) == id) {
413 ASSERT(*IO_idqpp == NULL); 430 ASSERT(*IO_idqpp == NULL);
414 431
@@ -451,28 +468,42 @@ xfs_qm_dqattach_one(
451 468
452 469
453/* 470/*
454 * 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
455 * udquot as a hint for future lookups. 472 * dquot pointer to the udquot as a hint for future lookups.
456 */ 473 */
457STATIC void 474STATIC void
458xfs_qm_dqattach_grouphint( 475xfs_qm_dqattach_hint(
459 xfs_dquot_t *udq, 476 struct xfs_inode *ip,
460 xfs_dquot_t *gdq) 477 int type)
461{ 478{
462 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);
463 484
464 xfs_dqlock(udq); 485 xfs_dqlock(udq);
465 486
466 tmp = udq->q_gdquot; 487 if (type == XFS_DQ_GROUP) {
467 if (tmp) { 488 dqp = ip->i_gdquot;
468 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)
469 goto done; 499 goto done;
470 500
471 udq->q_gdquot = NULL; 501 tmp = *dqhintp;
502 *dqhintp = NULL;
472 xfs_qm_dqrele(tmp); 503 xfs_qm_dqrele(tmp);
473 } 504 }
474 505
475 udq->q_gdquot = xfs_qm_dqhold(gdq); 506 *dqhintp = xfs_qm_dqhold(dqp);
476done: 507done:
477 xfs_dqunlock(udq); 508 xfs_dqunlock(udq);
478} 509}
@@ -489,8 +520,7 @@ xfs_qm_need_dqattach(
489 return false; 520 return false;
490 if (!XFS_NOT_DQATTACHED(mp, ip)) 521 if (!XFS_NOT_DQATTACHED(mp, ip))
491 return false; 522 return false;
492 if (ip->i_ino == mp->m_sb.sb_uquotino || 523 if (xfs_is_quota_inode(&mp->m_sb, ip->i_ino))
493 ip->i_ino == mp->m_sb.sb_gquotino)
494 return false; 524 return false;
495 return true; 525 return true;
496} 526}
@@ -526,12 +556,8 @@ xfs_qm_dqattach_locked(
526 } 556 }
527 557
528 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 558 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
529 if (XFS_IS_OQUOTA_ON(mp)) { 559 if (XFS_IS_GQUOTA_ON(mp)) {
530 error = XFS_IS_GQUOTA_ON(mp) ? 560 error = xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
531 xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
532 flags & XFS_QMOPT_DQALLOC,
533 ip->i_udquot, &ip->i_gdquot) :
534 xfs_qm_dqattach_one(ip, xfs_get_projid(ip), XFS_DQ_PROJ,
535 flags & XFS_QMOPT_DQALLOC, 561 flags & XFS_QMOPT_DQALLOC,
536 ip->i_udquot, &ip->i_gdquot); 562 ip->i_udquot, &ip->i_gdquot);
537 /* 563 /*
@@ -543,14 +569,28 @@ xfs_qm_dqattach_locked(
543 nquotas++; 569 nquotas++;
544 } 570 }
545 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
546 /* 586 /*
547 * Attach this group quota to the user quota as a hint. 587 * Attach this group/project quota to the user quota as a hint.
548 * This WON'T, in general, result in a thrash. 588 * This WON'T, in general, result in a thrash.
549 */ 589 */
550 if (nquotas == 2) { 590 if (nquotas > 1 && ip->i_udquot) {
551 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 591 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
552 ASSERT(ip->i_udquot); 592 ASSERT(ip->i_gdquot || !XFS_IS_GQUOTA_ON(mp));
553 ASSERT(ip->i_gdquot); 593 ASSERT(ip->i_pdquot || !XFS_IS_PQUOTA_ON(mp));
554 594
555 /* 595 /*
556 * 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
@@ -559,7 +599,10 @@ xfs_qm_dqattach_locked(
559 * succeed in general. 599 * succeed in general.
560 */ 600 */
561 if (ip->i_udquot->q_gdquot != ip->i_gdquot) 601 if (ip->i_udquot->q_gdquot != ip->i_gdquot)
562 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);
563 } 606 }
564 607
565 done: 608 done:
@@ -567,8 +610,10 @@ xfs_qm_dqattach_locked(
567 if (!error) { 610 if (!error) {
568 if (XFS_IS_UQUOTA_ON(mp)) 611 if (XFS_IS_UQUOTA_ON(mp))
569 ASSERT(ip->i_udquot); 612 ASSERT(ip->i_udquot);
570 if (XFS_IS_OQUOTA_ON(mp)) 613 if (XFS_IS_GQUOTA_ON(mp))
571 ASSERT(ip->i_gdquot); 614 ASSERT(ip->i_gdquot);
615 if (XFS_IS_PQUOTA_ON(mp))
616 ASSERT(ip->i_pdquot);
572 } 617 }
573 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 618 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
574#endif 619#endif
@@ -601,13 +646,12 @@ void
601xfs_qm_dqdetach( 646xfs_qm_dqdetach(
602 xfs_inode_t *ip) 647 xfs_inode_t *ip)
603{ 648{
604 if (!(ip->i_udquot || ip->i_gdquot)) 649 if (!(ip->i_udquot || ip->i_gdquot || ip->i_pdquot))
605 return; 650 return;
606 651
607 trace_xfs_dquot_dqdetach(ip); 652 trace_xfs_dquot_dqdetach(ip);
608 653
609 ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_uquotino); 654 ASSERT(!xfs_is_quota_inode(&ip->i_mount->m_sb, ip->i_ino));
610 ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_gquotino);
611 if (ip->i_udquot) { 655 if (ip->i_udquot) {
612 xfs_qm_dqrele(ip->i_udquot); 656 xfs_qm_dqrele(ip->i_udquot);
613 ip->i_udquot = NULL; 657 ip->i_udquot = NULL;
@@ -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;
@@ -1152,7 +1205,7 @@ xfs_qm_dqusage_adjust(
1152 * rootino must have its resources accounted for, not so with the quota 1205 * rootino must have its resources accounted for, not so with the quota
1153 * inodes. 1206 * inodes.
1154 */ 1207 */
1155 if (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino) { 1208 if (xfs_is_quota_inode(&mp->m_sb, ino)) {
1156 *res = BULKSTAT_RV_NOTHING; 1209 *res = BULKSTAT_RV_NOTHING;
1157 return XFS_ERROR(EINVAL); 1210 return XFS_ERROR(EINVAL);
1158 } 1211 }
@@ -1262,19 +1315,21 @@ int
1262xfs_qm_quotacheck( 1315xfs_qm_quotacheck(
1263 xfs_mount_t *mp) 1316 xfs_mount_t *mp)
1264{ 1317{
1265 int done, count, error, error2; 1318 int done, count, error, error2;
1266 xfs_ino_t lastino; 1319 xfs_ino_t lastino;
1267 size_t structsz; 1320 size_t structsz;
1268 xfs_inode_t *uip, *gip; 1321 uint flags;
1269 uint flags; 1322 LIST_HEAD (buffer_list);
1270 LIST_HEAD (buffer_list); 1323 struct xfs_inode *uip = mp->m_quotainfo->qi_uquotaip;
1324 struct xfs_inode *gip = mp->m_quotainfo->qi_gquotaip;
1325 struct xfs_inode *pip = mp->m_quotainfo->qi_pquotaip;
1271 1326
1272 count = INT_MAX; 1327 count = INT_MAX;
1273 structsz = 1; 1328 structsz = 1;
1274 lastino = 0; 1329 lastino = 0;
1275 flags = 0; 1330 flags = 0;
1276 1331
1277 ASSERT(mp->m_quotainfo->qi_uquotaip || mp->m_quotainfo->qi_gquotaip); 1332 ASSERT(uip || gip || pip);
1278 ASSERT(XFS_IS_QUOTA_RUNNING(mp)); 1333 ASSERT(XFS_IS_QUOTA_RUNNING(mp));
1279 1334
1280 xfs_notice(mp, "Quotacheck needed: Please wait."); 1335 xfs_notice(mp, "Quotacheck needed: Please wait.");
@@ -1284,7 +1339,6 @@ xfs_qm_quotacheck(
1284 * their counters to zero. We need a clean slate. 1339 * their counters to zero. We need a clean slate.
1285 * We don't log our changes till later. 1340 * We don't log our changes till later.
1286 */ 1341 */
1287 uip = mp->m_quotainfo->qi_uquotaip;
1288 if (uip) { 1342 if (uip) {
1289 error = xfs_qm_dqiterate(mp, uip, XFS_QMOPT_UQUOTA, 1343 error = xfs_qm_dqiterate(mp, uip, XFS_QMOPT_UQUOTA,
1290 &buffer_list); 1344 &buffer_list);
@@ -1293,14 +1347,20 @@ xfs_qm_quotacheck(
1293 flags |= XFS_UQUOTA_CHKD; 1347 flags |= XFS_UQUOTA_CHKD;
1294 } 1348 }
1295 1349
1296 gip = mp->m_quotainfo->qi_gquotaip;
1297 if (gip) { 1350 if (gip) {
1298 error = xfs_qm_dqiterate(mp, gip, XFS_IS_GQUOTA_ON(mp) ? 1351 error = xfs_qm_dqiterate(mp, gip, XFS_QMOPT_GQUOTA,
1299 XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA,
1300 &buffer_list); 1352 &buffer_list);
1301 if (error) 1353 if (error)
1302 goto error_return; 1354 goto error_return;
1303 flags |= XFS_OQUOTA_CHKD; 1355 flags |= XFS_GQUOTA_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 {
@@ -1395,15 +1455,14 @@ STATIC int
1395xfs_qm_init_quotainos( 1455xfs_qm_init_quotainos(
1396 xfs_mount_t *mp) 1456 xfs_mount_t *mp)
1397{ 1457{
1398 xfs_inode_t *uip, *gip; 1458 struct xfs_inode *uip = NULL;
1399 int error; 1459 struct xfs_inode *gip = NULL;
1400 __int64_t sbflags; 1460 struct xfs_inode *pip = NULL;
1401 uint flags; 1461 int error;
1462 __int64_t sbflags = 0;
1463 uint flags = 0;
1402 1464
1403 ASSERT(mp->m_quotainfo); 1465 ASSERT(mp->m_quotainfo);
1404 uip = gip = NULL;
1405 sbflags = 0;
1406 flags = 0;
1407 1466
1408 /* 1467 /*
1409 * Get the uquota and gquota inodes 1468 * Get the uquota and gquota inodes
@@ -1412,19 +1471,27 @@ xfs_qm_init_quotainos(
1412 if (XFS_IS_UQUOTA_ON(mp) && 1471 if (XFS_IS_UQUOTA_ON(mp) &&
1413 mp->m_sb.sb_uquotino != NULLFSINO) { 1472 mp->m_sb.sb_uquotino != NULLFSINO) {
1414 ASSERT(mp->m_sb.sb_uquotino > 0); 1473 ASSERT(mp->m_sb.sb_uquotino > 0);
1415 if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, 1474 error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
1416 0, 0, &uip))) 1475 0, 0, &uip);
1476 if (error)
1417 return XFS_ERROR(error); 1477 return XFS_ERROR(error);
1418 } 1478 }
1419 if (XFS_IS_OQUOTA_ON(mp) && 1479 if (XFS_IS_GQUOTA_ON(mp) &&
1420 mp->m_sb.sb_gquotino != NULLFSINO) { 1480 mp->m_sb.sb_gquotino != NULLFSINO) {
1421 ASSERT(mp->m_sb.sb_gquotino > 0); 1481 ASSERT(mp->m_sb.sb_gquotino > 0);
1422 if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 1482 error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
1423 0, 0, &gip))) { 1483 0, 0, &gip);
1424 if (uip) 1484 if (error)
1425 IRELE(uip); 1485 goto error_rele;
1426 return XFS_ERROR(error); 1486 }
1427 } 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;
1428 } 1495 }
1429 } else { 1496 } else {
1430 flags |= XFS_QMOPT_SBVERSION; 1497 flags |= XFS_QMOPT_SBVERSION;
@@ -1433,36 +1500,52 @@ xfs_qm_init_quotainos(
1433 } 1500 }
1434 1501
1435 /* 1502 /*
1436 * 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
1437 * 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
1438 * the qino_alloc calls below. If the device is readonly, 1505 * the qino_alloc calls below. If the device is readonly,
1439 * temporarily switch to read-write to do this. 1506 * temporarily switch to read-write to do this.
1440 */ 1507 */
1441 if (XFS_IS_UQUOTA_ON(mp) && uip == NULL) { 1508 if (XFS_IS_UQUOTA_ON(mp) && uip == NULL) {
1442 if ((error = xfs_qm_qino_alloc(mp, &uip, 1509 error = xfs_qm_qino_alloc(mp, &uip,
1443 sbflags | XFS_SB_UQUOTINO, 1510 sbflags | XFS_SB_UQUOTINO,
1444 flags | XFS_QMOPT_UQUOTA))) 1511 flags | XFS_QMOPT_UQUOTA);
1445 return XFS_ERROR(error); 1512 if (error)
1513 goto error_rele;
1446 1514
1447 flags &= ~XFS_QMOPT_SBVERSION; 1515 flags &= ~XFS_QMOPT_SBVERSION;
1448 } 1516 }
1449 if (XFS_IS_OQUOTA_ON(mp) && gip == NULL) { 1517 if (XFS_IS_GQUOTA_ON(mp) && gip == NULL) {
1450 flags |= (XFS_IS_GQUOTA_ON(mp) ?
1451 XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA);
1452 error = xfs_qm_qino_alloc(mp, &gip, 1518 error = xfs_qm_qino_alloc(mp, &gip,
1453 sbflags | XFS_SB_GQUOTINO, flags); 1519 sbflags | XFS_SB_GQUOTINO,
1454 if (error) { 1520 flags | XFS_QMOPT_GQUOTA);
1455 if (uip) 1521 if (error)
1456 IRELE(uip); 1522 goto error_rele;
1457 1523
1458 return XFS_ERROR(error); 1524 flags &= ~XFS_QMOPT_SBVERSION;
1459 } 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);
1531 if (error)
1532 goto error_rele;
1460 } 1533 }
1461 1534
1462 mp->m_quotainfo->qi_uquotaip = uip; 1535 mp->m_quotainfo->qi_uquotaip = uip;
1463 mp->m_quotainfo->qi_gquotaip = gip; 1536 mp->m_quotainfo->qi_gquotaip = gip;
1537 mp->m_quotainfo->qi_pquotaip = pip;
1464 1538
1465 return 0; 1539 return 0;
1540
1541error_rele:
1542 if (uip)
1543 IRELE(uip);
1544 if (gip)
1545 IRELE(gip);
1546 if (pip)
1547 IRELE(pip);
1548 return XFS_ERROR(error);
1466} 1549}
1467 1550
1468STATIC void 1551STATIC void
@@ -1473,7 +1556,7 @@ xfs_qm_dqfree_one(
1473 struct xfs_quotainfo *qi = mp->m_quotainfo; 1556 struct xfs_quotainfo *qi = mp->m_quotainfo;
1474 1557
1475 mutex_lock(&qi->qi_tree_lock); 1558 mutex_lock(&qi->qi_tree_lock);
1476 radix_tree_delete(XFS_DQUOT_TREE(qi, dqp->q_core.d_flags), 1559 radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags),
1477 be32_to_cpu(dqp->q_core.d_id)); 1560 be32_to_cpu(dqp->q_core.d_id));
1478 1561
1479 qi->qi_dquots--; 1562 qi->qi_dquots--;
@@ -1656,10 +1739,13 @@ xfs_qm_vop_dqalloc(
1656 prid_t prid, 1739 prid_t prid,
1657 uint flags, 1740 uint flags,
1658 struct xfs_dquot **O_udqpp, 1741 struct xfs_dquot **O_udqpp,
1659 struct xfs_dquot **O_gdqpp) 1742 struct xfs_dquot **O_gdqpp,
1743 struct xfs_dquot **O_pdqpp)
1660{ 1744{
1661 struct xfs_mount *mp = ip->i_mount; 1745 struct xfs_mount *mp = ip->i_mount;
1662 struct xfs_dquot *uq, *gq; 1746 struct xfs_dquot *uq = NULL;
1747 struct xfs_dquot *gq = NULL;
1748 struct xfs_dquot *pq = NULL;
1663 int error; 1749 int error;
1664 uint lockflags; 1750 uint lockflags;
1665 1751
@@ -1684,7 +1770,6 @@ xfs_qm_vop_dqalloc(
1684 } 1770 }
1685 } 1771 }
1686 1772
1687 uq = gq = NULL;
1688 if ((flags & XFS_QMOPT_UQUOTA) && XFS_IS_UQUOTA_ON(mp)) { 1773 if ((flags & XFS_QMOPT_UQUOTA) && XFS_IS_UQUOTA_ON(mp)) {
1689 if (ip->i_d.di_uid != uid) { 1774 if (ip->i_d.di_uid != uid) {
1690 /* 1775 /*
@@ -1697,11 +1782,12 @@ xfs_qm_vop_dqalloc(
1697 * holding ilock. 1782 * holding ilock.
1698 */ 1783 */
1699 xfs_iunlock(ip, lockflags); 1784 xfs_iunlock(ip, lockflags);
1700 if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t) uid, 1785 error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t) uid,
1701 XFS_DQ_USER, 1786 XFS_DQ_USER,
1702 XFS_QMOPT_DQALLOC | 1787 XFS_QMOPT_DQALLOC |
1703 XFS_QMOPT_DOWARN, 1788 XFS_QMOPT_DOWARN,
1704 &uq))) { 1789 &uq);
1790 if (error) {
1705 ASSERT(error != ENOENT); 1791 ASSERT(error != ENOENT);
1706 return error; 1792 return error;
1707 } 1793 }
@@ -1723,15 +1809,14 @@ xfs_qm_vop_dqalloc(
1723 if ((flags & XFS_QMOPT_GQUOTA) && XFS_IS_GQUOTA_ON(mp)) { 1809 if ((flags & XFS_QMOPT_GQUOTA) && XFS_IS_GQUOTA_ON(mp)) {
1724 if (ip->i_d.di_gid != gid) { 1810 if (ip->i_d.di_gid != gid) {
1725 xfs_iunlock(ip, lockflags); 1811 xfs_iunlock(ip, lockflags);
1726 if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid, 1812 error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid,
1727 XFS_DQ_GROUP, 1813 XFS_DQ_GROUP,
1728 XFS_QMOPT_DQALLOC | 1814 XFS_QMOPT_DQALLOC |
1729 XFS_QMOPT_DOWARN, 1815 XFS_QMOPT_DOWARN,
1730 &gq))) { 1816 &gq);
1731 if (uq) 1817 if (error) {
1732 xfs_qm_dqrele(uq);
1733 ASSERT(error != ENOENT); 1818 ASSERT(error != ENOENT);
1734 return error; 1819 goto error_rele;
1735 } 1820 }
1736 xfs_dqunlock(gq); 1821 xfs_dqunlock(gq);
1737 lockflags = XFS_ILOCK_SHARED; 1822 lockflags = XFS_ILOCK_SHARED;
@@ -1740,25 +1825,25 @@ xfs_qm_vop_dqalloc(
1740 ASSERT(ip->i_gdquot); 1825 ASSERT(ip->i_gdquot);
1741 gq = xfs_qm_dqhold(ip->i_gdquot); 1826 gq = xfs_qm_dqhold(ip->i_gdquot);
1742 } 1827 }
1743 } else if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) { 1828 }
1829 if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) {
1744 if (xfs_get_projid(ip) != prid) { 1830 if (xfs_get_projid(ip) != prid) {
1745 xfs_iunlock(ip, lockflags); 1831 xfs_iunlock(ip, lockflags);
1746 if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid, 1832 error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid,
1747 XFS_DQ_PROJ, 1833 XFS_DQ_PROJ,
1748 XFS_QMOPT_DQALLOC | 1834 XFS_QMOPT_DQALLOC |
1749 XFS_QMOPT_DOWARN, 1835 XFS_QMOPT_DOWARN,
1750 &gq))) { 1836 &pq);
1751 if (uq) 1837 if (error) {
1752 xfs_qm_dqrele(uq);
1753 ASSERT(error != ENOENT); 1838 ASSERT(error != ENOENT);
1754 return (error); 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,7 +1858,18 @@ 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;
1866
1867error_rele:
1868 if (gq)
1869 xfs_qm_dqrele(gq);
1870 if (uq)
1871 xfs_qm_dqrele(uq);
1872 return error;
1777} 1873}
1778 1874
1779/* 1875/*
@@ -1821,29 +1917,34 @@ xfs_qm_vop_chown(
1821 */ 1917 */
1822int 1918int
1823xfs_qm_vop_chown_reserve( 1919xfs_qm_vop_chown_reserve(
1824 xfs_trans_t *tp, 1920 struct xfs_trans *tp,
1825 xfs_inode_t *ip, 1921 struct xfs_inode *ip,
1826 xfs_dquot_t *udqp, 1922 struct xfs_dquot *udqp,
1827 xfs_dquot_t *gdqp, 1923 struct xfs_dquot *gdqp,
1828 uint flags) 1924 struct xfs_dquot *pdqp,
1925 uint flags)
1829{ 1926{
1830 xfs_mount_t *mp = ip->i_mount; 1927 struct xfs_mount *mp = ip->i_mount;
1831 uint delblks, blkflags, prjflags = 0; 1928 uint delblks, blkflags, prjflags = 0;
1832 xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq; 1929 struct xfs_dquot *udq_unres = NULL;
1833 int error; 1930 struct xfs_dquot *gdq_unres = NULL;
1931 struct xfs_dquot *pdq_unres = NULL;
1932 struct xfs_dquot *udq_delblks = NULL;
1933 struct xfs_dquot *gdq_delblks = NULL;
1934 struct xfs_dquot *pdq_delblks = NULL;
1935 int error;
1834 1936
1835 1937
1836 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); 1938 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
1837 ASSERT(XFS_IS_QUOTA_RUNNING(mp)); 1939 ASSERT(XFS_IS_QUOTA_RUNNING(mp));
1838 1940
1839 delblks = ip->i_delayed_blks; 1941 delblks = ip->i_delayed_blks;
1840 delblksudq = delblksgdq = unresudq = unresgdq = NULL;
1841 blkflags = XFS_IS_REALTIME_INODE(ip) ? 1942 blkflags = XFS_IS_REALTIME_INODE(ip) ?
1842 XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS; 1943 XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS;
1843 1944
1844 if (XFS_IS_UQUOTA_ON(mp) && udqp && 1945 if (XFS_IS_UQUOTA_ON(mp) && udqp &&
1845 ip->i_d.di_uid != (uid_t)be32_to_cpu(udqp->q_core.d_id)) { 1946 ip->i_d.di_uid != (uid_t)be32_to_cpu(udqp->q_core.d_id)) {
1846 delblksudq = udqp; 1947 udq_delblks = udqp;
1847 /* 1948 /*
1848 * If there are delayed allocation blocks, then we have to 1949 * If there are delayed allocation blocks, then we have to
1849 * unreserve those from the old dquot, and add them to the 1950 * unreserve those from the old dquot, and add them to the
@@ -1851,29 +1952,34 @@ xfs_qm_vop_chown_reserve(
1851 */ 1952 */
1852 if (delblks) { 1953 if (delblks) {
1853 ASSERT(ip->i_udquot); 1954 ASSERT(ip->i_udquot);
1854 unresudq = ip->i_udquot; 1955 udq_unres = ip->i_udquot;
1855 } 1956 }
1856 } 1957 }
1857 if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) { 1958 if (XFS_IS_GQUOTA_ON(ip->i_mount) && gdqp &&
1858 if (XFS_IS_PQUOTA_ON(ip->i_mount) && 1959 ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id)) {
1859 xfs_get_projid(ip) != be32_to_cpu(gdqp->q_core.d_id)) 1960 gdq_delblks = gdqp;
1860 prjflags = XFS_QMOPT_ENOSPC; 1961 if (delblks) {
1861 1962 ASSERT(ip->i_gdquot);
1862 if (prjflags || 1963 gdq_unres = ip->i_gdquot;
1863 (XFS_IS_GQUOTA_ON(ip->i_mount) &&
1864 ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id))) {
1865 delblksgdq = gdqp;
1866 if (delblks) {
1867 ASSERT(ip->i_gdquot);
1868 unresgdq = ip->i_gdquot;
1869 }
1870 } 1964 }
1871 } 1965 }
1872 1966
1873 if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount, 1967 if (XFS_IS_PQUOTA_ON(ip->i_mount) && pdqp &&
1874 delblksudq, delblksgdq, ip->i_d.di_nblocks, 1, 1968 xfs_get_projid(ip) != be32_to_cpu(pdqp->q_core.d_id)) {
1875 flags | blkflags | prjflags))) 1969 prjflags = XFS_QMOPT_ENOSPC;
1876 return (error); 1970 pdq_delblks = pdqp;
1971 if (delblks) {
1972 ASSERT(ip->i_pdquot);
1973 pdq_unres = ip->i_pdquot;
1974 }
1975 }
1976
1977 error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount,
1978 udq_delblks, gdq_delblks, pdq_delblks,
1979 ip->i_d.di_nblocks, 1,
1980 flags | blkflags | prjflags);
1981 if (error)
1982 return error;
1877 1983
1878 /* 1984 /*
1879 * Do the delayed blks reservations/unreservations now. Since, these 1985 * Do the delayed blks reservations/unreservations now. Since, these
@@ -1885,15 +1991,17 @@ xfs_qm_vop_chown_reserve(
1885 /* 1991 /*
1886 * Do the reservations first. Unreservation can't fail. 1992 * Do the reservations first. Unreservation can't fail.
1887 */ 1993 */
1888 ASSERT(delblksudq || delblksgdq); 1994 ASSERT(udq_delblks || gdq_delblks || pdq_delblks);
1889 ASSERT(unresudq || unresgdq); 1995 ASSERT(udq_unres || gdq_unres || pdq_unres);
1890 if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, 1996 error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
1891 delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0, 1997 udq_delblks, gdq_delblks, pdq_delblks,
1892 flags | blkflags | prjflags))) 1998 (xfs_qcnt_t)delblks, 0,
1893 return (error); 1999 flags | blkflags | prjflags);
2000 if (error)
2001 return error;
1894 xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, 2002 xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
1895 unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0, 2003 udq_unres, gdq_unres, pdq_unres,
1896 blkflags); 2004 -((xfs_qcnt_t)delblks), 0, blkflags);
1897 } 2005 }
1898 2006
1899 return (0); 2007 return (0);
@@ -1932,7 +2040,8 @@ xfs_qm_vop_create_dqattach(
1932 struct xfs_trans *tp, 2040 struct xfs_trans *tp,
1933 struct xfs_inode *ip, 2041 struct xfs_inode *ip,
1934 struct xfs_dquot *udqp, 2042 struct xfs_dquot *udqp,
1935 struct xfs_dquot *gdqp) 2043 struct xfs_dquot *gdqp,
2044 struct xfs_dquot *pdqp)
1936{ 2045{
1937 struct xfs_mount *mp = tp->t_mountp; 2046 struct xfs_mount *mp = tp->t_mountp;
1938 2047
@@ -1952,13 +2061,18 @@ xfs_qm_vop_create_dqattach(
1952 } 2061 }
1953 if (gdqp) { 2062 if (gdqp) {
1954 ASSERT(ip->i_gdquot == NULL); 2063 ASSERT(ip->i_gdquot == NULL);
1955 ASSERT(XFS_IS_OQUOTA_ON(mp)); 2064 ASSERT(XFS_IS_GQUOTA_ON(mp));
1956 ASSERT((XFS_IS_GQUOTA_ON(mp) ? 2065 ASSERT(ip->i_d.di_gid == be32_to_cpu(gdqp->q_core.d_id));
1957 ip->i_d.di_gid : xfs_get_projid(ip)) ==
1958 be32_to_cpu(gdqp->q_core.d_id));
1959
1960 ip->i_gdquot = xfs_qm_dqhold(gdqp); 2066 ip->i_gdquot = xfs_qm_dqhold(gdqp);
1961 xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1); 2067 xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1);
1962 } 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 }
1963} 2077}
1964 2078