aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/quota/xfs_qm.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/quota/xfs_qm.c')
-rw-r--r--fs/xfs/quota/xfs_qm.c202
1 files changed, 130 insertions, 72 deletions
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 89f2cd656ebf..f665ca8f9e96 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -81,12 +81,18 @@ struct xfs_qm *xfs_Gqm;
81 81
82kmem_zone_t *qm_dqzone; 82kmem_zone_t *qm_dqzone;
83kmem_zone_t *qm_dqtrxzone; 83kmem_zone_t *qm_dqtrxzone;
84kmem_shaker_t xfs_qm_shaker; 84STATIC kmem_shaker_t xfs_qm_shaker;
85 85
86STATIC void xfs_qm_list_init(xfs_dqlist_t *, char *, int); 86STATIC void xfs_qm_list_init(xfs_dqlist_t *, char *, int);
87STATIC void xfs_qm_list_destroy(xfs_dqlist_t *); 87STATIC void xfs_qm_list_destroy(xfs_dqlist_t *);
88 88
89STATIC void xfs_qm_freelist_init(xfs_frlist_t *);
90STATIC void xfs_qm_freelist_destroy(xfs_frlist_t *);
91STATIC int xfs_qm_mplist_nowait(xfs_mount_t *);
92STATIC int xfs_qm_dqhashlock_nowait(xfs_dquot_t *);
93
89STATIC int xfs_qm_init_quotainos(xfs_mount_t *); 94STATIC int xfs_qm_init_quotainos(xfs_mount_t *);
95STATIC int xfs_qm_init_quotainfo(xfs_mount_t *);
90STATIC int xfs_qm_shake(int, unsigned int); 96STATIC int xfs_qm_shake(int, unsigned int);
91 97
92#ifdef DEBUG 98#ifdef DEBUG
@@ -184,7 +190,7 @@ xfs_Gqm_init(void)
184/* 190/*
185 * Destroy the global quota manager when its reference count goes to zero. 191 * Destroy the global quota manager when its reference count goes to zero.
186 */ 192 */
187void 193STATIC void
188xfs_qm_destroy( 194xfs_qm_destroy(
189 struct xfs_qm *xqm) 195 struct xfs_qm *xqm)
190{ 196{
@@ -304,9 +310,9 @@ xfs_qm_mount_quotainit(
304 uint flags) 310 uint flags)
305{ 311{
306 /* 312 /*
307 * User or group quotas has to be on. 313 * User, projects or group quotas has to be on.
308 */ 314 */
309 ASSERT(flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA)); 315 ASSERT(flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA));
310 316
311 /* 317 /*
312 * Initialize the flags in the mount structure. From this point 318 * Initialize the flags in the mount structure. From this point
@@ -324,7 +330,11 @@ xfs_qm_mount_quotainit(
324 if (flags & XFSMNT_GQUOTA) { 330 if (flags & XFSMNT_GQUOTA) {
325 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); 331 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
326 if (flags & XFSMNT_GQUOTAENF) 332 if (flags & XFSMNT_GQUOTAENF)
327 mp->m_qflags |= XFS_GQUOTA_ENFD; 333 mp->m_qflags |= XFS_OQUOTA_ENFD;
334 } else if (flags & XFSMNT_PQUOTA) {
335 mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
336 if (flags & XFSMNT_PQUOTAENF)
337 mp->m_qflags |= XFS_OQUOTA_ENFD;
328 } 338 }
329} 339}
330 340
@@ -357,11 +367,11 @@ xfs_qm_mount_quotas(
357 367
358 /* 368 /*
359 * If a file system had quotas running earlier, but decided to 369 * If a file system had quotas running earlier, but decided to
360 * mount without -o quota/uquota/gquota options, revoke the 370 * mount without -o uquota/pquota/gquota options, revoke the
361 * quotachecked license, and bail out. 371 * quotachecked license, and bail out.
362 */ 372 */
363 if (! XFS_IS_QUOTA_ON(mp) && 373 if (! XFS_IS_QUOTA_ON(mp) &&
364 (mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT))) { 374 (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT)) {
365 mp->m_qflags = 0; 375 mp->m_qflags = 0;
366 goto write_changes; 376 goto write_changes;
367 } 377 }
@@ -509,7 +519,7 @@ out:
509 * Flush all dquots of the given file system to disk. The dquots are 519 * Flush all dquots of the given file system to disk. The dquots are
510 * _not_ purged from memory here, just their data written to disk. 520 * _not_ purged from memory here, just their data written to disk.
511 */ 521 */
512int 522STATIC int
513xfs_qm_dqflush_all( 523xfs_qm_dqflush_all(
514 xfs_mount_t *mp, 524 xfs_mount_t *mp,
515 int flags) 525 int flags)
@@ -613,7 +623,7 @@ xfs_qm_detach_gdquots(
613STATIC int 623STATIC int
614xfs_qm_dqpurge_int( 624xfs_qm_dqpurge_int(
615 xfs_mount_t *mp, 625 xfs_mount_t *mp,
616 uint flags) /* QUOTAOFF/UMOUNTING/UQUOTA/GQUOTA */ 626 uint flags) /* QUOTAOFF/UMOUNTING/UQUOTA/PQUOTA/GQUOTA */
617{ 627{
618 xfs_dquot_t *dqp; 628 xfs_dquot_t *dqp;
619 uint dqtype; 629 uint dqtype;
@@ -625,6 +635,7 @@ xfs_qm_dqpurge_int(
625 return (0); 635 return (0);
626 636
627 dqtype = (flags & XFS_QMOPT_UQUOTA) ? XFS_DQ_USER : 0; 637 dqtype = (flags & XFS_QMOPT_UQUOTA) ? XFS_DQ_USER : 0;
638 dqtype |= (flags & XFS_QMOPT_PQUOTA) ? XFS_DQ_PROJ : 0;
628 dqtype |= (flags & XFS_QMOPT_GQUOTA) ? XFS_DQ_GROUP : 0; 639 dqtype |= (flags & XFS_QMOPT_GQUOTA) ? XFS_DQ_GROUP : 0;
629 640
630 xfs_qm_mplist_lock(mp); 641 xfs_qm_mplist_lock(mp);
@@ -734,11 +745,11 @@ xfs_qm_dqattach_one(
734 745
735 /* 746 /*
736 * udqhint is the i_udquot field in inode, and is non-NULL only 747 * udqhint is the i_udquot field in inode, and is non-NULL only
737 * when the type arg is XFS_DQ_GROUP. Its purpose is to save a 748 * when the type arg is group/project. Its purpose is to save a
738 * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside 749 * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside
739 * the user dquot. 750 * the user dquot.
740 */ 751 */
741 ASSERT(!udqhint || type == XFS_DQ_GROUP); 752 ASSERT(!udqhint || type == XFS_DQ_GROUP || type == XFS_DQ_PROJ);
742 if (udqhint && !dolock) 753 if (udqhint && !dolock)
743 xfs_dqlock(udqhint); 754 xfs_dqlock(udqhint);
744 755
@@ -897,8 +908,8 @@ xfs_qm_dqattach_grouphint(
897 908
898 909
899/* 910/*
900 * Given a locked inode, attach dquot(s) to it, taking UQUOTAON / GQUOTAON 911 * Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON
901 * in to account. 912 * into account.
902 * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed. 913 * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed.
903 * If XFS_QMOPT_DQLOCK, the dquot(s) will be returned locked. This option pretty 914 * If XFS_QMOPT_DQLOCK, the dquot(s) will be returned locked. This option pretty
904 * much made this code a complete mess, but it has been pretty useful. 915 * much made this code a complete mess, but it has been pretty useful.
@@ -937,8 +948,13 @@ xfs_qm_dqattach(
937 nquotas++; 948 nquotas++;
938 } 949 }
939 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); 950 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
940 if (XFS_IS_GQUOTA_ON(mp)) { 951 if (XFS_IS_OQUOTA_ON(mp)) {
941 error = xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP, 952 error = XFS_IS_GQUOTA_ON(mp) ?
953 xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
954 flags & XFS_QMOPT_DQALLOC,
955 flags & XFS_QMOPT_DQLOCK,
956 ip->i_udquot, &ip->i_gdquot) :
957 xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ,
942 flags & XFS_QMOPT_DQALLOC, 958 flags & XFS_QMOPT_DQALLOC,
943 flags & XFS_QMOPT_DQLOCK, 959 flags & XFS_QMOPT_DQLOCK,
944 ip->i_udquot, &ip->i_gdquot); 960 ip->i_udquot, &ip->i_gdquot);
@@ -989,7 +1005,7 @@ xfs_qm_dqattach(
989 } 1005 }
990 if (XFS_IS_UQUOTA_ON(mp)) 1006 if (XFS_IS_UQUOTA_ON(mp))
991 ASSERT(ip->i_udquot); 1007 ASSERT(ip->i_udquot);
992 if (XFS_IS_GQUOTA_ON(mp)) 1008 if (XFS_IS_OQUOTA_ON(mp))
993 ASSERT(ip->i_gdquot); 1009 ASSERT(ip->i_gdquot);
994 } 1010 }
995#endif 1011#endif
@@ -1018,13 +1034,13 @@ xfs_qm_dqdetach(
1018 1034
1019 ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_uquotino); 1035 ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_uquotino);
1020 ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_gquotino); 1036 ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_gquotino);
1021 if (ip->i_udquot)
1022 xfs_dqtrace_entry_ino(ip->i_udquot, "DQDETTACH", ip);
1023 if (ip->i_udquot) { 1037 if (ip->i_udquot) {
1038 xfs_dqtrace_entry_ino(ip->i_udquot, "DQDETTACH", ip);
1024 xfs_qm_dqrele(ip->i_udquot); 1039 xfs_qm_dqrele(ip->i_udquot);
1025 ip->i_udquot = NULL; 1040 ip->i_udquot = NULL;
1026 } 1041 }
1027 if (ip->i_gdquot) { 1042 if (ip->i_gdquot) {
1043 xfs_dqtrace_entry_ino(ip->i_gdquot, "DQDETTACH", ip);
1028 xfs_qm_dqrele(ip->i_gdquot); 1044 xfs_qm_dqrele(ip->i_gdquot);
1029 ip->i_gdquot = NULL; 1045 ip->i_gdquot = NULL;
1030 } 1046 }
@@ -1149,7 +1165,7 @@ xfs_qm_sync(
1149 * This initializes all the quota information that's kept in the 1165 * This initializes all the quota information that's kept in the
1150 * mount structure 1166 * mount structure
1151 */ 1167 */
1152int 1168STATIC int
1153xfs_qm_init_quotainfo( 1169xfs_qm_init_quotainfo(
1154 xfs_mount_t *mp) 1170 xfs_mount_t *mp)
1155{ 1171{
@@ -1202,8 +1218,9 @@ xfs_qm_init_quotainfo(
1202 * and group quotas, at least not at this point. 1218 * and group quotas, at least not at this point.
1203 */ 1219 */
1204 error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)0, 1220 error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)0,
1205 (XFS_IS_UQUOTA_RUNNING(mp)) ? 1221 XFS_IS_UQUOTA_RUNNING(mp) ? XFS_DQ_USER :
1206 XFS_DQ_USER : XFS_DQ_GROUP, 1222 (XFS_IS_GQUOTA_RUNNING(mp) ? XFS_DQ_GROUP :
1223 XFS_DQ_PROJ),
1207 XFS_QMOPT_DQSUSER|XFS_QMOPT_DOWARN, 1224 XFS_QMOPT_DQSUSER|XFS_QMOPT_DOWARN,
1208 &dqp); 1225 &dqp);
1209 if (! error) { 1226 if (! error) {
@@ -1234,6 +1251,10 @@ xfs_qm_init_quotainfo(
1234 INT_GET(ddqp->d_iwarns, ARCH_CONVERT) ? 1251 INT_GET(ddqp->d_iwarns, ARCH_CONVERT) ?
1235 INT_GET(ddqp->d_iwarns, ARCH_CONVERT) : 1252 INT_GET(ddqp->d_iwarns, ARCH_CONVERT) :
1236 XFS_QM_IWARNLIMIT; 1253 XFS_QM_IWARNLIMIT;
1254 qinf->qi_rtbwarnlimit =
1255 INT_GET(ddqp->d_rtbwarns, ARCH_CONVERT) ?
1256 INT_GET(ddqp->d_rtbwarns, ARCH_CONVERT) :
1257 XFS_QM_RTBWARNLIMIT;
1237 qinf->qi_bhardlimit = 1258 qinf->qi_bhardlimit =
1238 INT_GET(ddqp->d_blk_hardlimit, ARCH_CONVERT); 1259 INT_GET(ddqp->d_blk_hardlimit, ARCH_CONVERT);
1239 qinf->qi_bsoftlimit = 1260 qinf->qi_bsoftlimit =
@@ -1259,6 +1280,7 @@ xfs_qm_init_quotainfo(
1259 qinf->qi_rtbtimelimit = XFS_QM_RTBTIMELIMIT; 1280 qinf->qi_rtbtimelimit = XFS_QM_RTBTIMELIMIT;
1260 qinf->qi_bwarnlimit = XFS_QM_BWARNLIMIT; 1281 qinf->qi_bwarnlimit = XFS_QM_BWARNLIMIT;
1261 qinf->qi_iwarnlimit = XFS_QM_IWARNLIMIT; 1282 qinf->qi_iwarnlimit = XFS_QM_IWARNLIMIT;
1283 qinf->qi_rtbwarnlimit = XFS_QM_RTBWARNLIMIT;
1262 } 1284 }
1263 1285
1264 return (0); 1286 return (0);
@@ -1366,13 +1388,20 @@ xfs_qm_dqget_noattach(
1366 ASSERT(udqp); 1388 ASSERT(udqp);
1367 } 1389 }
1368 1390
1369 if (XFS_IS_GQUOTA_ON(mp)) { 1391 if (XFS_IS_OQUOTA_ON(mp)) {
1370 ASSERT(ip->i_gdquot == NULL); 1392 ASSERT(ip->i_gdquot == NULL);
1371 if (udqp) 1393 if (udqp)
1372 xfs_dqunlock(udqp); 1394 xfs_dqunlock(udqp);
1373 if ((error = xfs_qm_dqget(mp, ip, ip->i_d.di_gid, XFS_DQ_GROUP, 1395 error = XFS_IS_GQUOTA_ON(mp) ?
1374 XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN, 1396 xfs_qm_dqget(mp, ip,
1375 &gdqp))) { 1397 ip->i_d.di_gid, XFS_DQ_GROUP,
1398 XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN,
1399 &gdqp) :
1400 xfs_qm_dqget(mp, ip,
1401 ip->i_d.di_projid, XFS_DQ_PROJ,
1402 XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN,
1403 &gdqp);
1404 if (error) {
1376 if (udqp) 1405 if (udqp)
1377 xfs_qm_dqrele(udqp); 1406 xfs_qm_dqrele(udqp);
1378 ASSERT(error != ESRCH); 1407 ASSERT(error != ESRCH);
@@ -1521,8 +1550,10 @@ xfs_qm_reset_dqcounts(
1521 INT_SET(ddq->d_rtbcount, ARCH_CONVERT, 0ULL); 1550 INT_SET(ddq->d_rtbcount, ARCH_CONVERT, 0ULL);
1522 INT_SET(ddq->d_btimer, ARCH_CONVERT, (time_t)0); 1551 INT_SET(ddq->d_btimer, ARCH_CONVERT, (time_t)0);
1523 INT_SET(ddq->d_itimer, ARCH_CONVERT, (time_t)0); 1552 INT_SET(ddq->d_itimer, ARCH_CONVERT, (time_t)0);
1553 INT_SET(ddq->d_rtbtimer, ARCH_CONVERT, (time_t)0);
1524 INT_SET(ddq->d_bwarns, ARCH_CONVERT, 0UL); 1554 INT_SET(ddq->d_bwarns, ARCH_CONVERT, 0UL);
1525 INT_SET(ddq->d_iwarns, ARCH_CONVERT, 0UL); 1555 INT_SET(ddq->d_iwarns, ARCH_CONVERT, 0UL);
1556 INT_SET(ddq->d_rtbwarns, ARCH_CONVERT, 0UL);
1526 ddq = (xfs_disk_dquot_t *) ((xfs_dqblk_t *)ddq + 1); 1557 ddq = (xfs_disk_dquot_t *) ((xfs_dqblk_t *)ddq + 1);
1527 } 1558 }
1528 1559
@@ -1541,11 +1572,14 @@ xfs_qm_dqiter_bufs(
1541 int error; 1572 int error;
1542 int notcommitted; 1573 int notcommitted;
1543 int incr; 1574 int incr;
1575 int type;
1544 1576
1545 ASSERT(blkcnt > 0); 1577 ASSERT(blkcnt > 0);
1546 notcommitted = 0; 1578 notcommitted = 0;
1547 incr = (blkcnt > XFS_QM_MAX_DQCLUSTER_LOGSZ) ? 1579 incr = (blkcnt > XFS_QM_MAX_DQCLUSTER_LOGSZ) ?
1548 XFS_QM_MAX_DQCLUSTER_LOGSZ : blkcnt; 1580 XFS_QM_MAX_DQCLUSTER_LOGSZ : blkcnt;
1581 type = flags & XFS_QMOPT_UQUOTA ? XFS_DQ_USER :
1582 (flags & XFS_QMOPT_PQUOTA ? XFS_DQ_PROJ : XFS_DQ_GROUP);
1549 error = 0; 1583 error = 0;
1550 1584
1551 /* 1585 /*
@@ -1564,9 +1598,7 @@ xfs_qm_dqiter_bufs(
1564 if (error) 1598 if (error)
1565 break; 1599 break;
1566 1600
1567 (void) xfs_qm_reset_dqcounts(mp, bp, firstid, 1601 (void) xfs_qm_reset_dqcounts(mp, bp, firstid, type);
1568 flags & XFS_QMOPT_UQUOTA ?
1569 XFS_DQ_USER : XFS_DQ_GROUP);
1570 xfs_bdwrite(mp, bp); 1602 xfs_bdwrite(mp, bp);
1571 /* 1603 /*
1572 * goto the next block. 1604 * goto the next block.
@@ -1578,7 +1610,7 @@ xfs_qm_dqiter_bufs(
1578} 1610}
1579 1611
1580/* 1612/*
1581 * Iterate over all allocated USR/GRP dquots in the system, calling a 1613 * Iterate over all allocated USR/GRP/PRJ dquots in the system, calling a
1582 * caller supplied function for every chunk of dquots that we find. 1614 * caller supplied function for every chunk of dquots that we find.
1583 */ 1615 */
1584STATIC int 1616STATIC int
@@ -1849,7 +1881,7 @@ xfs_qm_dqusage_adjust(
1849 xfs_qm_quotacheck_dqadjust(udqp, nblks, rtblks); 1881 xfs_qm_quotacheck_dqadjust(udqp, nblks, rtblks);
1850 xfs_qm_dqput(udqp); 1882 xfs_qm_dqput(udqp);
1851 } 1883 }
1852 if (XFS_IS_GQUOTA_ON(mp)) { 1884 if (XFS_IS_OQUOTA_ON(mp)) {
1853 ASSERT(gdqp); 1885 ASSERT(gdqp);
1854 xfs_qm_quotacheck_dqadjust(gdqp, nblks, rtblks); 1886 xfs_qm_quotacheck_dqadjust(gdqp, nblks, rtblks);
1855 xfs_qm_dqput(gdqp); 1887 xfs_qm_dqput(gdqp);
@@ -1898,7 +1930,7 @@ xfs_qm_quotacheck(
1898 cmn_err(CE_NOTE, "XFS quotacheck %s: Please wait.", mp->m_fsname); 1930 cmn_err(CE_NOTE, "XFS quotacheck %s: Please wait.", mp->m_fsname);
1899 1931
1900 /* 1932 /*
1901 * First we go thru all the dquots on disk, USR and GRP, and reset 1933 * First we go thru all the dquots on disk, USR and GRP/PRJ, and reset
1902 * their counters to zero. We need a clean slate. 1934 * their counters to zero. We need a clean slate.
1903 * We don't log our changes till later. 1935 * We don't log our changes till later.
1904 */ 1936 */
@@ -1909,9 +1941,10 @@ xfs_qm_quotacheck(
1909 } 1941 }
1910 1942
1911 if ((gip = XFS_QI_GQIP(mp))) { 1943 if ((gip = XFS_QI_GQIP(mp))) {
1912 if ((error = xfs_qm_dqiterate(mp, gip, XFS_QMOPT_GQUOTA))) 1944 if ((error = xfs_qm_dqiterate(mp, gip, XFS_IS_GQUOTA_ON(mp) ?
1945 XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA)))
1913 goto error_return; 1946 goto error_return;
1914 flags |= XFS_GQUOTA_CHKD; 1947 flags |= XFS_OQUOTA_CHKD;
1915 } 1948 }
1916 1949
1917 do { 1950 do {
@@ -1938,7 +1971,7 @@ xfs_qm_quotacheck(
1938 if (error) { 1971 if (error) {
1939 xfs_qm_dqpurge_all(mp, 1972 xfs_qm_dqpurge_all(mp,
1940 XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA| 1973 XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA|
1941 XFS_QMOPT_QUOTAOFF); 1974 XFS_QMOPT_PQUOTA|XFS_QMOPT_QUOTAOFF);
1942 goto error_return; 1975 goto error_return;
1943 } 1976 }
1944 /* 1977 /*
@@ -1961,7 +1994,7 @@ xfs_qm_quotacheck(
1961 * quotachecked status, since we won't be doing accounting for 1994 * quotachecked status, since we won't be doing accounting for
1962 * that type anymore. 1995 * that type anymore.
1963 */ 1996 */
1964 mp->m_qflags &= ~(XFS_GQUOTA_CHKD | XFS_UQUOTA_CHKD); 1997 mp->m_qflags &= ~(XFS_OQUOTA_CHKD | XFS_UQUOTA_CHKD);
1965 mp->m_qflags |= flags; 1998 mp->m_qflags |= flags;
1966 1999
1967 XQM_LIST_PRINT(&(XFS_QI_MPL_LIST(mp)), MPL_NEXT, "++++ Mp list +++"); 2000 XQM_LIST_PRINT(&(XFS_QI_MPL_LIST(mp)), MPL_NEXT, "++++ Mp list +++");
@@ -2013,7 +2046,7 @@ xfs_qm_init_quotainos(
2013 0, 0, &uip, 0))) 2046 0, 0, &uip, 0)))
2014 return XFS_ERROR(error); 2047 return XFS_ERROR(error);
2015 } 2048 }
2016 if (XFS_IS_GQUOTA_ON(mp) && 2049 if (XFS_IS_OQUOTA_ON(mp) &&
2017 mp->m_sb.sb_gquotino != NULLFSINO) { 2050 mp->m_sb.sb_gquotino != NULLFSINO) {
2018 ASSERT(mp->m_sb.sb_gquotino > 0); 2051 ASSERT(mp->m_sb.sb_gquotino > 0);
2019 if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 2052 if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
@@ -2043,10 +2076,12 @@ xfs_qm_init_quotainos(
2043 2076
2044 flags &= ~XFS_QMOPT_SBVERSION; 2077 flags &= ~XFS_QMOPT_SBVERSION;
2045 } 2078 }
2046 if (XFS_IS_GQUOTA_ON(mp) && gip == NULL) { 2079 if (XFS_IS_OQUOTA_ON(mp) && gip == NULL) {
2047 if ((error = xfs_qm_qino_alloc(mp, &gip, 2080 flags |= (XFS_IS_GQUOTA_ON(mp) ?
2048 sbflags | XFS_SB_GQUOTINO, 2081 XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA);
2049 flags | XFS_QMOPT_GQUOTA))) { 2082 error = xfs_qm_qino_alloc(mp, &gip,
2083 sbflags | XFS_SB_GQUOTINO, flags);
2084 if (error) {
2050 if (uip) 2085 if (uip)
2051 VN_RELE(XFS_ITOV(uip)); 2086 VN_RELE(XFS_ITOV(uip));
2052 2087
@@ -2452,6 +2487,7 @@ xfs_qm_vop_dqalloc(
2452 xfs_inode_t *ip, 2487 xfs_inode_t *ip,
2453 uid_t uid, 2488 uid_t uid,
2454 gid_t gid, 2489 gid_t gid,
2490 prid_t prid,
2455 uint flags, 2491 uint flags,
2456 xfs_dquot_t **O_udqpp, 2492 xfs_dquot_t **O_udqpp,
2457 xfs_dquot_t **O_gdqpp) 2493 xfs_dquot_t **O_gdqpp)
@@ -2483,8 +2519,7 @@ xfs_qm_vop_dqalloc(
2483 } 2519 }
2484 2520
2485 uq = gq = NULL; 2521 uq = gq = NULL;
2486 if ((flags & XFS_QMOPT_UQUOTA) && 2522 if ((flags & XFS_QMOPT_UQUOTA) && XFS_IS_UQUOTA_ON(mp)) {
2487 XFS_IS_UQUOTA_ON(mp)) {
2488 if (ip->i_d.di_uid != uid) { 2523 if (ip->i_d.di_uid != uid) {
2489 /* 2524 /*
2490 * What we need is the dquot that has this uid, and 2525 * What we need is the dquot that has this uid, and
@@ -2522,8 +2557,7 @@ xfs_qm_vop_dqalloc(
2522 xfs_dqunlock(uq); 2557 xfs_dqunlock(uq);
2523 } 2558 }
2524 } 2559 }
2525 if ((flags & XFS_QMOPT_GQUOTA) && 2560 if ((flags & XFS_QMOPT_GQUOTA) && XFS_IS_GQUOTA_ON(mp)) {
2526 XFS_IS_GQUOTA_ON(mp)) {
2527 if (ip->i_d.di_gid != gid) { 2561 if (ip->i_d.di_gid != gid) {
2528 xfs_iunlock(ip, lockflags); 2562 xfs_iunlock(ip, lockflags);
2529 if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid, 2563 if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid,
@@ -2546,6 +2580,29 @@ xfs_qm_vop_dqalloc(
2546 XFS_DQHOLD(gq); 2580 XFS_DQHOLD(gq);
2547 xfs_dqunlock(gq); 2581 xfs_dqunlock(gq);
2548 } 2582 }
2583 } else if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) {
2584 if (ip->i_d.di_projid != prid) {
2585 xfs_iunlock(ip, lockflags);
2586 if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid,
2587 XFS_DQ_PROJ,
2588 XFS_QMOPT_DQALLOC |
2589 XFS_QMOPT_DOWARN,
2590 &gq))) {
2591 if (uq)
2592 xfs_qm_dqrele(uq);
2593 ASSERT(error != ENOENT);
2594 return (error);
2595 }
2596 xfs_dqunlock(gq);
2597 lockflags = XFS_ILOCK_SHARED;
2598 xfs_ilock(ip, lockflags);
2599 } else {
2600 ASSERT(ip->i_gdquot);
2601 gq = ip->i_gdquot;
2602 xfs_dqlock(gq);
2603 XFS_DQHOLD(gq);
2604 xfs_dqunlock(gq);
2605 }
2549 } 2606 }
2550 if (uq) 2607 if (uq)
2551 xfs_dqtrace_entry_ino(uq, "DQALLOC", ip); 2608 xfs_dqtrace_entry_ino(uq, "DQALLOC", ip);
@@ -2574,6 +2631,9 @@ xfs_qm_vop_chown(
2574 xfs_dquot_t *newdq) 2631 xfs_dquot_t *newdq)
2575{ 2632{
2576 xfs_dquot_t *prevdq; 2633 xfs_dquot_t *prevdq;
2634 uint bfield = XFS_IS_REALTIME_INODE(ip) ?
2635 XFS_TRANS_DQ_RTBCOUNT : XFS_TRANS_DQ_BCOUNT;
2636
2577 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); 2637 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
2578 ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount)); 2638 ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount));
2579 2639
@@ -2582,20 +2642,12 @@ xfs_qm_vop_chown(
2582 ASSERT(prevdq); 2642 ASSERT(prevdq);
2583 ASSERT(prevdq != newdq); 2643 ASSERT(prevdq != newdq);
2584 2644
2585 xfs_trans_mod_dquot(tp, prevdq, 2645 xfs_trans_mod_dquot(tp, prevdq, bfield, -(ip->i_d.di_nblocks));
2586 XFS_TRANS_DQ_BCOUNT, 2646 xfs_trans_mod_dquot(tp, prevdq, XFS_TRANS_DQ_ICOUNT, -1);
2587 -(ip->i_d.di_nblocks));
2588 xfs_trans_mod_dquot(tp, prevdq,
2589 XFS_TRANS_DQ_ICOUNT,
2590 -1);
2591 2647
2592 /* the sparkling new dquot */ 2648 /* the sparkling new dquot */
2593 xfs_trans_mod_dquot(tp, newdq, 2649 xfs_trans_mod_dquot(tp, newdq, bfield, ip->i_d.di_nblocks);
2594 XFS_TRANS_DQ_BCOUNT, 2650 xfs_trans_mod_dquot(tp, newdq, XFS_TRANS_DQ_ICOUNT, 1);
2595 ip->i_d.di_nblocks);
2596 xfs_trans_mod_dquot(tp, newdq,
2597 XFS_TRANS_DQ_ICOUNT,
2598 1);
2599 2651
2600 /* 2652 /*
2601 * Take an extra reference, because the inode 2653 * Take an extra reference, because the inode
@@ -2611,7 +2663,7 @@ xfs_qm_vop_chown(
2611} 2663}
2612 2664
2613/* 2665/*
2614 * Quota reservations for setattr(AT_UID|AT_GID). 2666 * Quota reservations for setattr(AT_UID|AT_GID|AT_PROJID).
2615 */ 2667 */
2616int 2668int
2617xfs_qm_vop_chown_reserve( 2669xfs_qm_vop_chown_reserve(
@@ -2623,7 +2675,7 @@ xfs_qm_vop_chown_reserve(
2623{ 2675{
2624 int error; 2676 int error;
2625 xfs_mount_t *mp; 2677 xfs_mount_t *mp;
2626 uint delblks; 2678 uint delblks, blkflags;
2627 xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq; 2679 xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq;
2628 2680
2629 ASSERT(XFS_ISLOCKED_INODE(ip)); 2681 ASSERT(XFS_ISLOCKED_INODE(ip));
@@ -2632,6 +2684,8 @@ xfs_qm_vop_chown_reserve(
2632 2684
2633 delblks = ip->i_delayed_blks; 2685 delblks = ip->i_delayed_blks;
2634 delblksudq = delblksgdq = unresudq = unresgdq = NULL; 2686 delblksudq = delblksgdq = unresudq = unresgdq = NULL;
2687 blkflags = XFS_IS_REALTIME_INODE(ip) ?
2688 XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS;
2635 2689
2636 if (XFS_IS_UQUOTA_ON(mp) && udqp && 2690 if (XFS_IS_UQUOTA_ON(mp) && udqp &&
2637 ip->i_d.di_uid != (uid_t)INT_GET(udqp->q_core.d_id, ARCH_CONVERT)) { 2691 ip->i_d.di_uid != (uid_t)INT_GET(udqp->q_core.d_id, ARCH_CONVERT)) {
@@ -2646,18 +2700,22 @@ xfs_qm_vop_chown_reserve(
2646 unresudq = ip->i_udquot; 2700 unresudq = ip->i_udquot;
2647 } 2701 }
2648 } 2702 }
2649 if (XFS_IS_GQUOTA_ON(ip->i_mount) && gdqp && 2703 if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) {
2650 ip->i_d.di_gid != INT_GET(gdqp->q_core.d_id, ARCH_CONVERT)) { 2704 if ((XFS_IS_GQUOTA_ON(ip->i_mount) && ip->i_d.di_gid !=
2651 delblksgdq = gdqp; 2705 INT_GET(gdqp->q_core.d_id, ARCH_CONVERT)) ||
2652 if (delblks) { 2706 (XFS_IS_PQUOTA_ON(ip->i_mount) && ip->i_d.di_projid !=
2653 ASSERT(ip->i_gdquot); 2707 INT_GET(gdqp->q_core.d_id, ARCH_CONVERT))) {
2654 unresgdq = ip->i_gdquot; 2708 delblksgdq = gdqp;
2709 if (delblks) {
2710 ASSERT(ip->i_gdquot);
2711 unresgdq = ip->i_gdquot;
2712 }
2655 } 2713 }
2656 } 2714 }
2657 2715
2658 if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount, 2716 if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount,
2659 delblksudq, delblksgdq, ip->i_d.di_nblocks, 1, 2717 delblksudq, delblksgdq, ip->i_d.di_nblocks, 1,
2660 flags | XFS_QMOPT_RES_REGBLKS))) 2718 flags | blkflags)))
2661 return (error); 2719 return (error);
2662 2720
2663 /* 2721 /*
@@ -2674,11 +2732,11 @@ xfs_qm_vop_chown_reserve(
2674 ASSERT(unresudq || unresgdq); 2732 ASSERT(unresudq || unresgdq);
2675 if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, 2733 if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
2676 delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0, 2734 delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0,
2677 flags | XFS_QMOPT_RES_REGBLKS))) 2735 flags | blkflags)))
2678 return (error); 2736 return (error);
2679 xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, 2737 xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
2680 unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0, 2738 unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0,
2681 XFS_QMOPT_RES_REGBLKS); 2739 blkflags);
2682 } 2740 }
2683 2741
2684 return (0); 2742 return (0);
@@ -2751,7 +2809,7 @@ xfs_qm_vop_dqattach_and_dqmod_newinode(
2751} 2809}
2752 2810
2753/* ------------- list stuff -----------------*/ 2811/* ------------- list stuff -----------------*/
2754void 2812STATIC void
2755xfs_qm_freelist_init(xfs_frlist_t *ql) 2813xfs_qm_freelist_init(xfs_frlist_t *ql)
2756{ 2814{
2757 ql->qh_next = ql->qh_prev = (xfs_dquot_t *) ql; 2815 ql->qh_next = ql->qh_prev = (xfs_dquot_t *) ql;
@@ -2760,7 +2818,7 @@ xfs_qm_freelist_init(xfs_frlist_t *ql)
2760 ql->qh_nelems = 0; 2818 ql->qh_nelems = 0;
2761} 2819}
2762 2820
2763void 2821STATIC void
2764xfs_qm_freelist_destroy(xfs_frlist_t *ql) 2822xfs_qm_freelist_destroy(xfs_frlist_t *ql)
2765{ 2823{
2766 xfs_dquot_t *dqp, *nextdqp; 2824 xfs_dquot_t *dqp, *nextdqp;
@@ -2786,7 +2844,7 @@ xfs_qm_freelist_destroy(xfs_frlist_t *ql)
2786 ASSERT(ql->qh_nelems == 0); 2844 ASSERT(ql->qh_nelems == 0);
2787} 2845}
2788 2846
2789void 2847STATIC void
2790xfs_qm_freelist_insert(xfs_frlist_t *ql, xfs_dquot_t *dq) 2848xfs_qm_freelist_insert(xfs_frlist_t *ql, xfs_dquot_t *dq)
2791{ 2849{
2792 dq->dq_flnext = ql->qh_next; 2850 dq->dq_flnext = ql->qh_next;
@@ -2816,7 +2874,7 @@ xfs_qm_freelist_append(xfs_frlist_t *ql, xfs_dquot_t *dq)
2816 xfs_qm_freelist_insert((xfs_frlist_t *)ql->qh_prev, dq); 2874 xfs_qm_freelist_insert((xfs_frlist_t *)ql->qh_prev, dq);
2817} 2875}
2818 2876
2819int 2877STATIC int
2820xfs_qm_dqhashlock_nowait( 2878xfs_qm_dqhashlock_nowait(
2821 xfs_dquot_t *dqp) 2879 xfs_dquot_t *dqp)
2822{ 2880{
@@ -2836,7 +2894,7 @@ xfs_qm_freelist_lock_nowait(
2836 return (locked); 2894 return (locked);
2837} 2895}
2838 2896
2839int 2897STATIC int
2840xfs_qm_mplist_nowait( 2898xfs_qm_mplist_nowait(
2841 xfs_mount_t *mp) 2899 xfs_mount_t *mp)
2842{ 2900{