diff options
Diffstat (limited to 'fs/xfs/quota/xfs_qm.c')
-rw-r--r-- | fs/xfs/quota/xfs_qm.c | 202 |
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 | ||
82 | kmem_zone_t *qm_dqzone; | 82 | kmem_zone_t *qm_dqzone; |
83 | kmem_zone_t *qm_dqtrxzone; | 83 | kmem_zone_t *qm_dqtrxzone; |
84 | kmem_shaker_t xfs_qm_shaker; | 84 | STATIC kmem_shaker_t xfs_qm_shaker; |
85 | 85 | ||
86 | STATIC void xfs_qm_list_init(xfs_dqlist_t *, char *, int); | 86 | STATIC void xfs_qm_list_init(xfs_dqlist_t *, char *, int); |
87 | STATIC void xfs_qm_list_destroy(xfs_dqlist_t *); | 87 | STATIC void xfs_qm_list_destroy(xfs_dqlist_t *); |
88 | 88 | ||
89 | STATIC void xfs_qm_freelist_init(xfs_frlist_t *); | ||
90 | STATIC void xfs_qm_freelist_destroy(xfs_frlist_t *); | ||
91 | STATIC int xfs_qm_mplist_nowait(xfs_mount_t *); | ||
92 | STATIC int xfs_qm_dqhashlock_nowait(xfs_dquot_t *); | ||
93 | |||
89 | STATIC int xfs_qm_init_quotainos(xfs_mount_t *); | 94 | STATIC int xfs_qm_init_quotainos(xfs_mount_t *); |
95 | STATIC int xfs_qm_init_quotainfo(xfs_mount_t *); | ||
90 | STATIC int xfs_qm_shake(int, unsigned int); | 96 | STATIC 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 | */ |
187 | void | 193 | STATIC void |
188 | xfs_qm_destroy( | 194 | xfs_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 | */ |
512 | int | 522 | STATIC int |
513 | xfs_qm_dqflush_all( | 523 | xfs_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( | |||
613 | STATIC int | 623 | STATIC int |
614 | xfs_qm_dqpurge_int( | 624 | xfs_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 | */ |
1152 | int | 1168 | STATIC int |
1153 | xfs_qm_init_quotainfo( | 1169 | xfs_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 | */ |
1584 | STATIC int | 1616 | STATIC 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 | */ |
2616 | int | 2668 | int |
2617 | xfs_qm_vop_chown_reserve( | 2669 | xfs_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 -----------------*/ |
2754 | void | 2812 | STATIC void |
2755 | xfs_qm_freelist_init(xfs_frlist_t *ql) | 2813 | xfs_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 | ||
2763 | void | 2821 | STATIC void |
2764 | xfs_qm_freelist_destroy(xfs_frlist_t *ql) | 2822 | xfs_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 | ||
2789 | void | 2847 | STATIC void |
2790 | xfs_qm_freelist_insert(xfs_frlist_t *ql, xfs_dquot_t *dq) | 2848 | xfs_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 | ||
2819 | int | 2877 | STATIC int |
2820 | xfs_qm_dqhashlock_nowait( | 2878 | xfs_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 | ||
2839 | int | 2897 | STATIC int |
2840 | xfs_qm_mplist_nowait( | 2898 | xfs_qm_mplist_nowait( |
2841 | xfs_mount_t *mp) | 2899 | xfs_mount_t *mp) |
2842 | { | 2900 | { |