Commit 06d10dd9ca70ff1318ff2b871ff5f61a94223d9f

Authored by Nathan Scott
1 parent 77bc5beb59

[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 }
... ... @@ -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 |=
... ... @@ -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  
... ... @@ -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