[XFS] Merge fixes into realtime quota code, since one/two reported, still
Nathan Scott [Tue, 21 Jun 2005 05:48:47 +0000 (15:48 +1000)]
not enabled though.

SGI-PV: 938145
SGI-Modid: xfs-linux:xfs-kern:22900a

Signed-off-by: Nathan Scott <nathans@sgi.com>

fs/xfs/quota/xfs_qm.c
fs/xfs/quota/xfs_qm.h
fs/xfs/quota/xfs_quota_priv.h
fs/xfs/quota/xfs_trans_dquot.c
fs/xfs/xfs_bmap.c
fs/xfs/xfs_iomap.c
fs/xfs/xfs_quota.h
fs/xfs/xfs_vnodeops.c

index 3ea7597..3254cb7 100644 (file)
@@ -1251,6 +1251,10 @@ xfs_qm_init_quotainfo(
                                INT_GET(ddqp->d_iwarns, ARCH_CONVERT) ?
                                INT_GET(ddqp->d_iwarns, ARCH_CONVERT) :
                                XFS_QM_IWARNLIMIT;
+               qinf->qi_rtbwarnlimit =
+                               INT_GET(ddqp->d_rtbwarns, ARCH_CONVERT) ?
+                               INT_GET(ddqp->d_rtbwarns, ARCH_CONVERT) :
+                               XFS_QM_RTBWARNLIMIT;
                qinf->qi_bhardlimit =
                                INT_GET(ddqp->d_blk_hardlimit, ARCH_CONVERT);
                qinf->qi_bsoftlimit =
@@ -1276,6 +1280,7 @@ xfs_qm_init_quotainfo(
                qinf->qi_rtbtimelimit = XFS_QM_RTBTIMELIMIT;
                qinf->qi_bwarnlimit = XFS_QM_BWARNLIMIT;
                qinf->qi_iwarnlimit = XFS_QM_IWARNLIMIT;
+               qinf->qi_rtbwarnlimit = XFS_QM_RTBWARNLIMIT;
        }
 
        return (0);
@@ -2624,6 +2629,9 @@ xfs_qm_vop_chown(
        xfs_dquot_t     *newdq)
 {
        xfs_dquot_t     *prevdq;
+       uint            bfield = XFS_IS_REALTIME_INODE(ip) ?
+                                XFS_TRANS_DQ_RTBCOUNT : XFS_TRANS_DQ_BCOUNT;
+
        ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
        ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount));
 
@@ -2632,20 +2640,12 @@ xfs_qm_vop_chown(
        ASSERT(prevdq);
        ASSERT(prevdq != newdq);
 
-       xfs_trans_mod_dquot(tp, prevdq,
-                           XFS_TRANS_DQ_BCOUNT,
-                           -(ip->i_d.di_nblocks));
-       xfs_trans_mod_dquot(tp, prevdq,
-                           XFS_TRANS_DQ_ICOUNT,
-                           -1);
+       xfs_trans_mod_dquot(tp, prevdq, bfield, -(ip->i_d.di_nblocks));
+       xfs_trans_mod_dquot(tp, prevdq, XFS_TRANS_DQ_ICOUNT, -1);
 
        /* the sparkling new dquot */
-       xfs_trans_mod_dquot(tp, newdq,
-                           XFS_TRANS_DQ_BCOUNT,
-                           ip->i_d.di_nblocks);
-       xfs_trans_mod_dquot(tp, newdq,
-                           XFS_TRANS_DQ_ICOUNT,
-                           1);
+       xfs_trans_mod_dquot(tp, newdq, bfield, ip->i_d.di_nblocks);
+       xfs_trans_mod_dquot(tp, newdq, XFS_TRANS_DQ_ICOUNT, 1);
 
        /*
         * Take an extra reference, because the inode
@@ -2673,7 +2673,7 @@ xfs_qm_vop_chown_reserve(
 {
        int             error;
        xfs_mount_t     *mp;
-       uint            delblks;
+       uint            delblks, blkflags;
        xfs_dquot_t     *unresudq, *unresgdq, *delblksudq, *delblksgdq;
 
        ASSERT(XFS_ISLOCKED_INODE(ip));
@@ -2682,6 +2682,8 @@ xfs_qm_vop_chown_reserve(
 
        delblks = ip->i_delayed_blks;
        delblksudq = delblksgdq = unresudq = unresgdq = NULL;
+       blkflags = XFS_IS_REALTIME_INODE(ip) ?
+                       XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS;
 
        if (XFS_IS_UQUOTA_ON(mp) && udqp &&
            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(
 
        if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount,
                                delblksudq, delblksgdq, ip->i_d.di_nblocks, 1,
-                               flags | XFS_QMOPT_RES_REGBLKS)))
+                               flags | blkflags)))
                return (error);
 
        /*
@@ -2728,11 +2730,11 @@ xfs_qm_vop_chown_reserve(
                ASSERT(unresudq || unresgdq);
                if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
                                delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0,
-                               flags | XFS_QMOPT_RES_REGBLKS)))
+                               flags | blkflags)))
                        return (error);
                xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
                                unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0,
-                               XFS_QMOPT_RES_REGBLKS);
+                               blkflags);
        }
 
        return (0);
index 7819687..b03eecf 100644 (file)
@@ -133,8 +133,9 @@ typedef struct xfs_quotainfo {
        time_t           qi_btimelimit;  /* limit for blks timer */
        time_t           qi_itimelimit;  /* limit for inodes timer */
        time_t           qi_rtbtimelimit;/* limit for rt blks timer */
-       xfs_qwarncnt_t   qi_bwarnlimit;  /* limit for num warnings */
-       xfs_qwarncnt_t   qi_iwarnlimit;  /* limit for num warnings */
+       xfs_qwarncnt_t   qi_bwarnlimit;  /* limit for blks warnings */
+       xfs_qwarncnt_t   qi_iwarnlimit;  /* limit for inodes warnings */
+       xfs_qwarncnt_t   qi_rtbwarnlimit;/* limit for rt blks warnings */
        mutex_t          qi_quotaofflock;/* to serialize quotaoff */
        xfs_filblks_t    qi_dqchunklen;  /* # BBs in a chunk of dqs */
        uint             qi_dqperchunk;  /* # ondisk dqs in above chunk */
@@ -176,6 +177,7 @@ typedef struct xfs_dquot_acct {
 
 #define XFS_QM_BWARNLIMIT      5
 #define XFS_QM_IWARNLIMIT      5
+#define XFS_QM_RTBWARNLIMIT    5
 
 #define XFS_QM_LOCK(xqm)       (mutex_lock(&xqm##_lock, PINOD))
 #define XFS_QM_UNLOCK(xqm)     (mutex_unlock(&xqm##_lock))
index 472afd3..bf413e7 100644 (file)
@@ -56,6 +56,7 @@
 #define XFS_QI_RTBTIMELIMIT(mp) ((mp)->m_quotainfo->qi_rtbtimelimit)
 #define XFS_QI_ITIMELIMIT(mp)  ((mp)->m_quotainfo->qi_itimelimit)
 #define XFS_QI_BWARNLIMIT(mp)  ((mp)->m_quotainfo->qi_bwarnlimit)
+#define XFS_QI_RTBWARNLIMIT(mp)        ((mp)->m_quotainfo->qi_rtbwarnlimit)
 #define XFS_QI_IWARNLIMIT(mp)  ((mp)->m_quotainfo->qi_iwarnlimit)
 #define XFS_QI_QOFFLOCK(mp)    ((mp)->m_quotainfo->qi_quotaofflock)
 
index 565efb7..3b99daf 100644 (file)
@@ -497,7 +497,7 @@ xfs_trans_apply_dquot_deltas(
                         * Adjust the RT reservation.
                         */
                        if (qtrx->qt_rtblk_res != 0) {
-                               if (qtrx->qt_blk_res != qtrx->qt_blk_res_used) {
+                               if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) {
                                        if (qtrx->qt_rtblk_res >
                                            qtrx->qt_rtblk_res_used)
                                               dqp->q_res_rtbcount -= (xfs_qcnt_t)
@@ -530,12 +530,6 @@ xfs_trans_apply_dquot_deltas(
                                            (xfs_qcnt_t)qtrx->qt_icount_delta;
                        }
 
-
-#ifdef QUOTADEBUG
-                       if (qtrx->qt_rtblk_res != 0)
-                               cmn_err(CE_DEBUG, "RT res %d for 0x%p\n",
-                                       (int) qtrx->qt_rtblk_res, dqp);
-#endif
                        ASSERT(dqp->q_res_bcount >=
                                INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT));
                        ASSERT(dqp->q_res_icount >=
@@ -636,7 +630,10 @@ xfs_trans_dqresv(
        int             error;
        xfs_qcnt_t      hardlimit;
        xfs_qcnt_t      softlimit;
-       time_t          btimer;
+       time_t          timer;
+       xfs_qwarncnt_t  warns;
+       xfs_qwarncnt_t  warnlimit;
+       xfs_qcnt_t      count;
        xfs_qcnt_t      *resbcountp;
        xfs_quotainfo_t *q = mp->m_quotainfo;
 
@@ -651,7 +648,9 @@ xfs_trans_dqresv(
                softlimit = INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT);
                if (!softlimit)
                        softlimit = q->qi_bsoftlimit;
-               btimer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT);
+               timer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT);
+               warns = INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT);
+               warnlimit = XFS_QI_BWARNLIMIT(dqp->q_mount);
                resbcountp = &dqp->q_res_bcount;
        } else {
                ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
@@ -661,7 +660,9 @@ xfs_trans_dqresv(
                softlimit = INT_GET(dqp->q_core.d_rtb_softlimit, ARCH_CONVERT);
                if (!softlimit)
                        softlimit = q->qi_rtbsoftlimit;
-               btimer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT);
+               timer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT);
+               warns = INT_GET(dqp->q_core.d_rtbwarns, ARCH_CONVERT);
+               warnlimit = XFS_QI_RTBWARNLIMIT(dqp->q_mount);
                resbcountp = &dqp->q_res_rtbcount;
        }
        error = 0;
@@ -691,37 +692,36 @@ xfs_trans_dqresv(
                                 * If timer or warnings has expired,
                                 * return EDQUOT
                                 */
-                               if ((btimer != 0 && get_seconds() > btimer) ||
-                                   (dqp->q_core.d_bwarns &&
-                                    INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT) >=
-                                    XFS_QI_BWARNLIMIT(dqp->q_mount))) {
+                               if ((timer != 0 && get_seconds() > timer) ||
+                                   (warns != 0 && warns >= warnlimit)) {
                                        error = EDQUOT;
                                        goto error_return;
                                }
                        }
                }
                if (ninos > 0) {
-                       hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT);
+                       count = INT_GET(dqp->q_core.d_icount, ARCH_CONVERT);
+                       timer = INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT);
+                       warns = INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT);
+                       warnlimit = XFS_QI_IWARNLIMIT(dqp->q_mount);
+                       hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit,
+                                               ARCH_CONVERT);
                        if (!hardlimit)
                                hardlimit = q->qi_ihardlimit;
-                       softlimit = INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT);
+                       softlimit = INT_GET(dqp->q_core.d_ino_softlimit,
+                                               ARCH_CONVERT);
                        if (!softlimit)
                                softlimit = q->qi_isoftlimit;
-                       if (hardlimit > 0ULL &&
-                           INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= hardlimit) {
+                       if (hardlimit > 0ULL && count >= hardlimit) {
                                error = EDQUOT;
                                goto error_return;
-                       } else if (softlimit > 0ULL &&
-                                  INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= softlimit) {
+                       } else if (softlimit > 0ULL && count >= softlimit) {
                                /*
                                 * If timer or warnings has expired,
                                 * return EDQUOT
                                 */
-                               if ((dqp->q_core.d_itimer &&
-                                    get_seconds() > INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT)) ||
-                                   (dqp->q_core.d_iwarns &&
-                                    INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT) >=
-                                    XFS_QI_IWARNLIMIT(dqp->q_mount))) {
+                               if ((timer != 0 && get_seconds() > timer) ||
+                                    (warns != 0 && warns >= warnlimit)) {
                                        error = EDQUOT;
                                        goto error_return;
                                }
index f6f5ad3..6f5d283 100644 (file)
@@ -4545,18 +4545,17 @@ xfs_bmapi(
        xfs_extlen_t    alen;           /* allocated extent length */
        xfs_fileoff_t   aoff;           /* allocated file offset */
        xfs_bmalloca_t  bma;            /* args for xfs_bmap_alloc */
-       char            contig;         /* allocation must be one extent */
        xfs_btree_cur_t *cur;           /* bmap btree cursor */
-       char            delay;          /* this request is for delayed alloc */
        xfs_fileoff_t   end;            /* end of mapped file region */
        int             eof;            /* we've hit the end of extent list */
+       char            contig;         /* allocation must be one extent */
+       char            delay;          /* this request is for delayed alloc */
+       char            exact;          /* don't do all of wasdelayed extent */
        xfs_bmbt_rec_t  *ep;            /* extent list entry pointer */
        int             error;          /* error return */
-       char            exact;          /* don't do all of wasdelayed extent */
        xfs_bmbt_irec_t got;            /* current extent list record */
        xfs_ifork_t     *ifp;           /* inode fork pointer */
        xfs_extlen_t    indlen;         /* indirect blocks length */
-       char            inhole;         /* current location is hole in file */
        xfs_extnum_t    lastx;          /* last useful extent number */
        int             logflags;       /* flags for transaction logging */
        xfs_extlen_t    minleft;        /* min blocks left after allocation */
@@ -4567,13 +4566,15 @@ xfs_bmapi(
        xfs_extnum_t    nextents;       /* number of extents in file */
        xfs_fileoff_t   obno;           /* old block number (offset) */
        xfs_bmbt_irec_t prev;           /* previous extent list record */
-       char            stateless;      /* ignore state flag set */
        int             tmp_logflags;   /* temp flags holder */
+       int             whichfork;      /* data or attr fork */
+       char            inhole;         /* current location is hole in file */
+       char            stateless;      /* ignore state flag set */
        char            trim;           /* output trimmed to match range */
        char            userdata;       /* allocating non-metadata */
        char            wasdelay;       /* old extent was delayed */
-       int             whichfork;      /* data or attr fork */
        char            wr;             /* this is a write request */
+       char            rt;             /* this is a realtime file */
        char            rsvd;           /* OK to allocate reserved blocks */
 #ifdef DEBUG
        xfs_fileoff_t   orig_bno;       /* original block number value */
@@ -4603,6 +4604,7 @@ xfs_bmapi(
        }
        if (XFS_FORCED_SHUTDOWN(mp))
                return XFS_ERROR(EIO);
+       rt = XFS_IS_REALTIME_INODE(ip);
        ifp = XFS_IFORK_PTR(ip, whichfork);
        ASSERT(ifp->if_ext_max ==
               XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
@@ -4707,9 +4709,16 @@ xfs_bmapi(
                        }
                        minlen = contig ? alen : 1;
                        if (delay) {
-                               indlen = (xfs_extlen_t)
-                                       xfs_bmap_worst_indlen(ip, alen);
-                               ASSERT(indlen > 0);
+                               xfs_extlen_t    extsz = 0;
+
+                               /* Figure out the extent size, adjust alen */
+                               if (rt) {
+                                       if (!(extsz = ip->i_d.di_extsize))
+                                               extsz = mp->m_sb.sb_rextsize;
+                                       alen = roundup(alen, extsz);
+                                       extsz = alen / mp->m_sb.sb_rextsize;
+                               }
+
                                /*
                                 * Make a transaction-less quota reservation for
                                 * delayed allocation blocks. This number gets
@@ -4717,8 +4726,10 @@ xfs_bmapi(
                                 * We return EDQUOT if we haven't allocated
                                 * blks already inside this loop;
                                 */
-                               if (XFS_TRANS_RESERVE_BLKQUOTA(
-                                               mp, NULL, ip, (long)alen)) {
+                               if (XFS_TRANS_RESERVE_QUOTA_NBLKS(
+                                               mp, NULL, ip, (long)alen, 0,
+                                               rt ? XFS_QMOPT_RES_RTBLKS :
+                                                    XFS_QMOPT_RES_REGBLKS)) {
                                        if (n == 0) {
                                                *nmap = 0;
                                                ASSERT(cur == NULL);
@@ -4731,40 +4742,34 @@ xfs_bmapi(
                                 * Split changing sb for alen and indlen since
                                 * they could be coming from different places.
                                 */
-                               if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) {
-                                       xfs_extlen_t    extsz;
-                                       xfs_extlen_t    ralen;
-                                       if (!(extsz = ip->i_d.di_extsize))
-                                               extsz = mp->m_sb.sb_rextsize;
-                                       ralen = roundup(alen, extsz);
-                                       ralen = ralen / mp->m_sb.sb_rextsize;
-                                       if (xfs_mod_incore_sb(mp,
-                                               XFS_SBS_FREXTENTS,
-                                               -(ralen), rsvd)) {
-                                               if (XFS_IS_QUOTA_ON(ip->i_mount))
-                                                       XFS_TRANS_UNRESERVE_BLKQUOTA(
-                                                               mp, NULL, ip,
-                                                               (long)alen);
-                                               break;
-                                       }
-                               } else {
-                                       if (xfs_mod_incore_sb(mp,
-                                                             XFS_SBS_FDBLOCKS,
-                                                             -(alen), rsvd)) {
-                                               if (XFS_IS_QUOTA_ON(ip->i_mount))
-                                                       XFS_TRANS_UNRESERVE_BLKQUOTA(
-                                                               mp, NULL, ip,
-                                                               (long)alen);
-                                               break;
-                                       }
-                               }
+                               indlen = (xfs_extlen_t)
+                                       xfs_bmap_worst_indlen(ip, alen);
+                               ASSERT(indlen > 0);
 
-                               if (xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS,
-                                               -(indlen), rsvd)) {
-                                       XFS_TRANS_UNRESERVE_BLKQUOTA(
-                                               mp, NULL, ip, (long)alen);
+                               if (rt)
+                                       error = xfs_mod_incore_sb(mp,
+                                                       XFS_SBS_FREXTENTS,
+                                                       -(extsz), rsvd);
+                               else
+                                       error = xfs_mod_incore_sb(mp,
+                                                       XFS_SBS_FDBLOCKS,
+                                                       -(alen), rsvd);
+                               if (!error)
+                                       error = xfs_mod_incore_sb(mp,
+                                                       XFS_SBS_FDBLOCKS,
+                                                       -(indlen), rsvd);
+
+                               if (error) {
+                                       if (XFS_IS_QUOTA_ON(ip->i_mount))
+                                               /* unreserve the blocks now */
+                                               XFS_TRANS_UNRESERVE_QUOTA_NBLKS(
+                                                       mp, NULL, ip,
+                                                       (long)alen, 0, rt ?
+                                                       XFS_QMOPT_RES_RTBLKS :
+                                                       XFS_QMOPT_RES_REGBLKS);
                                        break;
                                }
+
                                ip->i_delayed_blks += alen;
                                abno = NULLSTARTBLOCK(indlen);
                        } else {
@@ -5389,13 +5394,24 @@ xfs_bunmapi(
                }
                if (wasdel) {
                        ASSERT(STARTBLOCKVAL(del.br_startblock) > 0);
-                       xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS,
-                               (int)del.br_blockcount, rsvd);
-                       /* Unreserve our quota space */
-                       XFS_TRANS_RESERVE_QUOTA_NBLKS(
-                               mp, NULL, ip, -((long)del.br_blockcount), 0,
-                               isrt ?  XFS_QMOPT_RES_RTBLKS :
+                       /* Update realtim/data freespace, unreserve quota */
+                       if (isrt) {
+                               xfs_filblks_t rtexts;
+
+                               rtexts = XFS_FSB_TO_B(mp, del.br_blockcount);
+                               do_div(rtexts, mp->m_sb.sb_rextsize);
+                               xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS,
+                                               (int)rtexts, rsvd);
+                               XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip,
+                                       -((long)del.br_blockcount), 0,
+                                       XFS_QMOPT_RES_RTBLKS);
+                       } else {
+                               xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS,
+                                               (int)del.br_blockcount, rsvd);
+                               XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip,
+                                       -((long)del.br_blockcount), 0,
                                        XFS_QMOPT_RES_REGBLKS);
+                       }
                        ip->i_delayed_blks -= del.br_blockcount;
                        if (cur)
                                cur->bc_private.b.flags |=
index 469e1a7..2edd676 100644 (file)
@@ -385,15 +385,15 @@ xfs_iomap_write_direct(
        int             nimaps, maps;
        int             error;
        int             bmapi_flag;
+       int             quota_flag;
        int             rt;
        xfs_trans_t     *tp;
        xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS], *imapp;
        xfs_bmap_free_t free_list;
        int             aeof;
-       xfs_filblks_t   datablocks;
+       xfs_filblks_t   datablocks, qblocks, resblks;
        int             committed;
        int             numrtextents;
-       uint            resblks;
 
        /*
         * Make sure that the dquots are there. This doesn't hold
@@ -419,7 +419,6 @@ xfs_iomap_write_direct(
                xfs_fileoff_t   map_last_fsb;
 
                map_last_fsb = ret_imap->br_blockcount + ret_imap->br_startoff;
-
                if (map_last_fsb < last_fsb) {
                        last_fsb = map_last_fsb;
                        count_fsb = last_fsb - offset_fsb;
@@ -428,56 +427,47 @@ xfs_iomap_write_direct(
        }
 
        /*
-        * determine if reserving space on
-        * the data or realtime partition.
+        * Determine if reserving space on the data or realtime partition.
         */
        if ((rt = XFS_IS_REALTIME_INODE(ip))) {
-               int     sbrtextsize, iprtextsize;
+               xfs_extlen_t    extsz;
 
-               sbrtextsize = mp->m_sb.sb_rextsize;
-               iprtextsize =
-                       ip->i_d.di_extsize ? ip->i_d.di_extsize : sbrtextsize;
-               numrtextents = (count_fsb + iprtextsize - 1);
-               do_div(numrtextents, sbrtextsize);
+               if (!(extsz = ip->i_d.di_extsize))
+                       extsz = mp->m_sb.sb_rextsize;
+               numrtextents = qblocks = (count_fsb + extsz - 1);
+               do_div(numrtextents, mp->m_sb.sb_rextsize);
+               quota_flag = XFS_QMOPT_RES_RTBLKS;
                datablocks = 0;
        } else {
-               datablocks = count_fsb;
+               datablocks = qblocks = count_fsb;
+               quota_flag = XFS_QMOPT_RES_REGBLKS;
                numrtextents = 0;
        }
 
        /*
-        * allocate and setup the transaction
+        * Allocate and setup the transaction
         */
        xfs_iunlock(ip, XFS_ILOCK_EXCL);
        tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
-
        resblks = XFS_DIOSTRAT_SPACE_RES(mp, datablocks);
-
        error = xfs_trans_reserve(tp, resblks,
                        XFS_WRITE_LOG_RES(mp), numrtextents,
                        XFS_TRANS_PERM_LOG_RES,
                        XFS_WRITE_LOG_COUNT);
 
        /*
-        * check for running out of space
+        * Check for running out of space, note: need lock to return
         */
        if (error)
-               /*
-                * Free the transaction structure.
-                */
                xfs_trans_cancel(tp, 0);
-
        xfs_ilock(ip, XFS_ILOCK_EXCL);
-
        if (error)
-               goto error_out; /* Don't return in above if .. trans ..,
-                                       need lock to return */
+               goto error_out;
 
-       if (XFS_TRANS_RESERVE_BLKQUOTA(mp, tp, ip, resblks)) {
+       if (XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag)) {
                error = (EDQUOT);
                goto error1;
        }
-       nimaps = 1;
 
        bmapi_flag = XFS_BMAPI_WRITE;
        xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
@@ -487,31 +477,29 @@ xfs_iomap_write_direct(
                bmapi_flag |= XFS_BMAPI_PREALLOC;
 
        /*
-        * issue the bmapi() call to allocate the blocks
+        * Issue the bmapi() call to allocate the blocks
         */
        XFS_BMAP_INIT(&free_list, &firstfsb);
+       nimaps = 1;
        imapp = &imap[0];
        error = xfs_bmapi(tp, ip, offset_fsb, count_fsb,
                bmapi_flag, &firstfsb, 0, imapp, &nimaps, &free_list);
-       if (error) {
+       if (error)
                goto error0;
-       }
 
        /*
-        * complete the transaction
+        * Complete the transaction
         */
-
        error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed);
-       if (error) {
+       if (error)
                goto error0;
-       }
-
        error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
-       if (error) {
+       if (error)
                goto error_out;
-       }
 
-       /* copy any maps to caller's array and return any error. */
+       /*
+        * Copy any maps to caller's array and return any error.
+        */
        if (nimaps == 0) {
                error = (ENOSPC);
                goto error_out;
@@ -530,10 +518,11 @@ xfs_iomap_write_direct(
         }
        return 0;
 
- error0:       /* Cancel bmap, unlock inode, and cancel trans */
+error0:        /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
        xfs_bmap_cancel(&free_list);
+       XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag);
 
- error1:       /* Just cancel transaction */
+error1:        /* Just cancel transaction */
        xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
        *nmaps = 0;     /* nothing set-up here */
 
index 341cb46..7134576 100644 (file)
@@ -352,15 +352,8 @@ typedef struct xfs_dqtrxops {
 #define XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp) \
        XFS_DQTRXOP_VOID(mp, tp, qo_unreserve_and_mod_dquots)
 
-#define XFS_TRANS_RESERVE_BLKQUOTA(mp, tp, ip, nblks) \
-       XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, 0, \
-                               XFS_QMOPT_RES_REGBLKS)
-#define XFS_TRANS_RESERVE_BLKQUOTA_FORCE(mp, tp, ip, nblks) \
-       XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, 0, \
-                               XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES)
-#define XFS_TRANS_UNRESERVE_BLKQUOTA(mp, tp, ip, nblks) \
-       XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, -(nblks), 0, \
-                               XFS_QMOPT_RES_REGBLKS)
+#define XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, ninos, flags) \
+       XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, -(nblks), -(ninos), flags)
 #define XFS_TRANS_RESERVE_QUOTA(mp, tp, ud, gd, nb, ni, f) \
        XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, ud, gd, nb, ni, \
                                f | XFS_QMOPT_RES_REGBLKS)
index d64ebcf..1377c86 100644 (file)
@@ -4175,9 +4175,8 @@ retry:
                        break;
                }
                xfs_ilock(ip, XFS_ILOCK_EXCL);
-               error = XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp,
-                               ip->i_udquot, ip->i_gdquot, resblks, 0, rt ?
-                               XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS);
+               error = XFS_TRANS_RESERVE_QUOTA(mp, tp,
+                               ip->i_udquot, ip->i_gdquot, resblks, 0, 0);
                if (error)
                        goto error1;