Commit 06d10dd9ca70ff1318ff2b871ff5f61a94223d9f
1 parent
77bc5beb59
Exists in
master
and in
7 other branches
[XFS] Merge fixes into realtime quota code, since one/two reported, still
not enabled though. SGI-PV: 938145 SGI-Modid: xfs-linux:xfs-kern:22900a Signed-off-by: Nathan Scott <nathans@sgi.com>
Showing 8 changed files with 143 additions and 141 deletions Side-by-side Diff
fs/xfs/quota/xfs_qm.c
... | ... | @@ -1251,6 +1251,10 @@ |
1251 | 1251 | INT_GET(ddqp->d_iwarns, ARCH_CONVERT) ? |
1252 | 1252 | INT_GET(ddqp->d_iwarns, ARCH_CONVERT) : |
1253 | 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 | 1258 | qinf->qi_bhardlimit = |
1255 | 1259 | INT_GET(ddqp->d_blk_hardlimit, ARCH_CONVERT); |
1256 | 1260 | qinf->qi_bsoftlimit = |
... | ... | @@ -1276,6 +1280,7 @@ |
1276 | 1280 | qinf->qi_rtbtimelimit = XFS_QM_RTBTIMELIMIT; |
1277 | 1281 | qinf->qi_bwarnlimit = XFS_QM_BWARNLIMIT; |
1278 | 1282 | qinf->qi_iwarnlimit = XFS_QM_IWARNLIMIT; |
1283 | + qinf->qi_rtbwarnlimit = XFS_QM_RTBWARNLIMIT; | |
1279 | 1284 | } |
1280 | 1285 | |
1281 | 1286 | return (0); |
... | ... | @@ -2624,6 +2629,9 @@ |
2624 | 2629 | xfs_dquot_t *newdq) |
2625 | 2630 | { |
2626 | 2631 | xfs_dquot_t *prevdq; |
2632 | + uint bfield = XFS_IS_REALTIME_INODE(ip) ? | |
2633 | + XFS_TRANS_DQ_RTBCOUNT : XFS_TRANS_DQ_BCOUNT; | |
2634 | + | |
2627 | 2635 | ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); |
2628 | 2636 | ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount)); |
2629 | 2637 | |
2630 | 2638 | |
... | ... | @@ -2632,20 +2640,12 @@ |
2632 | 2640 | ASSERT(prevdq); |
2633 | 2641 | ASSERT(prevdq != newdq); |
2634 | 2642 | |
2635 | - xfs_trans_mod_dquot(tp, prevdq, | |
2636 | - XFS_TRANS_DQ_BCOUNT, | |
2637 | - -(ip->i_d.di_nblocks)); | |
2638 | - xfs_trans_mod_dquot(tp, prevdq, | |
2639 | - XFS_TRANS_DQ_ICOUNT, | |
2640 | - -1); | |
2643 | + xfs_trans_mod_dquot(tp, prevdq, bfield, -(ip->i_d.di_nblocks)); | |
2644 | + xfs_trans_mod_dquot(tp, prevdq, XFS_TRANS_DQ_ICOUNT, -1); | |
2641 | 2645 | |
2642 | 2646 | /* the sparkling new dquot */ |
2643 | - xfs_trans_mod_dquot(tp, newdq, | |
2644 | - XFS_TRANS_DQ_BCOUNT, | |
2645 | - ip->i_d.di_nblocks); | |
2646 | - xfs_trans_mod_dquot(tp, newdq, | |
2647 | - XFS_TRANS_DQ_ICOUNT, | |
2648 | - 1); | |
2647 | + xfs_trans_mod_dquot(tp, newdq, bfield, ip->i_d.di_nblocks); | |
2648 | + xfs_trans_mod_dquot(tp, newdq, XFS_TRANS_DQ_ICOUNT, 1); | |
2649 | 2649 | |
2650 | 2650 | /* |
2651 | 2651 | * Take an extra reference, because the inode |
... | ... | @@ -2673,7 +2673,7 @@ |
2673 | 2673 | { |
2674 | 2674 | int error; |
2675 | 2675 | xfs_mount_t *mp; |
2676 | - uint delblks; | |
2676 | + uint delblks, blkflags; | |
2677 | 2677 | xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq; |
2678 | 2678 | |
2679 | 2679 | ASSERT(XFS_ISLOCKED_INODE(ip)); |
... | ... | @@ -2682,6 +2682,8 @@ |
2682 | 2682 | |
2683 | 2683 | delblks = ip->i_delayed_blks; |
2684 | 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 | 2688 | if (XFS_IS_UQUOTA_ON(mp) && udqp && |
2687 | 2689 | ip->i_d.di_uid != (uid_t)INT_GET(udqp->q_core.d_id, ARCH_CONVERT)) { |
... | ... | @@ -2711,7 +2713,7 @@ |
2711 | 2713 | |
2712 | 2714 | if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount, |
2713 | 2715 | delblksudq, delblksgdq, ip->i_d.di_nblocks, 1, |
2714 | - flags | XFS_QMOPT_RES_REGBLKS))) | |
2716 | + flags | blkflags))) | |
2715 | 2717 | return (error); |
2716 | 2718 | |
2717 | 2719 | /* |
2718 | 2720 | |
... | ... | @@ -2728,11 +2730,11 @@ |
2728 | 2730 | ASSERT(unresudq || unresgdq); |
2729 | 2731 | if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, |
2730 | 2732 | delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0, |
2731 | - flags | XFS_QMOPT_RES_REGBLKS))) | |
2733 | + flags | blkflags))) | |
2732 | 2734 | return (error); |
2733 | 2735 | xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, |
2734 | 2736 | unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0, |
2735 | - XFS_QMOPT_RES_REGBLKS); | |
2737 | + blkflags); | |
2736 | 2738 | } |
2737 | 2739 | |
2738 | 2740 | return (0); |
fs/xfs/quota/xfs_qm.h
... | ... | @@ -133,8 +133,9 @@ |
133 | 133 | time_t qi_btimelimit; /* limit for blks timer */ |
134 | 134 | time_t qi_itimelimit; /* limit for inodes timer */ |
135 | 135 | time_t qi_rtbtimelimit;/* limit for rt blks timer */ |
136 | - xfs_qwarncnt_t qi_bwarnlimit; /* limit for num warnings */ | |
137 | - xfs_qwarncnt_t qi_iwarnlimit; /* limit for num warnings */ | |
136 | + xfs_qwarncnt_t qi_bwarnlimit; /* limit for blks warnings */ | |
137 | + xfs_qwarncnt_t qi_iwarnlimit; /* limit for inodes warnings */ | |
138 | + xfs_qwarncnt_t qi_rtbwarnlimit;/* limit for rt blks warnings */ | |
138 | 139 | mutex_t qi_quotaofflock;/* to serialize quotaoff */ |
139 | 140 | xfs_filblks_t qi_dqchunklen; /* # BBs in a chunk of dqs */ |
140 | 141 | uint qi_dqperchunk; /* # ondisk dqs in above chunk */ |
... | ... | @@ -176,6 +177,7 @@ |
176 | 177 | |
177 | 178 | #define XFS_QM_BWARNLIMIT 5 |
178 | 179 | #define XFS_QM_IWARNLIMIT 5 |
180 | +#define XFS_QM_RTBWARNLIMIT 5 | |
179 | 181 | |
180 | 182 | #define XFS_QM_LOCK(xqm) (mutex_lock(&xqm##_lock, PINOD)) |
181 | 183 | #define XFS_QM_UNLOCK(xqm) (mutex_unlock(&xqm##_lock)) |
fs/xfs/quota/xfs_quota_priv.h
... | ... | @@ -56,6 +56,7 @@ |
56 | 56 | #define XFS_QI_RTBTIMELIMIT(mp) ((mp)->m_quotainfo->qi_rtbtimelimit) |
57 | 57 | #define XFS_QI_ITIMELIMIT(mp) ((mp)->m_quotainfo->qi_itimelimit) |
58 | 58 | #define XFS_QI_BWARNLIMIT(mp) ((mp)->m_quotainfo->qi_bwarnlimit) |
59 | +#define XFS_QI_RTBWARNLIMIT(mp) ((mp)->m_quotainfo->qi_rtbwarnlimit) | |
59 | 60 | #define XFS_QI_IWARNLIMIT(mp) ((mp)->m_quotainfo->qi_iwarnlimit) |
60 | 61 | #define XFS_QI_QOFFLOCK(mp) ((mp)->m_quotainfo->qi_quotaofflock) |
61 | 62 |
fs/xfs/quota/xfs_trans_dquot.c
... | ... | @@ -497,7 +497,7 @@ |
497 | 497 | * Adjust the RT reservation. |
498 | 498 | */ |
499 | 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 | 501 | if (qtrx->qt_rtblk_res > |
502 | 502 | qtrx->qt_rtblk_res_used) |
503 | 503 | dqp->q_res_rtbcount -= (xfs_qcnt_t) |
... | ... | @@ -530,12 +530,6 @@ |
530 | 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 | 533 | ASSERT(dqp->q_res_bcount >= |
540 | 534 | INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT)); |
541 | 535 | ASSERT(dqp->q_res_icount >= |
... | ... | @@ -636,7 +630,10 @@ |
636 | 630 | int error; |
637 | 631 | xfs_qcnt_t hardlimit; |
638 | 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 | 637 | xfs_qcnt_t *resbcountp; |
641 | 638 | xfs_quotainfo_t *q = mp->m_quotainfo; |
642 | 639 | |
... | ... | @@ -651,7 +648,9 @@ |
651 | 648 | softlimit = INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT); |
652 | 649 | if (!softlimit) |
653 | 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 | 654 | resbcountp = &dqp->q_res_bcount; |
656 | 655 | } else { |
657 | 656 | ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); |
... | ... | @@ -661,7 +660,9 @@ |
661 | 660 | softlimit = INT_GET(dqp->q_core.d_rtb_softlimit, ARCH_CONVERT); |
662 | 661 | if (!softlimit) |
663 | 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 | 666 | resbcountp = &dqp->q_res_rtbcount; |
666 | 667 | } |
667 | 668 | error = 0; |
668 | 669 | |
669 | 670 | |
670 | 671 | |
671 | 672 | |
672 | 673 | |
... | ... | @@ -691,37 +692,36 @@ |
691 | 692 | * If timer or warnings has expired, |
692 | 693 | * return EDQUOT |
693 | 694 | */ |
694 | - if ((btimer != 0 && get_seconds() > btimer) || | |
695 | - (dqp->q_core.d_bwarns && | |
696 | - INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT) >= | |
697 | - XFS_QI_BWARNLIMIT(dqp->q_mount))) { | |
695 | + if ((timer != 0 && get_seconds() > timer) || | |
696 | + (warns != 0 && warns >= warnlimit)) { | |
698 | 697 | error = EDQUOT; |
699 | 698 | goto error_return; |
700 | 699 | } |
701 | 700 | } |
702 | 701 | } |
703 | 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 | 709 | if (!hardlimit) |
706 | 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 | 713 | if (!softlimit) |
709 | 714 | softlimit = q->qi_isoftlimit; |
710 | - if (hardlimit > 0ULL && | |
711 | - INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= hardlimit) { | |
715 | + if (hardlimit > 0ULL && count >= hardlimit) { | |
712 | 716 | error = EDQUOT; |
713 | 717 | goto error_return; |
714 | - } else if (softlimit > 0ULL && | |
715 | - INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= softlimit) { | |
718 | + } else if (softlimit > 0ULL && count >= softlimit) { | |
716 | 719 | /* |
717 | 720 | * If timer or warnings has expired, |
718 | 721 | * return EDQUOT |
719 | 722 | */ |
720 | - if ((dqp->q_core.d_itimer && | |
721 | - get_seconds() > INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT)) || | |
722 | - (dqp->q_core.d_iwarns && | |
723 | - INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT) >= | |
724 | - XFS_QI_IWARNLIMIT(dqp->q_mount))) { | |
723 | + if ((timer != 0 && get_seconds() > timer) || | |
724 | + (warns != 0 && warns >= warnlimit)) { | |
725 | 725 | error = EDQUOT; |
726 | 726 | goto error_return; |
727 | 727 | } |
fs/xfs/xfs_bmap.c
... | ... | @@ -4545,18 +4545,17 @@ |
4545 | 4545 | xfs_extlen_t alen; /* allocated extent length */ |
4546 | 4546 | xfs_fileoff_t aoff; /* allocated file offset */ |
4547 | 4547 | xfs_bmalloca_t bma; /* args for xfs_bmap_alloc */ |
4548 | - char contig; /* allocation must be one extent */ | |
4549 | 4548 | xfs_btree_cur_t *cur; /* bmap btree cursor */ |
4550 | - char delay; /* this request is for delayed alloc */ | |
4551 | 4549 | xfs_fileoff_t end; /* end of mapped file region */ |
4552 | 4550 | int eof; /* we've hit the end of extent list */ |
4551 | + char contig; /* allocation must be one extent */ | |
4552 | + char delay; /* this request is for delayed alloc */ | |
4553 | + char exact; /* don't do all of wasdelayed extent */ | |
4553 | 4554 | xfs_bmbt_rec_t *ep; /* extent list entry pointer */ |
4554 | 4555 | int error; /* error return */ |
4555 | - char exact; /* don't do all of wasdelayed extent */ | |
4556 | 4556 | xfs_bmbt_irec_t got; /* current extent list record */ |
4557 | 4557 | xfs_ifork_t *ifp; /* inode fork pointer */ |
4558 | 4558 | xfs_extlen_t indlen; /* indirect blocks length */ |
4559 | - char inhole; /* current location is hole in file */ | |
4560 | 4559 | xfs_extnum_t lastx; /* last useful extent number */ |
4561 | 4560 | int logflags; /* flags for transaction logging */ |
4562 | 4561 | xfs_extlen_t minleft; /* min blocks left after allocation */ |
4563 | 4562 | |
4564 | 4563 | |
4565 | 4564 | |
... | ... | @@ -4567,13 +4566,15 @@ |
4567 | 4566 | xfs_extnum_t nextents; /* number of extents in file */ |
4568 | 4567 | xfs_fileoff_t obno; /* old block number (offset) */ |
4569 | 4568 | xfs_bmbt_irec_t prev; /* previous extent list record */ |
4570 | - char stateless; /* ignore state flag set */ | |
4571 | 4569 | int tmp_logflags; /* temp flags holder */ |
4570 | + int whichfork; /* data or attr fork */ | |
4571 | + char inhole; /* current location is hole in file */ | |
4572 | + char stateless; /* ignore state flag set */ | |
4572 | 4573 | char trim; /* output trimmed to match range */ |
4573 | 4574 | char userdata; /* allocating non-metadata */ |
4574 | 4575 | char wasdelay; /* old extent was delayed */ |
4575 | - int whichfork; /* data or attr fork */ | |
4576 | 4576 | char wr; /* this is a write request */ |
4577 | + char rt; /* this is a realtime file */ | |
4577 | 4578 | char rsvd; /* OK to allocate reserved blocks */ |
4578 | 4579 | #ifdef DEBUG |
4579 | 4580 | xfs_fileoff_t orig_bno; /* original block number value */ |
... | ... | @@ -4603,6 +4604,7 @@ |
4603 | 4604 | } |
4604 | 4605 | if (XFS_FORCED_SHUTDOWN(mp)) |
4605 | 4606 | return XFS_ERROR(EIO); |
4607 | + rt = XFS_IS_REALTIME_INODE(ip); | |
4606 | 4608 | ifp = XFS_IFORK_PTR(ip, whichfork); |
4607 | 4609 | ASSERT(ifp->if_ext_max == |
4608 | 4610 | XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); |
... | ... | @@ -4707,9 +4709,16 @@ |
4707 | 4709 | } |
4708 | 4710 | minlen = contig ? alen : 1; |
4709 | 4711 | if (delay) { |
4710 | - indlen = (xfs_extlen_t) | |
4711 | - xfs_bmap_worst_indlen(ip, alen); | |
4712 | - ASSERT(indlen > 0); | |
4712 | + xfs_extlen_t extsz = 0; | |
4713 | + | |
4714 | + /* Figure out the extent size, adjust alen */ | |
4715 | + if (rt) { | |
4716 | + if (!(extsz = ip->i_d.di_extsize)) | |
4717 | + extsz = mp->m_sb.sb_rextsize; | |
4718 | + alen = roundup(alen, extsz); | |
4719 | + extsz = alen / mp->m_sb.sb_rextsize; | |
4720 | + } | |
4721 | + | |
4713 | 4722 | /* |
4714 | 4723 | * Make a transaction-less quota reservation for |
4715 | 4724 | * delayed allocation blocks. This number gets |
... | ... | @@ -4717,8 +4726,10 @@ |
4717 | 4726 | * We return EDQUOT if we haven't allocated |
4718 | 4727 | * blks already inside this loop; |
4719 | 4728 | */ |
4720 | - if (XFS_TRANS_RESERVE_BLKQUOTA( | |
4721 | - mp, NULL, ip, (long)alen)) { | |
4729 | + if (XFS_TRANS_RESERVE_QUOTA_NBLKS( | |
4730 | + mp, NULL, ip, (long)alen, 0, | |
4731 | + rt ? XFS_QMOPT_RES_RTBLKS : | |
4732 | + XFS_QMOPT_RES_REGBLKS)) { | |
4722 | 4733 | if (n == 0) { |
4723 | 4734 | *nmap = 0; |
4724 | 4735 | ASSERT(cur == NULL); |
4725 | 4736 | |
4726 | 4737 | |
... | ... | @@ -4731,40 +4742,34 @@ |
4731 | 4742 | * Split changing sb for alen and indlen since |
4732 | 4743 | * they could be coming from different places. |
4733 | 4744 | */ |
4734 | - if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) { | |
4735 | - xfs_extlen_t extsz; | |
4736 | - xfs_extlen_t ralen; | |
4737 | - if (!(extsz = ip->i_d.di_extsize)) | |
4738 | - extsz = mp->m_sb.sb_rextsize; | |
4739 | - ralen = roundup(alen, extsz); | |
4740 | - ralen = ralen / mp->m_sb.sb_rextsize; | |
4741 | - if (xfs_mod_incore_sb(mp, | |
4742 | - XFS_SBS_FREXTENTS, | |
4743 | - -(ralen), rsvd)) { | |
4744 | - if (XFS_IS_QUOTA_ON(ip->i_mount)) | |
4745 | - XFS_TRANS_UNRESERVE_BLKQUOTA( | |
4746 | - mp, NULL, ip, | |
4747 | - (long)alen); | |
4748 | - break; | |
4749 | - } | |
4750 | - } else { | |
4751 | - if (xfs_mod_incore_sb(mp, | |
4752 | - XFS_SBS_FDBLOCKS, | |
4753 | - -(alen), rsvd)) { | |
4754 | - if (XFS_IS_QUOTA_ON(ip->i_mount)) | |
4755 | - XFS_TRANS_UNRESERVE_BLKQUOTA( | |
4756 | - mp, NULL, ip, | |
4757 | - (long)alen); | |
4758 | - break; | |
4759 | - } | |
4760 | - } | |
4745 | + indlen = (xfs_extlen_t) | |
4746 | + xfs_bmap_worst_indlen(ip, alen); | |
4747 | + ASSERT(indlen > 0); | |
4761 | 4748 | |
4762 | - if (xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, | |
4763 | - -(indlen), rsvd)) { | |
4764 | - XFS_TRANS_UNRESERVE_BLKQUOTA( | |
4765 | - mp, NULL, ip, (long)alen); | |
4749 | + if (rt) | |
4750 | + error = xfs_mod_incore_sb(mp, | |
4751 | + XFS_SBS_FREXTENTS, | |
4752 | + -(extsz), rsvd); | |
4753 | + else | |
4754 | + error = xfs_mod_incore_sb(mp, | |
4755 | + XFS_SBS_FDBLOCKS, | |
4756 | + -(alen), rsvd); | |
4757 | + if (!error) | |
4758 | + error = xfs_mod_incore_sb(mp, | |
4759 | + XFS_SBS_FDBLOCKS, | |
4760 | + -(indlen), rsvd); | |
4761 | + | |
4762 | + if (error) { | |
4763 | + if (XFS_IS_QUOTA_ON(ip->i_mount)) | |
4764 | + /* unreserve the blocks now */ | |
4765 | + XFS_TRANS_UNRESERVE_QUOTA_NBLKS( | |
4766 | + mp, NULL, ip, | |
4767 | + (long)alen, 0, rt ? | |
4768 | + XFS_QMOPT_RES_RTBLKS : | |
4769 | + XFS_QMOPT_RES_REGBLKS); | |
4766 | 4770 | break; |
4767 | 4771 | } |
4772 | + | |
4768 | 4773 | ip->i_delayed_blks += alen; |
4769 | 4774 | abno = NULLSTARTBLOCK(indlen); |
4770 | 4775 | } else { |
4771 | 4776 | |
... | ... | @@ -5389,13 +5394,24 @@ |
5389 | 5394 | } |
5390 | 5395 | if (wasdel) { |
5391 | 5396 | ASSERT(STARTBLOCKVAL(del.br_startblock) > 0); |
5392 | - xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, | |
5393 | - (int)del.br_blockcount, rsvd); | |
5394 | - /* Unreserve our quota space */ | |
5395 | - XFS_TRANS_RESERVE_QUOTA_NBLKS( | |
5396 | - mp, NULL, ip, -((long)del.br_blockcount), 0, | |
5397 | - isrt ? XFS_QMOPT_RES_RTBLKS : | |
5397 | + /* Update realtim/data freespace, unreserve quota */ | |
5398 | + if (isrt) { | |
5399 | + xfs_filblks_t rtexts; | |
5400 | + | |
5401 | + rtexts = XFS_FSB_TO_B(mp, del.br_blockcount); | |
5402 | + do_div(rtexts, mp->m_sb.sb_rextsize); | |
5403 | + xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, | |
5404 | + (int)rtexts, rsvd); | |
5405 | + XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip, | |
5406 | + -((long)del.br_blockcount), 0, | |
5407 | + XFS_QMOPT_RES_RTBLKS); | |
5408 | + } else { | |
5409 | + xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, | |
5410 | + (int)del.br_blockcount, rsvd); | |
5411 | + XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip, | |
5412 | + -((long)del.br_blockcount), 0, | |
5398 | 5413 | XFS_QMOPT_RES_REGBLKS); |
5414 | + } | |
5399 | 5415 | ip->i_delayed_blks -= del.br_blockcount; |
5400 | 5416 | if (cur) |
5401 | 5417 | cur->bc_private.b.flags |= |
fs/xfs/xfs_iomap.c
... | ... | @@ -385,15 +385,15 @@ |
385 | 385 | int nimaps, maps; |
386 | 386 | int error; |
387 | 387 | int bmapi_flag; |
388 | + int quota_flag; | |
388 | 389 | int rt; |
389 | 390 | xfs_trans_t *tp; |
390 | 391 | xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS], *imapp; |
391 | 392 | xfs_bmap_free_t free_list; |
392 | 393 | int aeof; |
393 | - xfs_filblks_t datablocks; | |
394 | + xfs_filblks_t datablocks, qblocks, resblks; | |
394 | 395 | int committed; |
395 | 396 | int numrtextents; |
396 | - uint resblks; | |
397 | 397 | |
398 | 398 | /* |
399 | 399 | * Make sure that the dquots are there. This doesn't hold |
... | ... | @@ -419,7 +419,6 @@ |
419 | 419 | xfs_fileoff_t map_last_fsb; |
420 | 420 | |
421 | 421 | map_last_fsb = ret_imap->br_blockcount + ret_imap->br_startoff; |
422 | - | |
423 | 422 | if (map_last_fsb < last_fsb) { |
424 | 423 | last_fsb = map_last_fsb; |
425 | 424 | count_fsb = last_fsb - offset_fsb; |
426 | 425 | |
427 | 426 | |
428 | 427 | |
429 | 428 | |
430 | 429 | |
431 | 430 | |
432 | 431 | |
433 | 432 | |
434 | 433 | |
435 | 434 | |
436 | 435 | |
437 | 436 | |
438 | 437 | |
... | ... | @@ -428,56 +427,47 @@ |
428 | 427 | } |
429 | 428 | |
430 | 429 | /* |
431 | - * determine if reserving space on | |
432 | - * the data or realtime partition. | |
430 | + * Determine if reserving space on the data or realtime partition. | |
433 | 431 | */ |
434 | 432 | if ((rt = XFS_IS_REALTIME_INODE(ip))) { |
435 | - int sbrtextsize, iprtextsize; | |
433 | + xfs_extlen_t extsz; | |
436 | 434 | |
437 | - sbrtextsize = mp->m_sb.sb_rextsize; | |
438 | - iprtextsize = | |
439 | - ip->i_d.di_extsize ? ip->i_d.di_extsize : sbrtextsize; | |
440 | - numrtextents = (count_fsb + iprtextsize - 1); | |
441 | - do_div(numrtextents, sbrtextsize); | |
435 | + if (!(extsz = ip->i_d.di_extsize)) | |
436 | + extsz = mp->m_sb.sb_rextsize; | |
437 | + numrtextents = qblocks = (count_fsb + extsz - 1); | |
438 | + do_div(numrtextents, mp->m_sb.sb_rextsize); | |
439 | + quota_flag = XFS_QMOPT_RES_RTBLKS; | |
442 | 440 | datablocks = 0; |
443 | 441 | } else { |
444 | - datablocks = count_fsb; | |
442 | + datablocks = qblocks = count_fsb; | |
443 | + quota_flag = XFS_QMOPT_RES_REGBLKS; | |
445 | 444 | numrtextents = 0; |
446 | 445 | } |
447 | 446 | |
448 | 447 | /* |
449 | - * allocate and setup the transaction | |
448 | + * Allocate and setup the transaction | |
450 | 449 | */ |
451 | 450 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
452 | 451 | tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); |
453 | - | |
454 | 452 | resblks = XFS_DIOSTRAT_SPACE_RES(mp, datablocks); |
455 | - | |
456 | 453 | error = xfs_trans_reserve(tp, resblks, |
457 | 454 | XFS_WRITE_LOG_RES(mp), numrtextents, |
458 | 455 | XFS_TRANS_PERM_LOG_RES, |
459 | 456 | XFS_WRITE_LOG_COUNT); |
460 | 457 | |
461 | 458 | /* |
462 | - * check for running out of space | |
459 | + * Check for running out of space, note: need lock to return | |
463 | 460 | */ |
464 | 461 | if (error) |
465 | - /* | |
466 | - * Free the transaction structure. | |
467 | - */ | |
468 | 462 | xfs_trans_cancel(tp, 0); |
469 | - | |
470 | 463 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
471 | - | |
472 | 464 | if (error) |
473 | - goto error_out; /* Don't return in above if .. trans .., | |
474 | - need lock to return */ | |
465 | + goto error_out; | |
475 | 466 | |
476 | - if (XFS_TRANS_RESERVE_BLKQUOTA(mp, tp, ip, resblks)) { | |
467 | + if (XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag)) { | |
477 | 468 | error = (EDQUOT); |
478 | 469 | goto error1; |
479 | 470 | } |
480 | - nimaps = 1; | |
481 | 471 | |
482 | 472 | bmapi_flag = XFS_BMAPI_WRITE; |
483 | 473 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); |
484 | 474 | |
485 | 475 | |
486 | 476 | |
487 | 477 | |
488 | 478 | |
489 | 479 | |
490 | 480 | |
491 | 481 | |
492 | 482 | |
493 | 483 | |
... | ... | @@ -487,31 +477,29 @@ |
487 | 477 | bmapi_flag |= XFS_BMAPI_PREALLOC; |
488 | 478 | |
489 | 479 | /* |
490 | - * issue the bmapi() call to allocate the blocks | |
480 | + * Issue the bmapi() call to allocate the blocks | |
491 | 481 | */ |
492 | 482 | XFS_BMAP_INIT(&free_list, &firstfsb); |
483 | + nimaps = 1; | |
493 | 484 | imapp = &imap[0]; |
494 | 485 | error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, |
495 | 486 | bmapi_flag, &firstfsb, 0, imapp, &nimaps, &free_list); |
496 | - if (error) { | |
487 | + if (error) | |
497 | 488 | goto error0; |
498 | - } | |
499 | 489 | |
500 | 490 | /* |
501 | - * complete the transaction | |
491 | + * Complete the transaction | |
502 | 492 | */ |
503 | - | |
504 | 493 | error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed); |
505 | - if (error) { | |
494 | + if (error) | |
506 | 495 | goto error0; |
507 | - } | |
508 | - | |
509 | 496 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); |
510 | - if (error) { | |
497 | + if (error) | |
511 | 498 | goto error_out; |
512 | - } | |
513 | 499 | |
514 | - /* copy any maps to caller's array and return any error. */ | |
500 | + /* | |
501 | + * Copy any maps to caller's array and return any error. | |
502 | + */ | |
515 | 503 | if (nimaps == 0) { |
516 | 504 | error = (ENOSPC); |
517 | 505 | goto error_out; |
518 | 506 | |
519 | 507 | |
... | ... | @@ -530,10 +518,11 @@ |
530 | 518 | } |
531 | 519 | return 0; |
532 | 520 | |
533 | - error0: /* Cancel bmap, unlock inode, and cancel trans */ | |
521 | +error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ | |
534 | 522 | xfs_bmap_cancel(&free_list); |
523 | + XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag); | |
535 | 524 | |
536 | - error1: /* Just cancel transaction */ | |
525 | +error1: /* Just cancel transaction */ | |
537 | 526 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); |
538 | 527 | *nmaps = 0; /* nothing set-up here */ |
539 | 528 |
fs/xfs/xfs_quota.h
... | ... | @@ -352,15 +352,8 @@ |
352 | 352 | #define XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp) \ |
353 | 353 | XFS_DQTRXOP_VOID(mp, tp, qo_unreserve_and_mod_dquots) |
354 | 354 | |
355 | -#define XFS_TRANS_RESERVE_BLKQUOTA(mp, tp, ip, nblks) \ | |
356 | - XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, 0, \ | |
357 | - XFS_QMOPT_RES_REGBLKS) | |
358 | -#define XFS_TRANS_RESERVE_BLKQUOTA_FORCE(mp, tp, ip, nblks) \ | |
359 | - XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, 0, \ | |
360 | - XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES) | |
361 | -#define XFS_TRANS_UNRESERVE_BLKQUOTA(mp, tp, ip, nblks) \ | |
362 | - XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, -(nblks), 0, \ | |
363 | - XFS_QMOPT_RES_REGBLKS) | |
355 | +#define XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, ninos, flags) \ | |
356 | + XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, -(nblks), -(ninos), flags) | |
364 | 357 | #define XFS_TRANS_RESERVE_QUOTA(mp, tp, ud, gd, nb, ni, f) \ |
365 | 358 | XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, ud, gd, nb, ni, \ |
366 | 359 | f | XFS_QMOPT_RES_REGBLKS) |
fs/xfs/xfs_vnodeops.c
... | ... | @@ -4175,9 +4175,8 @@ |
4175 | 4175 | break; |
4176 | 4176 | } |
4177 | 4177 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
4178 | - error = XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, | |
4179 | - ip->i_udquot, ip->i_gdquot, resblks, 0, rt ? | |
4180 | - XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS); | |
4178 | + error = XFS_TRANS_RESERVE_QUOTA(mp, tp, | |
4179 | + ip->i_udquot, ip->i_gdquot, resblks, 0, 0); | |
4181 | 4180 | if (error) |
4182 | 4181 | goto error1; |
4183 | 4182 |