diff options
author | Jaroslav Kysela <perex@petra> | 2005-06-22 06:19:24 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@petra> | 2005-06-22 06:19:24 -0400 |
commit | da04b128cf0d74dd4cab270c53d9264e70f9203e (patch) | |
tree | 095355c32dfd709236a85b497d3bd461d7cdfe8a /fs/xfs/quota | |
parent | fae6ec69c84d71b1d5bda9ede1a262c1681684aa (diff) | |
parent | 2a5a68b840cbab31baab2d9b2e1e6de3b289ae1e (diff) |
Merge with rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'fs/xfs/quota')
-rw-r--r-- | fs/xfs/quota/xfs_dquot.c | 105 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_dquot.h | 30 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_dquot_item.c | 6 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm.c | 202 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm.h | 16 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm_bhv.c | 43 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm_syscalls.c | 175 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_quota_priv.h | 15 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_trans_dquot.c | 60 |
9 files changed, 360 insertions, 292 deletions
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 740d20d33187..46ce1e3ce1d6 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c | |||
@@ -101,7 +101,7 @@ int xfs_dqerror_mod = 33; | |||
101 | * is the d_id field. The idea is to fill in the entire q_core | 101 | * is the d_id field. The idea is to fill in the entire q_core |
102 | * when we read in the on disk dquot. | 102 | * when we read in the on disk dquot. |
103 | */ | 103 | */ |
104 | xfs_dquot_t * | 104 | STATIC xfs_dquot_t * |
105 | xfs_qm_dqinit( | 105 | xfs_qm_dqinit( |
106 | xfs_mount_t *mp, | 106 | xfs_mount_t *mp, |
107 | xfs_dqid_t id, | 107 | xfs_dqid_t id, |
@@ -286,7 +286,9 @@ xfs_qm_adjust_dqlimits( | |||
286 | * We also return 0 as the values of the timers in Q_GETQUOTA calls, when | 286 | * We also return 0 as the values of the timers in Q_GETQUOTA calls, when |
287 | * enforcement's off. | 287 | * enforcement's off. |
288 | * In contrast, warnings are a little different in that they don't | 288 | * In contrast, warnings are a little different in that they don't |
289 | * 'automatically' get started when limits get exceeded. | 289 | * 'automatically' get started when limits get exceeded. They do |
290 | * get reset to zero, however, when we find the count to be under | ||
291 | * the soft limit (they are only ever set non-zero via userspace). | ||
290 | */ | 292 | */ |
291 | void | 293 | void |
292 | xfs_qm_adjust_dqtimers( | 294 | xfs_qm_adjust_dqtimers( |
@@ -315,6 +317,8 @@ xfs_qm_adjust_dqtimers( | |||
315 | INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) { | 317 | INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) { |
316 | INT_SET(d->d_btimer, ARCH_CONVERT, | 318 | INT_SET(d->d_btimer, ARCH_CONVERT, |
317 | get_seconds() + XFS_QI_BTIMELIMIT(mp)); | 319 | get_seconds() + XFS_QI_BTIMELIMIT(mp)); |
320 | } else { | ||
321 | d->d_bwarns = 0; | ||
318 | } | 322 | } |
319 | } else { | 323 | } else { |
320 | if ((!d->d_blk_softlimit || | 324 | if ((!d->d_blk_softlimit || |
@@ -336,6 +340,8 @@ xfs_qm_adjust_dqtimers( | |||
336 | INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) { | 340 | INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) { |
337 | INT_SET(d->d_itimer, ARCH_CONVERT, | 341 | INT_SET(d->d_itimer, ARCH_CONVERT, |
338 | get_seconds() + XFS_QI_ITIMELIMIT(mp)); | 342 | get_seconds() + XFS_QI_ITIMELIMIT(mp)); |
343 | } else { | ||
344 | d->d_iwarns = 0; | ||
339 | } | 345 | } |
340 | } else { | 346 | } else { |
341 | if ((!d->d_ino_softlimit || | 347 | if ((!d->d_ino_softlimit || |
@@ -357,6 +363,8 @@ xfs_qm_adjust_dqtimers( | |||
357 | INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT)))) { | 363 | INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT)))) { |
358 | INT_SET(d->d_rtbtimer, ARCH_CONVERT, | 364 | INT_SET(d->d_rtbtimer, ARCH_CONVERT, |
359 | get_seconds() + XFS_QI_RTBTIMELIMIT(mp)); | 365 | get_seconds() + XFS_QI_RTBTIMELIMIT(mp)); |
366 | } else { | ||
367 | d->d_rtbwarns = 0; | ||
360 | } | 368 | } |
361 | } else { | 369 | } else { |
362 | if ((!d->d_rtb_softlimit || | 370 | if ((!d->d_rtb_softlimit || |
@@ -371,68 +379,6 @@ xfs_qm_adjust_dqtimers( | |||
371 | } | 379 | } |
372 | 380 | ||
373 | /* | 381 | /* |
374 | * Increment or reset warnings of a given dquot. | ||
375 | */ | ||
376 | int | ||
377 | xfs_qm_dqwarn( | ||
378 | xfs_disk_dquot_t *d, | ||
379 | uint flags) | ||
380 | { | ||
381 | int warned; | ||
382 | |||
383 | /* | ||
384 | * root's limits are not real limits. | ||
385 | */ | ||
386 | if (!d->d_id) | ||
387 | return (0); | ||
388 | |||
389 | warned = 0; | ||
390 | if (INT_GET(d->d_blk_softlimit, ARCH_CONVERT) && | ||
391 | (INT_GET(d->d_bcount, ARCH_CONVERT) >= | ||
392 | INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) { | ||
393 | if (flags & XFS_QMOPT_DOWARN) { | ||
394 | INT_MOD(d->d_bwarns, ARCH_CONVERT, +1); | ||
395 | warned++; | ||
396 | } | ||
397 | } else { | ||
398 | if (!d->d_blk_softlimit || | ||
399 | (INT_GET(d->d_bcount, ARCH_CONVERT) < | ||
400 | INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) { | ||
401 | d->d_bwarns = 0; | ||
402 | } | ||
403 | } | ||
404 | |||
405 | if (INT_GET(d->d_ino_softlimit, ARCH_CONVERT) > 0 && | ||
406 | (INT_GET(d->d_icount, ARCH_CONVERT) >= | ||
407 | INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) { | ||
408 | if (flags & XFS_QMOPT_DOWARN) { | ||
409 | INT_MOD(d->d_iwarns, ARCH_CONVERT, +1); | ||
410 | warned++; | ||
411 | } | ||
412 | } else { | ||
413 | if (!d->d_ino_softlimit || | ||
414 | (INT_GET(d->d_icount, ARCH_CONVERT) < | ||
415 | INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) { | ||
416 | d->d_iwarns = 0; | ||
417 | } | ||
418 | } | ||
419 | #ifdef QUOTADEBUG | ||
420 | if (INT_GET(d->d_iwarns, ARCH_CONVERT)) | ||
421 | cmn_err(CE_DEBUG, | ||
422 | "--------@@Inode warnings running : %Lu >= %Lu", | ||
423 | INT_GET(d->d_icount, ARCH_CONVERT), | ||
424 | INT_GET(d->d_ino_softlimit, ARCH_CONVERT)); | ||
425 | if (INT_GET(d->d_bwarns, ARCH_CONVERT)) | ||
426 | cmn_err(CE_DEBUG, | ||
427 | "--------@@Blks warnings running : %Lu >= %Lu", | ||
428 | INT_GET(d->d_bcount, ARCH_CONVERT), | ||
429 | INT_GET(d->d_blk_softlimit, ARCH_CONVERT)); | ||
430 | #endif | ||
431 | return (warned); | ||
432 | } | ||
433 | |||
434 | |||
435 | /* | ||
436 | * initialize a buffer full of dquots and log the whole thing | 382 | * initialize a buffer full of dquots and log the whole thing |
437 | */ | 383 | */ |
438 | STATIC void | 384 | STATIC void |
@@ -461,9 +407,9 @@ xfs_qm_init_dquot_blk( | |||
461 | for (i = 0; i < XFS_QM_DQPERBLK(mp); i++, d++, curid++) | 407 | for (i = 0; i < XFS_QM_DQPERBLK(mp); i++, d++, curid++) |
462 | xfs_qm_dqinit_core(curid, type, d); | 408 | xfs_qm_dqinit_core(curid, type, d); |
463 | xfs_trans_dquot_buf(tp, bp, | 409 | xfs_trans_dquot_buf(tp, bp, |
464 | type & XFS_DQ_USER ? | 410 | (type & XFS_DQ_USER ? XFS_BLI_UDQUOT_BUF : |
465 | XFS_BLI_UDQUOT_BUF : | 411 | ((type & XFS_DQ_PROJ) ? XFS_BLI_PDQUOT_BUF : |
466 | XFS_BLI_GDQUOT_BUF); | 412 | XFS_BLI_GDQUOT_BUF))); |
467 | xfs_trans_log_buf(tp, bp, 0, BBTOB(XFS_QI_DQCHUNKLEN(mp)) - 1); | 413 | xfs_trans_log_buf(tp, bp, 0, BBTOB(XFS_QI_DQCHUNKLEN(mp)) - 1); |
468 | } | 414 | } |
469 | 415 | ||
@@ -544,8 +490,7 @@ xfs_qm_dqalloc( | |||
544 | * the entire thing. | 490 | * the entire thing. |
545 | */ | 491 | */ |
546 | xfs_qm_init_dquot_blk(tp, mp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT), | 492 | xfs_qm_init_dquot_blk(tp, mp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT), |
547 | dqp->dq_flags & (XFS_DQ_USER|XFS_DQ_GROUP), | 493 | dqp->dq_flags & XFS_DQ_ALLTYPES, bp); |
548 | bp); | ||
549 | 494 | ||
550 | if ((error = xfs_bmap_finish(&tp, &flist, firstblock, &committed))) { | 495 | if ((error = xfs_bmap_finish(&tp, &flist, firstblock, &committed))) { |
551 | goto error1; | 496 | goto error1; |
@@ -675,8 +620,7 @@ xfs_qm_dqtobp( | |||
675 | /* | 620 | /* |
676 | * A simple sanity check in case we got a corrupted dquot... | 621 | * A simple sanity check in case we got a corrupted dquot... |
677 | */ | 622 | */ |
678 | if (xfs_qm_dqcheck(ddq, id, | 623 | if (xfs_qm_dqcheck(ddq, id, dqp->dq_flags & XFS_DQ_ALLTYPES, |
679 | dqp->dq_flags & (XFS_DQ_USER|XFS_DQ_GROUP), | ||
680 | flags & (XFS_QMOPT_DQREPAIR|XFS_QMOPT_DOWARN), | 624 | flags & (XFS_QMOPT_DQREPAIR|XFS_QMOPT_DOWARN), |
681 | "dqtobp")) { | 625 | "dqtobp")) { |
682 | if (!(flags & XFS_QMOPT_DQREPAIR)) { | 626 | if (!(flags & XFS_QMOPT_DQREPAIR)) { |
@@ -953,8 +897,8 @@ int | |||
953 | xfs_qm_dqget( | 897 | xfs_qm_dqget( |
954 | xfs_mount_t *mp, | 898 | xfs_mount_t *mp, |
955 | xfs_inode_t *ip, /* locked inode (optional) */ | 899 | xfs_inode_t *ip, /* locked inode (optional) */ |
956 | xfs_dqid_t id, /* gid or uid, depending on type */ | 900 | xfs_dqid_t id, /* uid/projid/gid depending on type */ |
957 | uint type, /* UDQUOT or GDQUOT */ | 901 | uint type, /* XFS_DQ_USER/XFS_DQ_PROJ/XFS_DQ_GROUP */ |
958 | uint flags, /* DQALLOC, DQSUSER, DQREPAIR, DOWARN */ | 902 | uint flags, /* DQALLOC, DQSUSER, DQREPAIR, DOWARN */ |
959 | xfs_dquot_t **O_dqpp) /* OUT : locked incore dquot */ | 903 | xfs_dquot_t **O_dqpp) /* OUT : locked incore dquot */ |
960 | { | 904 | { |
@@ -965,6 +909,7 @@ xfs_qm_dqget( | |||
965 | 909 | ||
966 | ASSERT(XFS_IS_QUOTA_RUNNING(mp)); | 910 | ASSERT(XFS_IS_QUOTA_RUNNING(mp)); |
967 | if ((! XFS_IS_UQUOTA_ON(mp) && type == XFS_DQ_USER) || | 911 | if ((! XFS_IS_UQUOTA_ON(mp) && type == XFS_DQ_USER) || |
912 | (! XFS_IS_PQUOTA_ON(mp) && type == XFS_DQ_PROJ) || | ||
968 | (! XFS_IS_GQUOTA_ON(mp) && type == XFS_DQ_GROUP)) { | 913 | (! XFS_IS_GQUOTA_ON(mp) && type == XFS_DQ_GROUP)) { |
969 | return (ESRCH); | 914 | return (ESRCH); |
970 | } | 915 | } |
@@ -983,7 +928,9 @@ xfs_qm_dqget( | |||
983 | again: | 928 | again: |
984 | 929 | ||
985 | #ifdef DEBUG | 930 | #ifdef DEBUG |
986 | ASSERT(type == XFS_DQ_USER || type == XFS_DQ_GROUP); | 931 | ASSERT(type == XFS_DQ_USER || |
932 | type == XFS_DQ_PROJ || | ||
933 | type == XFS_DQ_GROUP); | ||
987 | if (ip) { | 934 | if (ip) { |
988 | ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); | 935 | ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); |
989 | if (type == XFS_DQ_USER) | 936 | if (type == XFS_DQ_USER) |
@@ -1306,8 +1253,8 @@ xfs_qm_dqflush( | |||
1306 | return (error); | 1253 | return (error); |
1307 | } | 1254 | } |
1308 | 1255 | ||
1309 | if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT), 0, XFS_QMOPT_DOWARN, | 1256 | if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT), |
1310 | "dqflush (incore copy)")) { | 1257 | 0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) { |
1311 | xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE); | 1258 | xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE); |
1312 | return XFS_ERROR(EIO); | 1259 | return XFS_ERROR(EIO); |
1313 | } | 1260 | } |
@@ -1459,7 +1406,8 @@ xfs_dqlock2( | |||
1459 | { | 1406 | { |
1460 | if (d1 && d2) { | 1407 | if (d1 && d2) { |
1461 | ASSERT(d1 != d2); | 1408 | ASSERT(d1 != d2); |
1462 | if (INT_GET(d1->q_core.d_id, ARCH_CONVERT) > INT_GET(d2->q_core.d_id, ARCH_CONVERT)) { | 1409 | if (INT_GET(d1->q_core.d_id, ARCH_CONVERT) > |
1410 | INT_GET(d2->q_core.d_id, ARCH_CONVERT)) { | ||
1463 | xfs_dqlock(d2); | 1411 | xfs_dqlock(d2); |
1464 | xfs_dqlock(d1); | 1412 | xfs_dqlock(d1); |
1465 | } else { | 1413 | } else { |
@@ -1582,8 +1530,7 @@ xfs_qm_dqprint(xfs_dquot_t *dqp) | |||
1582 | cmn_err(CE_DEBUG, "-----------KERNEL DQUOT----------------"); | 1530 | cmn_err(CE_DEBUG, "-----------KERNEL DQUOT----------------"); |
1583 | cmn_err(CE_DEBUG, "---- dquotID = %d", | 1531 | cmn_err(CE_DEBUG, "---- dquotID = %d", |
1584 | (int)INT_GET(dqp->q_core.d_id, ARCH_CONVERT)); | 1532 | (int)INT_GET(dqp->q_core.d_id, ARCH_CONVERT)); |
1585 | cmn_err(CE_DEBUG, "---- type = %s", | 1533 | cmn_err(CE_DEBUG, "---- type = %s", DQFLAGTO_TYPESTR(dqp)); |
1586 | XFS_QM_ISUDQ(dqp) ? "USR" : "GRP"); | ||
1587 | cmn_err(CE_DEBUG, "---- fs = 0x%p", dqp->q_mount); | 1534 | cmn_err(CE_DEBUG, "---- fs = 0x%p", dqp->q_mount); |
1588 | cmn_err(CE_DEBUG, "---- blkno = 0x%x", (int) dqp->q_blkno); | 1535 | cmn_err(CE_DEBUG, "---- blkno = 0x%x", (int) dqp->q_blkno); |
1589 | cmn_err(CE_DEBUG, "---- boffset = 0x%x", (int) dqp->q_bufoffset); | 1536 | cmn_err(CE_DEBUG, "---- boffset = 0x%x", (int) dqp->q_bufoffset); |
diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h index 0c3fe3175baa..39175103c8e0 100644 --- a/fs/xfs/quota/xfs_dquot.h +++ b/fs/xfs/quota/xfs_dquot.h | |||
@@ -114,25 +114,18 @@ typedef struct xfs_dquot { | |||
114 | #define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++) | 114 | #define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++) |
115 | 115 | ||
116 | /* | 116 | /* |
117 | * Quota Accounting flags | 117 | * Quota Accounting/Enforcement flags |
118 | */ | 118 | */ |
119 | #define XFS_ALL_QUOTA_ACCT (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT) | 119 | #define XFS_ALL_QUOTA_ACCT \ |
120 | #define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_GQUOTA_ENFD) | 120 | (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT) |
121 | #define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_GQUOTA_CHKD) | 121 | #define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD) |
122 | #define XFS_ALL_QUOTA_ACTV (XFS_UQUOTA_ACTIVE | XFS_GQUOTA_ACTIVE) | 122 | #define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD) |
123 | #define XFS_ALL_QUOTA_ACCT_ENFD (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\ | ||
124 | XFS_GQUOTA_ACCT|XFS_GQUOTA_ENFD) | ||
125 | 123 | ||
126 | #define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT) | 124 | #define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT) |
127 | #define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT) | ||
128 | #define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT) | ||
129 | |||
130 | /* | ||
131 | * Quota Limit Enforcement flags | ||
132 | */ | ||
133 | #define XFS_IS_QUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD) | 125 | #define XFS_IS_QUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD) |
134 | #define XFS_IS_UQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_UQUOTA_ENFD) | 126 | #define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT) |
135 | #define XFS_IS_GQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_GQUOTA_ENFD) | 127 | #define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT) |
128 | #define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT) | ||
136 | 129 | ||
137 | #ifdef DEBUG | 130 | #ifdef DEBUG |
138 | static inline int | 131 | static inline int |
@@ -167,6 +160,8 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp) | |||
167 | #define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp)) | 160 | #define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp)) |
168 | #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) | 161 | #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) |
169 | #define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) | 162 | #define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) |
163 | #define XFS_QM_ISPDQ(dqp) ((dqp)->dq_flags & XFS_DQ_PROJ) | ||
164 | #define XFS_QM_ISGDQ(dqp) ((dqp)->dq_flags & XFS_DQ_GROUP) | ||
170 | #define XFS_DQ_TO_QINF(dqp) ((dqp)->q_mount->m_quotainfo) | 165 | #define XFS_DQ_TO_QINF(dqp) ((dqp)->q_mount->m_quotainfo) |
171 | #define XFS_DQ_TO_QIP(dqp) (XFS_QM_ISUDQ(dqp) ? \ | 166 | #define XFS_DQ_TO_QIP(dqp) (XFS_QM_ISUDQ(dqp) ? \ |
172 | XFS_DQ_TO_QINF(dqp)->qi_uquotaip : \ | 167 | XFS_DQ_TO_QINF(dqp)->qi_uquotaip : \ |
@@ -174,7 +169,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp) | |||
174 | 169 | ||
175 | #define XFS_IS_THIS_QUOTA_OFF(d) (! (XFS_QM_ISUDQ(d) ? \ | 170 | #define XFS_IS_THIS_QUOTA_OFF(d) (! (XFS_QM_ISUDQ(d) ? \ |
176 | (XFS_IS_UQUOTA_ON((d)->q_mount)) : \ | 171 | (XFS_IS_UQUOTA_ON((d)->q_mount)) : \ |
177 | (XFS_IS_GQUOTA_ON((d)->q_mount)))) | 172 | (XFS_IS_OQUOTA_ON((d)->q_mount)))) |
178 | 173 | ||
179 | #ifdef XFS_DQUOT_TRACE | 174 | #ifdef XFS_DQUOT_TRACE |
180 | /* | 175 | /* |
@@ -211,7 +206,6 @@ extern void xfs_qm_adjust_dqtimers(xfs_mount_t *, | |||
211 | xfs_disk_dquot_t *); | 206 | xfs_disk_dquot_t *); |
212 | extern void xfs_qm_adjust_dqlimits(xfs_mount_t *, | 207 | extern void xfs_qm_adjust_dqlimits(xfs_mount_t *, |
213 | xfs_disk_dquot_t *); | 208 | xfs_disk_dquot_t *); |
214 | extern int xfs_qm_dqwarn(xfs_disk_dquot_t *, uint); | ||
215 | extern int xfs_qm_dqget(xfs_mount_t *, xfs_inode_t *, | 209 | extern int xfs_qm_dqget(xfs_mount_t *, xfs_inode_t *, |
216 | xfs_dqid_t, uint, uint, xfs_dquot_t **); | 210 | xfs_dqid_t, uint, uint, xfs_dquot_t **); |
217 | extern void xfs_qm_dqput(xfs_dquot_t *); | 211 | extern void xfs_qm_dqput(xfs_dquot_t *); |
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c index a5425ee6e7bd..f5271b7b1e84 100644 --- a/fs/xfs/quota/xfs_dquot_item.c +++ b/fs/xfs/quota/xfs_dquot_item.c | |||
@@ -428,7 +428,7 @@ xfs_qm_dquot_logitem_committing( | |||
428 | /* | 428 | /* |
429 | * This is the ops vector for dquots | 429 | * This is the ops vector for dquots |
430 | */ | 430 | */ |
431 | struct xfs_item_ops xfs_dquot_item_ops = { | 431 | STATIC struct xfs_item_ops xfs_dquot_item_ops = { |
432 | .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_size, | 432 | .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_size, |
433 | .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) | 433 | .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) |
434 | xfs_qm_dquot_logitem_format, | 434 | xfs_qm_dquot_logitem_format, |
@@ -646,7 +646,7 @@ xfs_qm_qoffend_logitem_committing(xfs_qoff_logitem_t *qip, xfs_lsn_t commit_lsn) | |||
646 | return; | 646 | return; |
647 | } | 647 | } |
648 | 648 | ||
649 | struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { | 649 | STATIC struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { |
650 | .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size, | 650 | .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size, |
651 | .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) | 651 | .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) |
652 | xfs_qm_qoff_logitem_format, | 652 | xfs_qm_qoff_logitem_format, |
@@ -669,7 +669,7 @@ struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { | |||
669 | /* | 669 | /* |
670 | * This is the ops vector shared by all quotaoff-start log items. | 670 | * This is the ops vector shared by all quotaoff-start log items. |
671 | */ | 671 | */ |
672 | struct xfs_item_ops xfs_qm_qoff_logitem_ops = { | 672 | STATIC struct xfs_item_ops xfs_qm_qoff_logitem_ops = { |
673 | .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size, | 673 | .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size, |
674 | .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) | 674 | .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) |
675 | xfs_qm_qoff_logitem_format, | 675 | xfs_qm_qoff_logitem_format, |
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 | { |
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h index dcf1a7a831d8..b03eecf3b6cb 100644 --- a/fs/xfs/quota/xfs_qm.h +++ b/fs/xfs/quota/xfs_qm.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. | 2 | * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of version 2 of the GNU General Public License as | 5 | * under the terms of version 2 of the GNU General Public License as |
@@ -133,8 +133,9 @@ typedef struct xfs_quotainfo { | |||
133 | time_t qi_btimelimit; /* limit for blks timer */ | 133 | time_t qi_btimelimit; /* limit for blks timer */ |
134 | time_t qi_itimelimit; /* limit for inodes timer */ | 134 | time_t qi_itimelimit; /* limit for inodes timer */ |
135 | time_t qi_rtbtimelimit;/* limit for rt blks timer */ | 135 | time_t qi_rtbtimelimit;/* limit for rt blks timer */ |
136 | xfs_qwarncnt_t qi_bwarnlimit; /* limit for num warnings */ | 136 | xfs_qwarncnt_t qi_bwarnlimit; /* limit for blks warnings */ |
137 | xfs_qwarncnt_t qi_iwarnlimit; /* limit for num warnings */ | 137 | xfs_qwarncnt_t qi_iwarnlimit; /* limit for inodes warnings */ |
138 | xfs_qwarncnt_t qi_rtbwarnlimit;/* limit for rt blks warnings */ | ||
138 | mutex_t qi_quotaofflock;/* to serialize quotaoff */ | 139 | mutex_t qi_quotaofflock;/* to serialize quotaoff */ |
139 | xfs_filblks_t qi_dqchunklen; /* # BBs in a chunk of dqs */ | 140 | xfs_filblks_t qi_dqchunklen; /* # BBs in a chunk of dqs */ |
140 | uint qi_dqperchunk; /* # ondisk dqs in above chunk */ | 141 | uint qi_dqperchunk; /* # ondisk dqs in above chunk */ |
@@ -176,6 +177,7 @@ typedef struct xfs_dquot_acct { | |||
176 | 177 | ||
177 | #define XFS_QM_BWARNLIMIT 5 | 178 | #define XFS_QM_BWARNLIMIT 5 |
178 | #define XFS_QM_IWARNLIMIT 5 | 179 | #define XFS_QM_IWARNLIMIT 5 |
180 | #define XFS_QM_RTBWARNLIMIT 5 | ||
179 | 181 | ||
180 | #define XFS_QM_LOCK(xqm) (mutex_lock(&xqm##_lock, PINOD)) | 182 | #define XFS_QM_LOCK(xqm) (mutex_lock(&xqm##_lock, PINOD)) |
181 | #define XFS_QM_UNLOCK(xqm) (mutex_unlock(&xqm##_lock)) | 183 | #define XFS_QM_UNLOCK(xqm) (mutex_unlock(&xqm##_lock)) |
@@ -184,7 +186,6 @@ typedef struct xfs_dquot_acct { | |||
184 | 186 | ||
185 | extern void xfs_mount_reset_sbqflags(xfs_mount_t *); | 187 | extern void xfs_mount_reset_sbqflags(xfs_mount_t *); |
186 | 188 | ||
187 | extern int xfs_qm_init_quotainfo(xfs_mount_t *); | ||
188 | extern void xfs_qm_destroy_quotainfo(xfs_mount_t *); | 189 | extern void xfs_qm_destroy_quotainfo(xfs_mount_t *); |
189 | extern int xfs_qm_mount_quotas(xfs_mount_t *, int); | 190 | extern int xfs_qm_mount_quotas(xfs_mount_t *, int); |
190 | extern void xfs_qm_mount_quotainit(xfs_mount_t *, uint); | 191 | extern void xfs_qm_mount_quotainit(xfs_mount_t *, uint); |
@@ -203,7 +204,7 @@ extern void xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint); | |||
203 | 204 | ||
204 | /* vop stuff */ | 205 | /* vop stuff */ |
205 | extern int xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *, | 206 | extern int xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *, |
206 | uid_t, gid_t, uint, | 207 | uid_t, gid_t, prid_t, uint, |
207 | xfs_dquot_t **, xfs_dquot_t **); | 208 | xfs_dquot_t **, xfs_dquot_t **); |
208 | extern void xfs_qm_vop_dqattach_and_dqmod_newinode( | 209 | extern void xfs_qm_vop_dqattach_and_dqmod_newinode( |
209 | xfs_trans_t *, xfs_inode_t *, | 210 | xfs_trans_t *, xfs_inode_t *, |
@@ -215,14 +216,9 @@ extern int xfs_qm_vop_chown_reserve(xfs_trans_t *, xfs_inode_t *, | |||
215 | xfs_dquot_t *, xfs_dquot_t *, uint); | 216 | xfs_dquot_t *, xfs_dquot_t *, uint); |
216 | 217 | ||
217 | /* list stuff */ | 218 | /* list stuff */ |
218 | extern void xfs_qm_freelist_init(xfs_frlist_t *); | ||
219 | extern void xfs_qm_freelist_destroy(xfs_frlist_t *); | ||
220 | extern void xfs_qm_freelist_insert(xfs_frlist_t *, xfs_dquot_t *); | ||
221 | extern void xfs_qm_freelist_append(xfs_frlist_t *, xfs_dquot_t *); | 219 | extern void xfs_qm_freelist_append(xfs_frlist_t *, xfs_dquot_t *); |
222 | extern void xfs_qm_freelist_unlink(xfs_dquot_t *); | 220 | extern void xfs_qm_freelist_unlink(xfs_dquot_t *); |
223 | extern int xfs_qm_freelist_lock_nowait(xfs_qm_t *); | 221 | extern int xfs_qm_freelist_lock_nowait(xfs_qm_t *); |
224 | extern int xfs_qm_mplist_nowait(xfs_mount_t *); | ||
225 | extern int xfs_qm_dqhashlock_nowait(xfs_dquot_t *); | ||
226 | 222 | ||
227 | /* system call interface */ | 223 | /* system call interface */ |
228 | extern int xfs_qm_quotactl(bhv_desc_t *, int, int, xfs_caddr_t); | 224 | extern int xfs_qm_quotactl(bhv_desc_t *, int, int, xfs_caddr_t); |
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c index be67d9c265f8..dc3c37a1e158 100644 --- a/fs/xfs/quota/xfs_qm_bhv.c +++ b/fs/xfs/quota/xfs_qm_bhv.c | |||
@@ -71,10 +71,13 @@ | |||
71 | #define MNTOPT_NOQUOTA "noquota" /* no quotas */ | 71 | #define MNTOPT_NOQUOTA "noquota" /* no quotas */ |
72 | #define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */ | 72 | #define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */ |
73 | #define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */ | 73 | #define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */ |
74 | #define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */ | ||
74 | #define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */ | 75 | #define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */ |
75 | #define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */ | 76 | #define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */ |
77 | #define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */ | ||
76 | #define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */ | 78 | #define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */ |
77 | #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ | 79 | #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ |
80 | #define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */ | ||
78 | #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ | 81 | #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ |
79 | 82 | ||
80 | STATIC int | 83 | STATIC int |
@@ -109,6 +112,14 @@ xfs_qm_parseargs( | |||
109 | args->flags |= XFSMNT_UQUOTA; | 112 | args->flags |= XFSMNT_UQUOTA; |
110 | args->flags &= ~XFSMNT_UQUOTAENF; | 113 | args->flags &= ~XFSMNT_UQUOTAENF; |
111 | referenced = 1; | 114 | referenced = 1; |
115 | } else if (!strcmp(this_char, MNTOPT_PQUOTA) || | ||
116 | !strcmp(this_char, MNTOPT_PRJQUOTA)) { | ||
117 | args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF; | ||
118 | referenced = 1; | ||
119 | } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) { | ||
120 | args->flags |= XFSMNT_PQUOTA; | ||
121 | args->flags &= ~XFSMNT_PQUOTAENF; | ||
122 | referenced = 1; | ||
112 | } else if (!strcmp(this_char, MNTOPT_GQUOTA) || | 123 | } else if (!strcmp(this_char, MNTOPT_GQUOTA) || |
113 | !strcmp(this_char, MNTOPT_GRPQUOTA)) { | 124 | !strcmp(this_char, MNTOPT_GRPQUOTA)) { |
114 | args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF; | 125 | args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF; |
@@ -127,6 +138,12 @@ xfs_qm_parseargs( | |||
127 | *this_char++ = ','; | 138 | *this_char++ = ','; |
128 | } | 139 | } |
129 | 140 | ||
141 | if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) { | ||
142 | cmn_err(CE_WARN, | ||
143 | "XFS: cannot mount with both project and group quota"); | ||
144 | return XFS_ERROR(EINVAL); | ||
145 | } | ||
146 | |||
130 | PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error); | 147 | PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error); |
131 | if (!error && !referenced) | 148 | if (!error && !referenced) |
132 | bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM); | 149 | bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM); |
@@ -148,13 +165,19 @@ xfs_qm_showargs( | |||
148 | seq_puts(m, "," MNTOPT_UQUOTANOENF); | 165 | seq_puts(m, "," MNTOPT_UQUOTANOENF); |
149 | } | 166 | } |
150 | 167 | ||
168 | if (mp->m_qflags & XFS_PQUOTA_ACCT) { | ||
169 | (mp->m_qflags & XFS_OQUOTA_ENFD) ? | ||
170 | seq_puts(m, "," MNTOPT_PRJQUOTA) : | ||
171 | seq_puts(m, "," MNTOPT_PQUOTANOENF); | ||
172 | } | ||
173 | |||
151 | if (mp->m_qflags & XFS_GQUOTA_ACCT) { | 174 | if (mp->m_qflags & XFS_GQUOTA_ACCT) { |
152 | (mp->m_qflags & XFS_GQUOTA_ENFD) ? | 175 | (mp->m_qflags & XFS_OQUOTA_ENFD) ? |
153 | seq_puts(m, "," MNTOPT_GRPQUOTA) : | 176 | seq_puts(m, "," MNTOPT_GRPQUOTA) : |
154 | seq_puts(m, "," MNTOPT_GQUOTANOENF); | 177 | seq_puts(m, "," MNTOPT_GQUOTANOENF); |
155 | } | 178 | } |
156 | 179 | ||
157 | if (!(mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT))) | 180 | if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) |
158 | seq_puts(m, "," MNTOPT_NOQUOTA); | 181 | seq_puts(m, "," MNTOPT_NOQUOTA); |
159 | 182 | ||
160 | PVFS_SHOWARGS(BHV_NEXT(bhv), m, error); | 183 | PVFS_SHOWARGS(BHV_NEXT(bhv), m, error); |
@@ -171,7 +194,7 @@ xfs_qm_mount( | |||
171 | struct xfs_mount *mp = XFS_VFSTOM(vfsp); | 194 | struct xfs_mount *mp = XFS_VFSTOM(vfsp); |
172 | int error; | 195 | int error; |
173 | 196 | ||
174 | if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA)) | 197 | if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA)) |
175 | xfs_qm_mount_quotainit(mp, args->flags); | 198 | xfs_qm_mount_quotainit(mp, args->flags); |
176 | PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error); | 199 | PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error); |
177 | return error; | 200 | return error; |
@@ -255,16 +278,17 @@ xfs_qm_newmount( | |||
255 | uint *quotaflags) | 278 | uint *quotaflags) |
256 | { | 279 | { |
257 | uint quotaondisk; | 280 | uint quotaondisk; |
258 | uint uquotaondisk = 0, gquotaondisk = 0; | 281 | uint uquotaondisk = 0, gquotaondisk = 0, pquotaondisk = 0; |
259 | 282 | ||
260 | *quotaflags = 0; | 283 | *quotaflags = 0; |
261 | *needquotamount = B_FALSE; | 284 | *needquotamount = B_FALSE; |
262 | 285 | ||
263 | quotaondisk = XFS_SB_VERSION_HASQUOTA(&mp->m_sb) && | 286 | quotaondisk = XFS_SB_VERSION_HASQUOTA(&mp->m_sb) && |
264 | mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT); | 287 | (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT); |
265 | 288 | ||
266 | if (quotaondisk) { | 289 | if (quotaondisk) { |
267 | uquotaondisk = mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT; | 290 | uquotaondisk = mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT; |
291 | pquotaondisk = mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT; | ||
268 | gquotaondisk = mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT; | 292 | gquotaondisk = mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT; |
269 | } | 293 | } |
270 | 294 | ||
@@ -277,13 +301,16 @@ xfs_qm_newmount( | |||
277 | 301 | ||
278 | if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) || | 302 | if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) || |
279 | (!uquotaondisk && XFS_IS_UQUOTA_ON(mp)) || | 303 | (!uquotaondisk && XFS_IS_UQUOTA_ON(mp)) || |
304 | (pquotaondisk && !XFS_IS_PQUOTA_ON(mp)) || | ||
305 | (!pquotaondisk && XFS_IS_PQUOTA_ON(mp)) || | ||
280 | (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) || | 306 | (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) || |
281 | (!gquotaondisk && XFS_IS_GQUOTA_ON(mp))) && | 307 | (!gquotaondisk && XFS_IS_OQUOTA_ON(mp))) && |
282 | xfs_dev_is_read_only(mp, "changing quota state")) { | 308 | xfs_dev_is_read_only(mp, "changing quota state")) { |
283 | cmn_err(CE_WARN, | 309 | cmn_err(CE_WARN, |
284 | "XFS: please mount with%s%s%s.", | 310 | "XFS: please mount with%s%s%s%s.", |
285 | (!quotaondisk ? "out quota" : ""), | 311 | (!quotaondisk ? "out quota" : ""), |
286 | (uquotaondisk ? " usrquota" : ""), | 312 | (uquotaondisk ? " usrquota" : ""), |
313 | (pquotaondisk ? " prjquota" : ""), | ||
287 | (gquotaondisk ? " grpquota" : "")); | 314 | (gquotaondisk ? " grpquota" : "")); |
288 | return XFS_ERROR(EPERM); | 315 | return XFS_ERROR(EPERM); |
289 | } | 316 | } |
@@ -359,7 +386,7 @@ xfs_qm_dqrele_null( | |||
359 | } | 386 | } |
360 | 387 | ||
361 | 388 | ||
362 | struct xfs_qmops xfs_qmcore_xfs = { | 389 | STATIC struct xfs_qmops xfs_qmcore_xfs = { |
363 | .xfs_qminit = xfs_qm_newmount, | 390 | .xfs_qminit = xfs_qm_newmount, |
364 | .xfs_qmdone = xfs_qm_unmount_quotadestroy, | 391 | .xfs_qmdone = xfs_qm_unmount_quotadestroy, |
365 | .xfs_qmmount = xfs_qm_endmount, | 392 | .xfs_qmmount = xfs_qm_endmount, |
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 229f5b5a2d25..68e98962dbef 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c | |||
@@ -118,40 +118,41 @@ xfs_qm_quotactl( | |||
118 | * The following commands are valid even when quotaoff. | 118 | * The following commands are valid even when quotaoff. |
119 | */ | 119 | */ |
120 | switch (cmd) { | 120 | switch (cmd) { |
121 | case Q_XQUOTARM: | ||
121 | /* | 122 | /* |
122 | * truncate quota files. quota must be off. | 123 | * Truncate quota files. quota must be off. |
123 | */ | 124 | */ |
124 | case Q_XQUOTARM: | ||
125 | if (XFS_IS_QUOTA_ON(mp) || addr == NULL) | 125 | if (XFS_IS_QUOTA_ON(mp) || addr == NULL) |
126 | return XFS_ERROR(EINVAL); | 126 | return XFS_ERROR(EINVAL); |
127 | if (vfsp->vfs_flag & VFS_RDONLY) | 127 | if (vfsp->vfs_flag & VFS_RDONLY) |
128 | return XFS_ERROR(EROFS); | 128 | return XFS_ERROR(EROFS); |
129 | return (xfs_qm_scall_trunc_qfiles(mp, | 129 | return (xfs_qm_scall_trunc_qfiles(mp, |
130 | xfs_qm_import_qtype_flags(*(uint *)addr))); | 130 | xfs_qm_import_qtype_flags(*(uint *)addr))); |
131 | |||
132 | case Q_XGETQSTAT: | ||
131 | /* | 133 | /* |
132 | * Get quota status information. | 134 | * Get quota status information. |
133 | */ | 135 | */ |
134 | case Q_XGETQSTAT: | ||
135 | return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr)); | 136 | return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr)); |
136 | 137 | ||
138 | case Q_XQUOTAON: | ||
137 | /* | 139 | /* |
138 | * QUOTAON for root f/s and quota enforcement on others.. | 140 | * QUOTAON - enabling quota enforcement. |
139 | * Quota accounting for non-root f/s's must be turned on | 141 | * Quota accounting must be turned on at mount time. |
140 | * at mount time. | ||
141 | */ | 142 | */ |
142 | case Q_XQUOTAON: | ||
143 | if (addr == NULL) | 143 | if (addr == NULL) |
144 | return XFS_ERROR(EINVAL); | 144 | return XFS_ERROR(EINVAL); |
145 | if (vfsp->vfs_flag & VFS_RDONLY) | 145 | if (vfsp->vfs_flag & VFS_RDONLY) |
146 | return XFS_ERROR(EROFS); | 146 | return XFS_ERROR(EROFS); |
147 | return (xfs_qm_scall_quotaon(mp, | 147 | return (xfs_qm_scall_quotaon(mp, |
148 | xfs_qm_import_flags(*(uint *)addr))); | 148 | xfs_qm_import_flags(*(uint *)addr))); |
149 | case Q_XQUOTAOFF: | 149 | |
150 | case Q_XQUOTAOFF: | ||
150 | if (vfsp->vfs_flag & VFS_RDONLY) | 151 | if (vfsp->vfs_flag & VFS_RDONLY) |
151 | return XFS_ERROR(EROFS); | 152 | return XFS_ERROR(EROFS); |
152 | break; | 153 | break; |
153 | 154 | ||
154 | default: | 155 | default: |
155 | break; | 156 | break; |
156 | } | 157 | } |
157 | 158 | ||
@@ -159,7 +160,7 @@ xfs_qm_quotactl( | |||
159 | return XFS_ERROR(ESRCH); | 160 | return XFS_ERROR(ESRCH); |
160 | 161 | ||
161 | switch (cmd) { | 162 | switch (cmd) { |
162 | case Q_XQUOTAOFF: | 163 | case Q_XQUOTAOFF: |
163 | if (vfsp->vfs_flag & VFS_RDONLY) | 164 | if (vfsp->vfs_flag & VFS_RDONLY) |
164 | return XFS_ERROR(EROFS); | 165 | return XFS_ERROR(EROFS); |
165 | error = xfs_qm_scall_quotaoff(mp, | 166 | error = xfs_qm_scall_quotaoff(mp, |
@@ -167,42 +168,39 @@ xfs_qm_quotactl( | |||
167 | B_FALSE); | 168 | B_FALSE); |
168 | break; | 169 | break; |
169 | 170 | ||
170 | /* | 171 | case Q_XGETQUOTA: |
171 | * Defaults to XFS_GETUQUOTA. | ||
172 | */ | ||
173 | case Q_XGETQUOTA: | ||
174 | error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER, | 172 | error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER, |
175 | (fs_disk_quota_t *)addr); | 173 | (fs_disk_quota_t *)addr); |
176 | break; | 174 | break; |
177 | /* | 175 | case Q_XGETGQUOTA: |
178 | * Set limits, both hard and soft. Defaults to Q_SETUQLIM. | 176 | error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, |
179 | */ | 177 | (fs_disk_quota_t *)addr); |
180 | case Q_XSETQLIM: | 178 | break; |
179 | case Q_XGETPQUOTA: | ||
180 | error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_PROJ, | ||
181 | (fs_disk_quota_t *)addr); | ||
182 | break; | ||
183 | |||
184 | case Q_XSETQLIM: | ||
181 | if (vfsp->vfs_flag & VFS_RDONLY) | 185 | if (vfsp->vfs_flag & VFS_RDONLY) |
182 | return XFS_ERROR(EROFS); | 186 | return XFS_ERROR(EROFS); |
183 | error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER, | 187 | error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER, |
184 | (fs_disk_quota_t *)addr); | 188 | (fs_disk_quota_t *)addr); |
185 | break; | 189 | break; |
186 | 190 | case Q_XSETGQLIM: | |
187 | case Q_XSETGQLIM: | ||
188 | if (vfsp->vfs_flag & VFS_RDONLY) | 191 | if (vfsp->vfs_flag & VFS_RDONLY) |
189 | return XFS_ERROR(EROFS); | 192 | return XFS_ERROR(EROFS); |
190 | error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, | 193 | error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, |
191 | (fs_disk_quota_t *)addr); | 194 | (fs_disk_quota_t *)addr); |
192 | break; | 195 | break; |
193 | 196 | case Q_XSETPQLIM: | |
194 | 197 | if (vfsp->vfs_flag & VFS_RDONLY) | |
195 | case Q_XGETGQUOTA: | 198 | return XFS_ERROR(EROFS); |
196 | error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, | 199 | error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_PROJ, |
197 | (fs_disk_quota_t *)addr); | 200 | (fs_disk_quota_t *)addr); |
198 | break; | 201 | break; |
199 | 202 | ||
200 | /* | 203 | default: |
201 | * Quotas are entirely undefined after quotaoff in XFS quotas. | ||
202 | * For instance, there's no way to set limits when quotaoff. | ||
203 | */ | ||
204 | |||
205 | default: | ||
206 | error = XFS_ERROR(EINVAL); | 204 | error = XFS_ERROR(EINVAL); |
207 | break; | 205 | break; |
208 | } | 206 | } |
@@ -286,8 +284,12 @@ xfs_qm_scall_quotaoff( | |||
286 | } | 284 | } |
287 | if (flags & XFS_GQUOTA_ACCT) { | 285 | if (flags & XFS_GQUOTA_ACCT) { |
288 | dqtype |= XFS_QMOPT_GQUOTA; | 286 | dqtype |= XFS_QMOPT_GQUOTA; |
289 | flags |= (XFS_GQUOTA_CHKD | XFS_GQUOTA_ENFD); | 287 | flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD); |
290 | inactivate_flags |= XFS_GQUOTA_ACTIVE; | 288 | inactivate_flags |= XFS_GQUOTA_ACTIVE; |
289 | } else if (flags & XFS_PQUOTA_ACCT) { | ||
290 | dqtype |= XFS_QMOPT_PQUOTA; | ||
291 | flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD); | ||
292 | inactivate_flags |= XFS_PQUOTA_ACTIVE; | ||
291 | } | 293 | } |
292 | 294 | ||
293 | /* | 295 | /* |
@@ -364,7 +366,8 @@ xfs_qm_scall_quotaoff( | |||
364 | /* | 366 | /* |
365 | * If quotas is completely disabled, close shop. | 367 | * If quotas is completely disabled, close shop. |
366 | */ | 368 | */ |
367 | if ((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_ALL) { | 369 | if (((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_SET1) || |
370 | ((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_SET2)) { | ||
368 | mutex_unlock(&(XFS_QI_QOFFLOCK(mp))); | 371 | mutex_unlock(&(XFS_QI_QOFFLOCK(mp))); |
369 | xfs_qm_destroy_quotainfo(mp); | 372 | xfs_qm_destroy_quotainfo(mp); |
370 | return (0); | 373 | return (0); |
@@ -378,7 +381,7 @@ xfs_qm_scall_quotaoff( | |||
378 | XFS_PURGE_INODE(XFS_QI_UQIP(mp)); | 381 | XFS_PURGE_INODE(XFS_QI_UQIP(mp)); |
379 | XFS_QI_UQIP(mp) = NULL; | 382 | XFS_QI_UQIP(mp) = NULL; |
380 | } | 383 | } |
381 | if ((dqtype & XFS_QMOPT_GQUOTA) && XFS_QI_GQIP(mp)) { | 384 | if ((dqtype & (XFS_QMOPT_GQUOTA|XFS_QMOPT_PQUOTA)) && XFS_QI_GQIP(mp)) { |
382 | XFS_PURGE_INODE(XFS_QI_GQIP(mp)); | 385 | XFS_PURGE_INODE(XFS_QI_GQIP(mp)); |
383 | XFS_QI_GQIP(mp) = NULL; | 386 | XFS_QI_GQIP(mp) = NULL; |
384 | } | 387 | } |
@@ -411,7 +414,8 @@ xfs_qm_scall_trunc_qfiles( | |||
411 | } | 414 | } |
412 | } | 415 | } |
413 | 416 | ||
414 | if ((flags & XFS_DQ_GROUP) && mp->m_sb.sb_gquotino != NULLFSINO) { | 417 | if ((flags & (XFS_DQ_GROUP|XFS_DQ_PROJ)) && |
418 | mp->m_sb.sb_gquotino != NULLFSINO) { | ||
415 | error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip, 0); | 419 | error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip, 0); |
416 | if (! error) { | 420 | if (! error) { |
417 | (void) xfs_truncate_file(mp, qip); | 421 | (void) xfs_truncate_file(mp, qip); |
@@ -434,7 +438,7 @@ xfs_qm_scall_quotaon( | |||
434 | uint flags) | 438 | uint flags) |
435 | { | 439 | { |
436 | int error; | 440 | int error; |
437 | unsigned long s; | 441 | unsigned long s; |
438 | uint qf; | 442 | uint qf; |
439 | uint accflags; | 443 | uint accflags; |
440 | __int64_t sbflags; | 444 | __int64_t sbflags; |
@@ -468,9 +472,13 @@ xfs_qm_scall_quotaon( | |||
468 | (mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 && | 472 | (mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 && |
469 | (flags & XFS_UQUOTA_ENFD)) | 473 | (flags & XFS_UQUOTA_ENFD)) |
470 | || | 474 | || |
475 | ((flags & XFS_PQUOTA_ACCT) == 0 && | ||
476 | (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 && | ||
477 | (flags & XFS_OQUOTA_ENFD)) | ||
478 | || | ||
471 | ((flags & XFS_GQUOTA_ACCT) == 0 && | 479 | ((flags & XFS_GQUOTA_ACCT) == 0 && |
472 | (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 && | 480 | (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 && |
473 | (flags & XFS_GQUOTA_ENFD))) { | 481 | (flags & XFS_OQUOTA_ENFD))) { |
474 | qdprintk("Can't enforce without acct, flags=%x sbflags=%x\n", | 482 | qdprintk("Can't enforce without acct, flags=%x sbflags=%x\n", |
475 | flags, mp->m_sb.sb_qflags); | 483 | flags, mp->m_sb.sb_qflags); |
476 | return XFS_ERROR(EINVAL); | 484 | return XFS_ERROR(EINVAL); |
@@ -504,6 +512,10 @@ xfs_qm_scall_quotaon( | |||
504 | */ | 512 | */ |
505 | if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) != | 513 | if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) != |
506 | (mp->m_qflags & XFS_UQUOTA_ACCT)) || | 514 | (mp->m_qflags & XFS_UQUOTA_ACCT)) || |
515 | ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) != | ||
516 | (mp->m_qflags & XFS_PQUOTA_ACCT)) || | ||
517 | ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) != | ||
518 | (mp->m_qflags & XFS_GQUOTA_ACCT)) || | ||
507 | (flags & XFS_ALL_QUOTA_ENFD) == 0) | 519 | (flags & XFS_ALL_QUOTA_ENFD) == 0) |
508 | return (0); | 520 | return (0); |
509 | 521 | ||
@@ -521,7 +533,6 @@ xfs_qm_scall_quotaon( | |||
521 | } | 533 | } |
522 | 534 | ||
523 | 535 | ||
524 | |||
525 | /* | 536 | /* |
526 | * Return quota status information, such as uquota-off, enforcements, etc. | 537 | * Return quota status information, such as uquota-off, enforcements, etc. |
527 | */ | 538 | */ |
@@ -606,7 +617,8 @@ xfs_qm_scall_setqlim( | |||
606 | if (!capable(CAP_SYS_ADMIN)) | 617 | if (!capable(CAP_SYS_ADMIN)) |
607 | return XFS_ERROR(EPERM); | 618 | return XFS_ERROR(EPERM); |
608 | 619 | ||
609 | if ((newlim->d_fieldmask & (FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK)) == 0) | 620 | if ((newlim->d_fieldmask & |
621 | (FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK|FS_DQ_WARNS_MASK)) == 0) | ||
610 | return (0); | 622 | return (0); |
611 | 623 | ||
612 | tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM); | 624 | tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM); |
@@ -691,12 +703,23 @@ xfs_qm_scall_setqlim( | |||
691 | qdprintk("ihard %Ld < isoft %Ld\n", hard, soft); | 703 | qdprintk("ihard %Ld < isoft %Ld\n", hard, soft); |
692 | } | 704 | } |
693 | 705 | ||
706 | /* | ||
707 | * Update warnings counter(s) if requested | ||
708 | */ | ||
709 | if (newlim->d_fieldmask & FS_DQ_BWARNS) | ||
710 | INT_SET(ddq->d_bwarns, ARCH_CONVERT, newlim->d_bwarns); | ||
711 | if (newlim->d_fieldmask & FS_DQ_IWARNS) | ||
712 | INT_SET(ddq->d_iwarns, ARCH_CONVERT, newlim->d_iwarns); | ||
713 | if (newlim->d_fieldmask & FS_DQ_RTBWARNS) | ||
714 | INT_SET(ddq->d_rtbwarns, ARCH_CONVERT, newlim->d_rtbwarns); | ||
715 | |||
694 | if (id == 0) { | 716 | if (id == 0) { |
695 | /* | 717 | /* |
696 | * Timelimits for the super user set the relative time | 718 | * Timelimits for the super user set the relative time |
697 | * the other users can be over quota for this file system. | 719 | * the other users can be over quota for this file system. |
698 | * If it is zero a default is used. Ditto for the default | 720 | * If it is zero a default is used. Ditto for the default |
699 | * soft and hard limit values (already done, above). | 721 | * soft and hard limit values (already done, above), and |
722 | * for warnings. | ||
700 | */ | 723 | */ |
701 | if (newlim->d_fieldmask & FS_DQ_BTIMER) { | 724 | if (newlim->d_fieldmask & FS_DQ_BTIMER) { |
702 | mp->m_quotainfo->qi_btimelimit = newlim->d_btimer; | 725 | mp->m_quotainfo->qi_btimelimit = newlim->d_btimer; |
@@ -710,7 +733,13 @@ xfs_qm_scall_setqlim( | |||
710 | mp->m_quotainfo->qi_rtbtimelimit = newlim->d_rtbtimer; | 733 | mp->m_quotainfo->qi_rtbtimelimit = newlim->d_rtbtimer; |
711 | INT_SET(ddq->d_rtbtimer, ARCH_CONVERT, newlim->d_rtbtimer); | 734 | INT_SET(ddq->d_rtbtimer, ARCH_CONVERT, newlim->d_rtbtimer); |
712 | } | 735 | } |
713 | } else /* if (XFS_IS_QUOTA_ENFORCED(mp)) */ { | 736 | if (newlim->d_fieldmask & FS_DQ_BWARNS) |
737 | mp->m_quotainfo->qi_bwarnlimit = newlim->d_bwarns; | ||
738 | if (newlim->d_fieldmask & FS_DQ_IWARNS) | ||
739 | mp->m_quotainfo->qi_iwarnlimit = newlim->d_iwarns; | ||
740 | if (newlim->d_fieldmask & FS_DQ_RTBWARNS) | ||
741 | mp->m_quotainfo->qi_rtbwarnlimit = newlim->d_rtbwarns; | ||
742 | } else { | ||
714 | /* | 743 | /* |
715 | * If the user is now over quota, start the timelimit. | 744 | * If the user is now over quota, start the timelimit. |
716 | * The user will not be 'warned'. | 745 | * The user will not be 'warned'. |
@@ -776,9 +805,9 @@ xfs_qm_log_quotaoff_end( | |||
776 | xfs_qoff_logitem_t *startqoff, | 805 | xfs_qoff_logitem_t *startqoff, |
777 | uint flags) | 806 | uint flags) |
778 | { | 807 | { |
779 | xfs_trans_t *tp; | 808 | xfs_trans_t *tp; |
780 | int error; | 809 | int error; |
781 | xfs_qoff_logitem_t *qoffi; | 810 | xfs_qoff_logitem_t *qoffi; |
782 | 811 | ||
783 | tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF_END); | 812 | tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF_END); |
784 | 813 | ||
@@ -928,18 +957,26 @@ xfs_qm_export_dquot( | |||
928 | 957 | ||
929 | STATIC uint | 958 | STATIC uint |
930 | xfs_qm_import_qtype_flags( | 959 | xfs_qm_import_qtype_flags( |
931 | uint uflags) | 960 | uint uflags) |
932 | { | 961 | { |
962 | uint oflags = 0; | ||
963 | |||
933 | /* | 964 | /* |
934 | * Can't be both at the same time. | 965 | * Can't be more than one, or none. |
935 | */ | 966 | */ |
936 | if (((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) == | 967 | if (((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) == |
937 | (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) || | 968 | (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) || |
938 | ((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) == 0)) | 969 | ((uflags & (XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) == |
970 | (XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) || | ||
971 | ((uflags & (XFS_USER_QUOTA | XFS_PROJ_QUOTA)) == | ||
972 | (XFS_USER_QUOTA | XFS_PROJ_QUOTA)) || | ||
973 | ((uflags & (XFS_GROUP_QUOTA|XFS_USER_QUOTA|XFS_PROJ_QUOTA)) == 0)) | ||
939 | return (0); | 974 | return (0); |
940 | 975 | ||
941 | return (uflags & XFS_USER_QUOTA) ? | 976 | oflags |= (uflags & XFS_USER_QUOTA) ? XFS_DQ_USER : 0; |
942 | XFS_DQ_USER : XFS_DQ_GROUP; | 977 | oflags |= (uflags & XFS_PROJ_QUOTA) ? XFS_DQ_PROJ : 0; |
978 | oflags |= (uflags & XFS_GROUP_QUOTA) ? XFS_DQ_GROUP: 0; | ||
979 | return oflags; | ||
943 | } | 980 | } |
944 | 981 | ||
945 | STATIC uint | 982 | STATIC uint |
@@ -947,14 +984,19 @@ xfs_qm_export_qtype_flags( | |||
947 | uint flags) | 984 | uint flags) |
948 | { | 985 | { |
949 | /* | 986 | /* |
950 | * Can't be both at the same time. | 987 | * Can't be more than one, or none. |
951 | */ | 988 | */ |
952 | ASSERT((flags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) != | 989 | ASSERT((flags & (XFS_PROJ_QUOTA | XFS_USER_QUOTA)) != |
953 | (XFS_GROUP_QUOTA | XFS_USER_QUOTA)); | 990 | (XFS_PROJ_QUOTA | XFS_USER_QUOTA)); |
954 | ASSERT((flags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) != 0); | 991 | ASSERT((flags & (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)) != |
992 | (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)); | ||
993 | ASSERT((flags & (XFS_USER_QUOTA | XFS_GROUP_QUOTA)) != | ||
994 | (XFS_USER_QUOTA | XFS_GROUP_QUOTA)); | ||
995 | ASSERT((flags & (XFS_PROJ_QUOTA|XFS_USER_QUOTA|XFS_GROUP_QUOTA)) != 0); | ||
955 | 996 | ||
956 | return (flags & XFS_DQ_USER) ? | 997 | return (flags & XFS_DQ_USER) ? |
957 | XFS_USER_QUOTA : XFS_GROUP_QUOTA; | 998 | XFS_USER_QUOTA : (flags & XFS_DQ_PROJ) ? |
999 | XFS_PROJ_QUOTA : XFS_GROUP_QUOTA; | ||
958 | } | 1000 | } |
959 | 1001 | ||
960 | STATIC uint | 1002 | STATIC uint |
@@ -965,12 +1007,14 @@ xfs_qm_import_flags( | |||
965 | 1007 | ||
966 | if (uflags & XFS_QUOTA_UDQ_ACCT) | 1008 | if (uflags & XFS_QUOTA_UDQ_ACCT) |
967 | flags |= XFS_UQUOTA_ACCT; | 1009 | flags |= XFS_UQUOTA_ACCT; |
1010 | if (uflags & XFS_QUOTA_PDQ_ACCT) | ||
1011 | flags |= XFS_PQUOTA_ACCT; | ||
968 | if (uflags & XFS_QUOTA_GDQ_ACCT) | 1012 | if (uflags & XFS_QUOTA_GDQ_ACCT) |
969 | flags |= XFS_GQUOTA_ACCT; | 1013 | flags |= XFS_GQUOTA_ACCT; |
970 | if (uflags & XFS_QUOTA_UDQ_ENFD) | 1014 | if (uflags & XFS_QUOTA_UDQ_ENFD) |
971 | flags |= XFS_UQUOTA_ENFD; | 1015 | flags |= XFS_UQUOTA_ENFD; |
972 | if (uflags & XFS_QUOTA_GDQ_ENFD) | 1016 | if (uflags & (XFS_QUOTA_PDQ_ENFD|XFS_QUOTA_GDQ_ENFD)) |
973 | flags |= XFS_GQUOTA_ENFD; | 1017 | flags |= XFS_OQUOTA_ENFD; |
974 | return (flags); | 1018 | return (flags); |
975 | } | 1019 | } |
976 | 1020 | ||
@@ -984,12 +1028,16 @@ xfs_qm_export_flags( | |||
984 | uflags = 0; | 1028 | uflags = 0; |
985 | if (flags & XFS_UQUOTA_ACCT) | 1029 | if (flags & XFS_UQUOTA_ACCT) |
986 | uflags |= XFS_QUOTA_UDQ_ACCT; | 1030 | uflags |= XFS_QUOTA_UDQ_ACCT; |
1031 | if (flags & XFS_PQUOTA_ACCT) | ||
1032 | uflags |= XFS_QUOTA_PDQ_ACCT; | ||
987 | if (flags & XFS_GQUOTA_ACCT) | 1033 | if (flags & XFS_GQUOTA_ACCT) |
988 | uflags |= XFS_QUOTA_GDQ_ACCT; | 1034 | uflags |= XFS_QUOTA_GDQ_ACCT; |
989 | if (flags & XFS_UQUOTA_ENFD) | 1035 | if (flags & XFS_UQUOTA_ENFD) |
990 | uflags |= XFS_QUOTA_UDQ_ENFD; | 1036 | uflags |= XFS_QUOTA_UDQ_ENFD; |
991 | if (flags & XFS_GQUOTA_ENFD) | 1037 | if (flags & (XFS_OQUOTA_ENFD)) { |
992 | uflags |= XFS_QUOTA_GDQ_ENFD; | 1038 | uflags |= (flags & XFS_GQUOTA_ACCT) ? |
1039 | XFS_QUOTA_GDQ_ENFD : XFS_QUOTA_PDQ_ENFD; | ||
1040 | } | ||
993 | return (uflags); | 1041 | return (uflags); |
994 | } | 1042 | } |
995 | 1043 | ||
@@ -1070,7 +1118,7 @@ again: | |||
1070 | xfs_qm_dqrele(ip->i_udquot); | 1118 | xfs_qm_dqrele(ip->i_udquot); |
1071 | ip->i_udquot = NULL; | 1119 | ip->i_udquot = NULL; |
1072 | } | 1120 | } |
1073 | if ((flags & XFS_GQUOTA_ACCT) && ip->i_gdquot) { | 1121 | if (flags & (XFS_PQUOTA_ACCT|XFS_GQUOTA_ACCT) && ip->i_gdquot) { |
1074 | xfs_qm_dqrele(ip->i_gdquot); | 1122 | xfs_qm_dqrele(ip->i_gdquot); |
1075 | ip->i_gdquot = NULL; | 1123 | ip->i_gdquot = NULL; |
1076 | } | 1124 | } |
@@ -1160,7 +1208,6 @@ xfs_qm_dqtest_print( | |||
1160 | { | 1208 | { |
1161 | cmn_err(CE_DEBUG, "-----------DQTEST DQUOT----------------"); | 1209 | cmn_err(CE_DEBUG, "-----------DQTEST DQUOT----------------"); |
1162 | cmn_err(CE_DEBUG, "---- dquot ID = %d", d->d_id); | 1210 | cmn_err(CE_DEBUG, "---- dquot ID = %d", d->d_id); |
1163 | cmn_err(CE_DEBUG, "---- type = %s", XFS_QM_ISUDQ(d)? "USR" : "GRP"); | ||
1164 | cmn_err(CE_DEBUG, "---- fs = 0x%p", d->q_mount); | 1211 | cmn_err(CE_DEBUG, "---- fs = 0x%p", d->q_mount); |
1165 | cmn_err(CE_DEBUG, "---- bcount = %Lu (0x%x)", | 1212 | cmn_err(CE_DEBUG, "---- bcount = %Lu (0x%x)", |
1166 | d->d_bcount, (int)d->d_bcount); | 1213 | d->d_bcount, (int)d->d_bcount); |
@@ -1231,7 +1278,7 @@ xfs_dqtest_cmp2( | |||
1231 | #ifdef QUOTADEBUG | 1278 | #ifdef QUOTADEBUG |
1232 | if (!err) { | 1279 | if (!err) { |
1233 | cmn_err(CE_DEBUG, "%d [%s] [0x%p] qchecked", | 1280 | cmn_err(CE_DEBUG, "%d [%s] [0x%p] qchecked", |
1234 | d->d_id, XFS_QM_ISUDQ(d) ? "USR" : "GRP", d->q_mount); | 1281 | d->d_id, DQFLAGTO_TYPESTR(d), d->q_mount); |
1235 | } | 1282 | } |
1236 | #endif | 1283 | #endif |
1237 | return (err); | 1284 | return (err); |
@@ -1287,6 +1334,7 @@ STATIC void | |||
1287 | xfs_qm_internalqcheck_get_dquots( | 1334 | xfs_qm_internalqcheck_get_dquots( |
1288 | xfs_mount_t *mp, | 1335 | xfs_mount_t *mp, |
1289 | xfs_dqid_t uid, | 1336 | xfs_dqid_t uid, |
1337 | xfs_dqid_t projid, | ||
1290 | xfs_dqid_t gid, | 1338 | xfs_dqid_t gid, |
1291 | xfs_dqtest_t **ud, | 1339 | xfs_dqtest_t **ud, |
1292 | xfs_dqtest_t **gd) | 1340 | xfs_dqtest_t **gd) |
@@ -1295,6 +1343,8 @@ xfs_qm_internalqcheck_get_dquots( | |||
1295 | xfs_qm_internalqcheck_dqget(mp, uid, XFS_DQ_USER, ud); | 1343 | xfs_qm_internalqcheck_dqget(mp, uid, XFS_DQ_USER, ud); |
1296 | if (XFS_IS_GQUOTA_ON(mp)) | 1344 | if (XFS_IS_GQUOTA_ON(mp)) |
1297 | xfs_qm_internalqcheck_dqget(mp, gid, XFS_DQ_GROUP, gd); | 1345 | xfs_qm_internalqcheck_dqget(mp, gid, XFS_DQ_GROUP, gd); |
1346 | else if (XFS_IS_PQUOTA_ON(mp)) | ||
1347 | xfs_qm_internalqcheck_dqget(mp, projid, XFS_DQ_PROJ, gd); | ||
1298 | } | 1348 | } |
1299 | 1349 | ||
1300 | 1350 | ||
@@ -1362,13 +1412,14 @@ xfs_qm_internalqcheck_adjust( | |||
1362 | } | 1412 | } |
1363 | xfs_qm_internalqcheck_get_dquots(mp, | 1413 | xfs_qm_internalqcheck_get_dquots(mp, |
1364 | (xfs_dqid_t) ip->i_d.di_uid, | 1414 | (xfs_dqid_t) ip->i_d.di_uid, |
1415 | (xfs_dqid_t) ip->i_d.di_projid, | ||
1365 | (xfs_dqid_t) ip->i_d.di_gid, | 1416 | (xfs_dqid_t) ip->i_d.di_gid, |
1366 | &ud, &gd); | 1417 | &ud, &gd); |
1367 | if (XFS_IS_UQUOTA_ON(mp)) { | 1418 | if (XFS_IS_UQUOTA_ON(mp)) { |
1368 | ASSERT(ud); | 1419 | ASSERT(ud); |
1369 | xfs_qm_internalqcheck_dqadjust(ip, ud); | 1420 | xfs_qm_internalqcheck_dqadjust(ip, ud); |
1370 | } | 1421 | } |
1371 | if (XFS_IS_GQUOTA_ON(mp)) { | 1422 | if (XFS_IS_OQUOTA_ON(mp)) { |
1372 | ASSERT(gd); | 1423 | ASSERT(gd); |
1373 | xfs_qm_internalqcheck_dqadjust(ip, gd); | 1424 | xfs_qm_internalqcheck_dqadjust(ip, gd); |
1374 | } | 1425 | } |
diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h index 414b6004af21..bf413e70ec07 100644 --- a/fs/xfs/quota/xfs_quota_priv.h +++ b/fs/xfs/quota/xfs_quota_priv.h | |||
@@ -56,6 +56,7 @@ | |||
56 | #define XFS_QI_RTBTIMELIMIT(mp) ((mp)->m_quotainfo->qi_rtbtimelimit) | 56 | #define XFS_QI_RTBTIMELIMIT(mp) ((mp)->m_quotainfo->qi_rtbtimelimit) |
57 | #define XFS_QI_ITIMELIMIT(mp) ((mp)->m_quotainfo->qi_itimelimit) | 57 | #define XFS_QI_ITIMELIMIT(mp) ((mp)->m_quotainfo->qi_itimelimit) |
58 | #define XFS_QI_BWARNLIMIT(mp) ((mp)->m_quotainfo->qi_bwarnlimit) | 58 | #define XFS_QI_BWARNLIMIT(mp) ((mp)->m_quotainfo->qi_bwarnlimit) |
59 | #define XFS_QI_RTBWARNLIMIT(mp) ((mp)->m_quotainfo->qi_rtbwarnlimit) | ||
59 | #define XFS_QI_IWARNLIMIT(mp) ((mp)->m_quotainfo->qi_iwarnlimit) | 60 | #define XFS_QI_IWARNLIMIT(mp) ((mp)->m_quotainfo->qi_iwarnlimit) |
60 | #define XFS_QI_QOFFLOCK(mp) ((mp)->m_quotainfo->qi_quotaofflock) | 61 | #define XFS_QI_QOFFLOCK(mp) ((mp)->m_quotainfo->qi_quotaofflock) |
61 | 62 | ||
@@ -102,7 +103,8 @@ static inline int XQMISLCKD(struct xfs_dqhash *h) | |||
102 | (xfs_Gqm->qm_grp_dqhtable + \ | 103 | (xfs_Gqm->qm_grp_dqhtable + \ |
103 | XFS_DQ_HASHVAL(mp, id))) | 104 | XFS_DQ_HASHVAL(mp, id))) |
104 | #define XFS_IS_DQTYPE_ON(mp, type) (type == XFS_DQ_USER ? \ | 105 | #define XFS_IS_DQTYPE_ON(mp, type) (type == XFS_DQ_USER ? \ |
105 | XFS_IS_UQUOTA_ON(mp):XFS_IS_GQUOTA_ON(mp)) | 106 | XFS_IS_UQUOTA_ON(mp) : \ |
107 | XFS_IS_OQUOTA_ON(mp)) | ||
106 | #define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \ | 108 | #define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \ |
107 | !dqp->q_core.d_blk_hardlimit && \ | 109 | !dqp->q_core.d_blk_hardlimit && \ |
108 | !dqp->q_core.d_blk_softlimit && \ | 110 | !dqp->q_core.d_blk_softlimit && \ |
@@ -177,16 +179,11 @@ for ((dqp) = (qlist)->qh_next; (dqp) != (xfs_dquot_t *)(qlist); \ | |||
177 | (!((dqp)->q_core.d_id)) | 179 | (!((dqp)->q_core.d_id)) |
178 | 180 | ||
179 | #define XFS_PURGE_INODE(ip) \ | 181 | #define XFS_PURGE_INODE(ip) \ |
180 | { \ | 182 | IRELE(ip); |
181 | vmap_t dqvmap; \ | ||
182 | vnode_t *dqvp; \ | ||
183 | dqvp = XFS_ITOV(ip); \ | ||
184 | VMAP(dqvp, dqvmap); \ | ||
185 | VN_RELE(dqvp); \ | ||
186 | } | ||
187 | 183 | ||
188 | #define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \ | 184 | #define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \ |
189 | (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : "???")) | 185 | (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : \ |
186 | (((d)->dq_flags & XFS_DQ_PROJ) ? "PRJ":"???"))) | ||
190 | #define DQFLAGTO_DIRTYSTR(d) (XFS_DQ_IS_DIRTY(d) ? "DIRTY" : "NOTDIRTY") | 187 | #define DQFLAGTO_DIRTYSTR(d) (XFS_DQ_IS_DIRTY(d) ? "DIRTY" : "NOTDIRTY") |
191 | 188 | ||
192 | #endif /* __XFS_QUOTA_PRIV_H__ */ | 189 | #endif /* __XFS_QUOTA_PRIV_H__ */ |
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c index 149b2a1fd949..3b99daf8a640 100644 --- a/fs/xfs/quota/xfs_trans_dquot.c +++ b/fs/xfs/quota/xfs_trans_dquot.c | |||
@@ -187,7 +187,7 @@ xfs_trans_dup_dqinfo( | |||
187 | /* | 187 | /* |
188 | * Wrap around mod_dquot to account for both user and group quotas. | 188 | * Wrap around mod_dquot to account for both user and group quotas. |
189 | */ | 189 | */ |
190 | void | 190 | STATIC void |
191 | xfs_trans_mod_dquot_byino( | 191 | xfs_trans_mod_dquot_byino( |
192 | xfs_trans_t *tp, | 192 | xfs_trans_t *tp, |
193 | xfs_inode_t *ip, | 193 | xfs_inode_t *ip, |
@@ -207,12 +207,10 @@ xfs_trans_mod_dquot_byino( | |||
207 | if (tp->t_dqinfo == NULL) | 207 | if (tp->t_dqinfo == NULL) |
208 | xfs_trans_alloc_dqinfo(tp); | 208 | xfs_trans_alloc_dqinfo(tp); |
209 | 209 | ||
210 | if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot) { | 210 | if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot) |
211 | (void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta); | 211 | (void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta); |
212 | } | 212 | if (XFS_IS_OQUOTA_ON(mp) && ip->i_gdquot) |
213 | if (XFS_IS_GQUOTA_ON(mp) && ip->i_gdquot) { | ||
214 | (void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta); | 213 | (void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta); |
215 | } | ||
216 | } | 214 | } |
217 | 215 | ||
218 | STATIC xfs_dqtrx_t * | 216 | STATIC xfs_dqtrx_t * |
@@ -368,7 +366,7 @@ xfs_trans_dqlockedjoin( | |||
368 | * Unreserve just the reservations done by this transaction. | 366 | * Unreserve just the reservations done by this transaction. |
369 | * dquot is still left locked at exit. | 367 | * dquot is still left locked at exit. |
370 | */ | 368 | */ |
371 | void | 369 | STATIC void |
372 | xfs_trans_apply_dquot_deltas( | 370 | xfs_trans_apply_dquot_deltas( |
373 | xfs_trans_t *tp) | 371 | xfs_trans_t *tp) |
374 | { | 372 | { |
@@ -499,7 +497,7 @@ xfs_trans_apply_dquot_deltas( | |||
499 | * Adjust the RT reservation. | 497 | * Adjust the RT reservation. |
500 | */ | 498 | */ |
501 | if (qtrx->qt_rtblk_res != 0) { | 499 | if (qtrx->qt_rtblk_res != 0) { |
502 | if (qtrx->qt_blk_res != qtrx->qt_blk_res_used) { | 500 | if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) { |
503 | if (qtrx->qt_rtblk_res > | 501 | if (qtrx->qt_rtblk_res > |
504 | qtrx->qt_rtblk_res_used) | 502 | qtrx->qt_rtblk_res_used) |
505 | dqp->q_res_rtbcount -= (xfs_qcnt_t) | 503 | dqp->q_res_rtbcount -= (xfs_qcnt_t) |
@@ -532,12 +530,6 @@ xfs_trans_apply_dquot_deltas( | |||
532 | (xfs_qcnt_t)qtrx->qt_icount_delta; | 530 | (xfs_qcnt_t)qtrx->qt_icount_delta; |
533 | } | 531 | } |
534 | 532 | ||
535 | |||
536 | #ifdef QUOTADEBUG | ||
537 | if (qtrx->qt_rtblk_res != 0) | ||
538 | cmn_err(CE_DEBUG, "RT res %d for 0x%p\n", | ||
539 | (int) qtrx->qt_rtblk_res, dqp); | ||
540 | #endif | ||
541 | ASSERT(dqp->q_res_bcount >= | 533 | ASSERT(dqp->q_res_bcount >= |
542 | INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT)); | 534 | INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT)); |
543 | ASSERT(dqp->q_res_icount >= | 535 | ASSERT(dqp->q_res_icount >= |
@@ -638,7 +630,10 @@ xfs_trans_dqresv( | |||
638 | int error; | 630 | int error; |
639 | xfs_qcnt_t hardlimit; | 631 | xfs_qcnt_t hardlimit; |
640 | xfs_qcnt_t softlimit; | 632 | xfs_qcnt_t softlimit; |
641 | time_t btimer; | 633 | time_t timer; |
634 | xfs_qwarncnt_t warns; | ||
635 | xfs_qwarncnt_t warnlimit; | ||
636 | xfs_qcnt_t count; | ||
642 | xfs_qcnt_t *resbcountp; | 637 | xfs_qcnt_t *resbcountp; |
643 | xfs_quotainfo_t *q = mp->m_quotainfo; | 638 | xfs_quotainfo_t *q = mp->m_quotainfo; |
644 | 639 | ||
@@ -653,7 +648,9 @@ xfs_trans_dqresv( | |||
653 | softlimit = INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT); | 648 | softlimit = INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT); |
654 | if (!softlimit) | 649 | if (!softlimit) |
655 | softlimit = q->qi_bsoftlimit; | 650 | softlimit = q->qi_bsoftlimit; |
656 | btimer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT); | 651 | timer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT); |
652 | warns = INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT); | ||
653 | warnlimit = XFS_QI_BWARNLIMIT(dqp->q_mount); | ||
657 | resbcountp = &dqp->q_res_bcount; | 654 | resbcountp = &dqp->q_res_bcount; |
658 | } else { | 655 | } else { |
659 | ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); | 656 | ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); |
@@ -663,7 +660,9 @@ xfs_trans_dqresv( | |||
663 | softlimit = INT_GET(dqp->q_core.d_rtb_softlimit, ARCH_CONVERT); | 660 | softlimit = INT_GET(dqp->q_core.d_rtb_softlimit, ARCH_CONVERT); |
664 | if (!softlimit) | 661 | if (!softlimit) |
665 | softlimit = q->qi_rtbsoftlimit; | 662 | softlimit = q->qi_rtbsoftlimit; |
666 | btimer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT); | 663 | timer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT); |
664 | warns = INT_GET(dqp->q_core.d_rtbwarns, ARCH_CONVERT); | ||
665 | warnlimit = XFS_QI_RTBWARNLIMIT(dqp->q_mount); | ||
667 | resbcountp = &dqp->q_res_rtbcount; | 666 | resbcountp = &dqp->q_res_rtbcount; |
668 | } | 667 | } |
669 | error = 0; | 668 | error = 0; |
@@ -693,37 +692,36 @@ xfs_trans_dqresv( | |||
693 | * If timer or warnings has expired, | 692 | * If timer or warnings has expired, |
694 | * return EDQUOT | 693 | * return EDQUOT |
695 | */ | 694 | */ |
696 | if ((btimer != 0 && get_seconds() > btimer) || | 695 | if ((timer != 0 && get_seconds() > timer) || |
697 | (dqp->q_core.d_bwarns && | 696 | (warns != 0 && warns >= warnlimit)) { |
698 | INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT) >= | ||
699 | XFS_QI_BWARNLIMIT(dqp->q_mount))) { | ||
700 | error = EDQUOT; | 697 | error = EDQUOT; |
701 | goto error_return; | 698 | goto error_return; |
702 | } | 699 | } |
703 | } | 700 | } |
704 | } | 701 | } |
705 | if (ninos > 0) { | 702 | if (ninos > 0) { |
706 | hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT); | 703 | count = INT_GET(dqp->q_core.d_icount, ARCH_CONVERT); |
704 | timer = INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT); | ||
705 | warns = INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT); | ||
706 | warnlimit = XFS_QI_IWARNLIMIT(dqp->q_mount); | ||
707 | hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit, | ||
708 | ARCH_CONVERT); | ||
707 | if (!hardlimit) | 709 | if (!hardlimit) |
708 | hardlimit = q->qi_ihardlimit; | 710 | hardlimit = q->qi_ihardlimit; |
709 | softlimit = INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT); | 711 | softlimit = INT_GET(dqp->q_core.d_ino_softlimit, |
712 | ARCH_CONVERT); | ||
710 | if (!softlimit) | 713 | if (!softlimit) |
711 | softlimit = q->qi_isoftlimit; | 714 | softlimit = q->qi_isoftlimit; |
712 | if (hardlimit > 0ULL && | 715 | if (hardlimit > 0ULL && count >= hardlimit) { |
713 | INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= hardlimit) { | ||
714 | error = EDQUOT; | 716 | error = EDQUOT; |
715 | goto error_return; | 717 | goto error_return; |
716 | } else if (softlimit > 0ULL && | 718 | } else if (softlimit > 0ULL && count >= softlimit) { |
717 | INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= softlimit) { | ||
718 | /* | 719 | /* |
719 | * If timer or warnings has expired, | 720 | * If timer or warnings has expired, |
720 | * return EDQUOT | 721 | * return EDQUOT |
721 | */ | 722 | */ |
722 | if ((dqp->q_core.d_itimer && | 723 | if ((timer != 0 && get_seconds() > timer) || |
723 | get_seconds() > INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT)) || | 724 | (warns != 0 && warns >= warnlimit)) { |
724 | (dqp->q_core.d_iwarns && | ||
725 | INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT) >= | ||
726 | XFS_QI_IWARNLIMIT(dqp->q_mount))) { | ||
727 | error = EDQUOT; | 725 | error = EDQUOT; |
728 | goto error_return; | 726 | goto error_return; |
729 | } | 727 | } |