diff options
Diffstat (limited to 'fs/xfs/quota')
-rw-r--r-- | fs/xfs/quota/xfs_qm.c | 34 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm.h | 6 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_quota_priv.h | 1 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_trans_dquot.c | 50 |
4 files changed, 48 insertions, 43 deletions
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 3ea75972767c..3254cb7b87f4 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
@@ -1251,6 +1251,10 @@ xfs_qm_init_quotainfo( | |||
1251 | INT_GET(ddqp->d_iwarns, ARCH_CONVERT) ? | 1251 | INT_GET(ddqp->d_iwarns, ARCH_CONVERT) ? |
1252 | INT_GET(ddqp->d_iwarns, ARCH_CONVERT) : | 1252 | INT_GET(ddqp->d_iwarns, ARCH_CONVERT) : |
1253 | 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; | ||
1254 | qinf->qi_bhardlimit = | 1258 | qinf->qi_bhardlimit = |
1255 | INT_GET(ddqp->d_blk_hardlimit, ARCH_CONVERT); | 1259 | INT_GET(ddqp->d_blk_hardlimit, ARCH_CONVERT); |
1256 | qinf->qi_bsoftlimit = | 1260 | qinf->qi_bsoftlimit = |
@@ -1276,6 +1280,7 @@ xfs_qm_init_quotainfo( | |||
1276 | qinf->qi_rtbtimelimit = XFS_QM_RTBTIMELIMIT; | 1280 | qinf->qi_rtbtimelimit = XFS_QM_RTBTIMELIMIT; |
1277 | qinf->qi_bwarnlimit = XFS_QM_BWARNLIMIT; | 1281 | qinf->qi_bwarnlimit = XFS_QM_BWARNLIMIT; |
1278 | qinf->qi_iwarnlimit = XFS_QM_IWARNLIMIT; | 1282 | qinf->qi_iwarnlimit = XFS_QM_IWARNLIMIT; |
1283 | qinf->qi_rtbwarnlimit = XFS_QM_RTBWARNLIMIT; | ||
1279 | } | 1284 | } |
1280 | 1285 | ||
1281 | return (0); | 1286 | return (0); |
@@ -2624,6 +2629,9 @@ xfs_qm_vop_chown( | |||
2624 | xfs_dquot_t *newdq) | 2629 | xfs_dquot_t *newdq) |
2625 | { | 2630 | { |
2626 | xfs_dquot_t *prevdq; | 2631 | xfs_dquot_t *prevdq; |
2632 | uint bfield = XFS_IS_REALTIME_INODE(ip) ? | ||
2633 | XFS_TRANS_DQ_RTBCOUNT : XFS_TRANS_DQ_BCOUNT; | ||
2634 | |||
2627 | ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); | 2635 | ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); |
2628 | ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount)); | 2636 | ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount)); |
2629 | 2637 | ||
@@ -2632,20 +2640,12 @@ xfs_qm_vop_chown( | |||
2632 | ASSERT(prevdq); | 2640 | ASSERT(prevdq); |
2633 | ASSERT(prevdq != newdq); | 2641 | ASSERT(prevdq != newdq); |
2634 | 2642 | ||
2635 | xfs_trans_mod_dquot(tp, prevdq, | 2643 | xfs_trans_mod_dquot(tp, prevdq, bfield, -(ip->i_d.di_nblocks)); |
2636 | XFS_TRANS_DQ_BCOUNT, | 2644 | xfs_trans_mod_dquot(tp, prevdq, XFS_TRANS_DQ_ICOUNT, -1); |
2637 | -(ip->i_d.di_nblocks)); | ||
2638 | xfs_trans_mod_dquot(tp, prevdq, | ||
2639 | XFS_TRANS_DQ_ICOUNT, | ||
2640 | -1); | ||
2641 | 2645 | ||
2642 | /* the sparkling new dquot */ | 2646 | /* the sparkling new dquot */ |
2643 | xfs_trans_mod_dquot(tp, newdq, | 2647 | xfs_trans_mod_dquot(tp, newdq, bfield, ip->i_d.di_nblocks); |
2644 | XFS_TRANS_DQ_BCOUNT, | 2648 | xfs_trans_mod_dquot(tp, newdq, XFS_TRANS_DQ_ICOUNT, 1); |
2645 | ip->i_d.di_nblocks); | ||
2646 | xfs_trans_mod_dquot(tp, newdq, | ||
2647 | XFS_TRANS_DQ_ICOUNT, | ||
2648 | 1); | ||
2649 | 2649 | ||
2650 | /* | 2650 | /* |
2651 | * Take an extra reference, because the inode | 2651 | * Take an extra reference, because the inode |
@@ -2673,7 +2673,7 @@ xfs_qm_vop_chown_reserve( | |||
2673 | { | 2673 | { |
2674 | int error; | 2674 | int error; |
2675 | xfs_mount_t *mp; | 2675 | xfs_mount_t *mp; |
2676 | uint delblks; | 2676 | uint delblks, blkflags; |
2677 | xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq; | 2677 | xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq; |
2678 | 2678 | ||
2679 | ASSERT(XFS_ISLOCKED_INODE(ip)); | 2679 | ASSERT(XFS_ISLOCKED_INODE(ip)); |
@@ -2682,6 +2682,8 @@ xfs_qm_vop_chown_reserve( | |||
2682 | 2682 | ||
2683 | delblks = ip->i_delayed_blks; | 2683 | delblks = ip->i_delayed_blks; |
2684 | delblksudq = delblksgdq = unresudq = unresgdq = NULL; | 2684 | delblksudq = delblksgdq = unresudq = unresgdq = NULL; |
2685 | blkflags = XFS_IS_REALTIME_INODE(ip) ? | ||
2686 | XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS; | ||
2685 | 2687 | ||
2686 | if (XFS_IS_UQUOTA_ON(mp) && udqp && | 2688 | if (XFS_IS_UQUOTA_ON(mp) && udqp && |
2687 | ip->i_d.di_uid != (uid_t)INT_GET(udqp->q_core.d_id, ARCH_CONVERT)) { | 2689 | ip->i_d.di_uid != (uid_t)INT_GET(udqp->q_core.d_id, ARCH_CONVERT)) { |
@@ -2711,7 +2713,7 @@ xfs_qm_vop_chown_reserve( | |||
2711 | 2713 | ||
2712 | if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount, | 2714 | if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount, |
2713 | delblksudq, delblksgdq, ip->i_d.di_nblocks, 1, | 2715 | delblksudq, delblksgdq, ip->i_d.di_nblocks, 1, |
2714 | flags | XFS_QMOPT_RES_REGBLKS))) | 2716 | flags | blkflags))) |
2715 | return (error); | 2717 | return (error); |
2716 | 2718 | ||
2717 | /* | 2719 | /* |
@@ -2728,11 +2730,11 @@ xfs_qm_vop_chown_reserve( | |||
2728 | ASSERT(unresudq || unresgdq); | 2730 | ASSERT(unresudq || unresgdq); |
2729 | if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, | 2731 | if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, |
2730 | delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0, | 2732 | delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0, |
2731 | flags | XFS_QMOPT_RES_REGBLKS))) | 2733 | flags | blkflags))) |
2732 | return (error); | 2734 | return (error); |
2733 | xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, | 2735 | xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, |
2734 | unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0, | 2736 | unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0, |
2735 | XFS_QMOPT_RES_REGBLKS); | 2737 | blkflags); |
2736 | } | 2738 | } |
2737 | 2739 | ||
2738 | return (0); | 2740 | return (0); |
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h index 781968779540..b03eecf3b6cb 100644 --- a/fs/xfs/quota/xfs_qm.h +++ b/fs/xfs/quota/xfs_qm.h | |||
@@ -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)) |
diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h index 472afd3570c6..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 | ||
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c index 565efb73c233..3b99daf8a640 100644 --- a/fs/xfs/quota/xfs_trans_dquot.c +++ b/fs/xfs/quota/xfs_trans_dquot.c | |||
@@ -497,7 +497,7 @@ xfs_trans_apply_dquot_deltas( | |||
497 | * Adjust the RT reservation. | 497 | * Adjust the RT reservation. |
498 | */ | 498 | */ |
499 | if (qtrx->qt_rtblk_res != 0) { | 499 | if (qtrx->qt_rtblk_res != 0) { |
500 | if (qtrx->qt_blk_res != qtrx->qt_blk_res_used) { | 500 | if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) { |
501 | if (qtrx->qt_rtblk_res > | 501 | if (qtrx->qt_rtblk_res > |
502 | qtrx->qt_rtblk_res_used) | 502 | qtrx->qt_rtblk_res_used) |
503 | dqp->q_res_rtbcount -= (xfs_qcnt_t) | 503 | dqp->q_res_rtbcount -= (xfs_qcnt_t) |
@@ -530,12 +530,6 @@ xfs_trans_apply_dquot_deltas( | |||
530 | (xfs_qcnt_t)qtrx->qt_icount_delta; | 530 | (xfs_qcnt_t)qtrx->qt_icount_delta; |
531 | } | 531 | } |
532 | 532 | ||
533 | |||
534 | #ifdef QUOTADEBUG | ||
535 | if (qtrx->qt_rtblk_res != 0) | ||
536 | cmn_err(CE_DEBUG, "RT res %d for 0x%p\n", | ||
537 | (int) qtrx->qt_rtblk_res, dqp); | ||
538 | #endif | ||
539 | ASSERT(dqp->q_res_bcount >= | 533 | ASSERT(dqp->q_res_bcount >= |
540 | INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT)); | 534 | INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT)); |
541 | ASSERT(dqp->q_res_icount >= | 535 | ASSERT(dqp->q_res_icount >= |
@@ -636,7 +630,10 @@ xfs_trans_dqresv( | |||
636 | int error; | 630 | int error; |
637 | xfs_qcnt_t hardlimit; | 631 | xfs_qcnt_t hardlimit; |
638 | xfs_qcnt_t softlimit; | 632 | xfs_qcnt_t softlimit; |
639 | time_t btimer; | 633 | time_t timer; |
634 | xfs_qwarncnt_t warns; | ||
635 | xfs_qwarncnt_t warnlimit; | ||
636 | xfs_qcnt_t count; | ||
640 | xfs_qcnt_t *resbcountp; | 637 | xfs_qcnt_t *resbcountp; |
641 | xfs_quotainfo_t *q = mp->m_quotainfo; | 638 | xfs_quotainfo_t *q = mp->m_quotainfo; |
642 | 639 | ||
@@ -651,7 +648,9 @@ xfs_trans_dqresv( | |||
651 | softlimit = INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT); | 648 | softlimit = INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT); |
652 | if (!softlimit) | 649 | if (!softlimit) |
653 | softlimit = q->qi_bsoftlimit; | 650 | softlimit = q->qi_bsoftlimit; |
654 | 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); | ||
655 | resbcountp = &dqp->q_res_bcount; | 654 | resbcountp = &dqp->q_res_bcount; |
656 | } else { | 655 | } else { |
657 | ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); | 656 | ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); |
@@ -661,7 +660,9 @@ xfs_trans_dqresv( | |||
661 | softlimit = INT_GET(dqp->q_core.d_rtb_softlimit, ARCH_CONVERT); | 660 | softlimit = INT_GET(dqp->q_core.d_rtb_softlimit, ARCH_CONVERT); |
662 | if (!softlimit) | 661 | if (!softlimit) |
663 | softlimit = q->qi_rtbsoftlimit; | 662 | softlimit = q->qi_rtbsoftlimit; |
664 | 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); | ||
665 | resbcountp = &dqp->q_res_rtbcount; | 666 | resbcountp = &dqp->q_res_rtbcount; |
666 | } | 667 | } |
667 | error = 0; | 668 | error = 0; |
@@ -691,37 +692,36 @@ xfs_trans_dqresv( | |||
691 | * If timer or warnings has expired, | 692 | * If timer or warnings has expired, |
692 | * return EDQUOT | 693 | * return EDQUOT |
693 | */ | 694 | */ |
694 | if ((btimer != 0 && get_seconds() > btimer) || | 695 | if ((timer != 0 && get_seconds() > timer) || |
695 | (dqp->q_core.d_bwarns && | 696 | (warns != 0 && warns >= warnlimit)) { |
696 | INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT) >= | ||
697 | XFS_QI_BWARNLIMIT(dqp->q_mount))) { | ||
698 | error = EDQUOT; | 697 | error = EDQUOT; |
699 | goto error_return; | 698 | goto error_return; |
700 | } | 699 | } |
701 | } | 700 | } |
702 | } | 701 | } |
703 | if (ninos > 0) { | 702 | if (ninos > 0) { |
704 | 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); | ||
705 | if (!hardlimit) | 709 | if (!hardlimit) |
706 | hardlimit = q->qi_ihardlimit; | 710 | hardlimit = q->qi_ihardlimit; |
707 | softlimit = INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT); | 711 | softlimit = INT_GET(dqp->q_core.d_ino_softlimit, |
712 | ARCH_CONVERT); | ||
708 | if (!softlimit) | 713 | if (!softlimit) |
709 | softlimit = q->qi_isoftlimit; | 714 | softlimit = q->qi_isoftlimit; |
710 | if (hardlimit > 0ULL && | 715 | if (hardlimit > 0ULL && count >= hardlimit) { |
711 | INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= hardlimit) { | ||
712 | error = EDQUOT; | 716 | error = EDQUOT; |
713 | goto error_return; | 717 | goto error_return; |
714 | } else if (softlimit > 0ULL && | 718 | } else if (softlimit > 0ULL && count >= softlimit) { |
715 | INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= softlimit) { | ||
716 | /* | 719 | /* |
717 | * If timer or warnings has expired, | 720 | * If timer or warnings has expired, |
718 | * return EDQUOT | 721 | * return EDQUOT |
719 | */ | 722 | */ |
720 | if ((dqp->q_core.d_itimer && | 723 | if ((timer != 0 && get_seconds() > timer) || |
721 | get_seconds() > INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT)) || | 724 | (warns != 0 && warns >= warnlimit)) { |
722 | (dqp->q_core.d_iwarns && | ||
723 | INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT) >= | ||
724 | XFS_QI_IWARNLIMIT(dqp->q_mount))) { | ||
725 | error = EDQUOT; | 725 | error = EDQUOT; |
726 | goto error_return; | 726 | goto error_return; |
727 | } | 727 | } |