diff options
author | Nathan Scott <nathans@sgi.com> | 2005-06-21 15:48:47 +1000 |
---|---|---|
committer | Nathan Scott <nathans@sgi.com> | 2005-06-21 15:48:47 +1000 |
commit | 06d10dd9ca70ff1318ff2b871ff5f61a94223d9f (patch) | |
tree | 5ce06a8dc60a7ee78183e5b97a3565ac10424ea1 /fs/xfs | |
parent | 77bc5beb5977a166e41b87c9d55d8e9cf2b3a04f (diff) | |
download | linux-3.10-06d10dd9ca70ff1318ff2b871ff5f61a94223d9f.tar.gz linux-3.10-06d10dd9ca70ff1318ff2b871ff5f61a94223d9f.tar.bz2 linux-3.10-06d10dd9ca70ff1318ff2b871ff5f61a94223d9f.zip |
[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>
Diffstat (limited to 'fs/xfs')
-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 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap.c | 112 | ||||
-rw-r--r-- | fs/xfs/xfs_iomap.c | 65 | ||||
-rw-r--r-- | fs/xfs/xfs_quota.h | 11 | ||||
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 5 |
8 files changed, 143 insertions, 141 deletions
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 3ea75972767..3254cb7b87f 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -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); diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h index 78196877954..b03eecf3b6c 100644 --- a/fs/xfs/quota/xfs_qm.h +++ b/fs/xfs/quota/xfs_qm.h @@ -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)) diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h index 472afd3570c..bf413e70ec0 100644 --- a/fs/xfs/quota/xfs_quota_priv.h +++ b/fs/xfs/quota/xfs_quota_priv.h @@ -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) diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c index 565efb73c23..3b99daf8a64 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( * 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; } diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index f6f5ad35734..6f5d283888a 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -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 |= diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 469e1a7939d..2edd6769e5d 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -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 */ diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h index 341cb4604c6..7134576ae7f 100644 --- a/fs/xfs/xfs_quota.h +++ b/fs/xfs/xfs_quota.h @@ -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) diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index d64ebcfa0b6..1377c868f3f 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -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; |