[PATCH 05/38] xfs: factor xfs_trans_reserve_blocks() from xfs_trans_reserve()
Dave Chinner <[email protected]>
| Newsgroups | org.kernel.vger.linux-xfs |
|---|---|
| Message-ID | <[email protected]> |
Rename xfs_trans_reserve_more() to xfs_trans_reserve_blocks() and refactor xfs_trans_reserve() to call it instead of open coding the block reservation. Add the inverse xfs_trans_unreserve_blocks() for callers that need to give back reservations. This provides a common helper for both the initial transaction reservation and the reserve-more-later pattern used by online repair and the iomap paths. Update xfs_trans_reserve_more_inode() to use the new helpers and convert all remaining xfs_trans_reserve_more() callers in scrub. Signed-off-by: Dave Chinner <[email protected]> --- fs/xfs/scrub/cow_repair.c | 4 +- fs/xfs/scrub/quota_repair.c | 2 +- fs/xfs/scrub/rtbitmap_repair.c | 2 +- fs/xfs/scrub/tempfile.c | 2 +- fs/xfs/xfs_trans.c | 136 ++++++++++++++------------------- fs/xfs/xfs_trans.h | 4 +- 6 files changed, 67 insertions(+), 83 deletions(-) diff --git a/fs/xfs/scrub/cow_repair.c b/fs/xfs/scrub/cow_repair.c index 8dd9c0266e21..ee2a362d9bb2 100644 --- a/fs/xfs/scrub/cow_repair.c +++ b/fs/xfs/scrub/cow_repair.c @@ -435,7 +435,7 @@ xrep_cow_alloc( }; int error; - error = xfs_trans_reserve_more(sc->tp, del->br_blockcount, 0); + error = xfs_trans_reserve_blocks(sc->tp, del->br_blockcount, 0); if (error) return error; @@ -467,7 +467,7 @@ xrep_cow_alloc_rt( xfs_extlen_t len; int error; - error = xfs_trans_reserve_more(sc->tp, 0, maxrtx); + error = xfs_trans_reserve_blocks(sc->tp, 0, maxrtx); if (error) return error; diff --git a/fs/xfs/scrub/quota_repair.c b/fs/xfs/scrub/quota_repair.c index 487bd4f68ebb..759a5d5b2379 100644 --- a/fs/xfs/scrub/quota_repair.c +++ b/fs/xfs/scrub/quota_repair.c @@ -66,7 +66,7 @@ xrep_quota_item_fill_bmap_hole( xfs_trans_ijoin(sc->tp, sc->ip, 0); /* Map a block into the file. */ - error = xfs_trans_reserve_more(sc->tp, XFS_QM_DQALLOC_SPACE_RES(mp), + error = xfs_trans_reserve_blocks(sc->tp, XFS_QM_DQALLOC_SPACE_RES(mp), 0); if (error) return error; diff --git a/fs/xfs/scrub/rtbitmap_repair.c b/fs/xfs/scrub/rtbitmap_repair.c index 442a17bf9720..61f33e558ba4 100644 --- a/fs/xfs/scrub/rtbitmap_repair.c +++ b/fs/xfs/scrub/rtbitmap_repair.c @@ -546,7 +546,7 @@ xrep_rtbitmap( if (delta > UINT_MAX) return -EOPNOTSUPP; - error = xfs_trans_reserve_more(sc->tp, delta, 0); + error = xfs_trans_reserve_blocks(sc->tp, delta, 0); if (error) return error; diff --git a/fs/xfs/scrub/tempfile.c b/fs/xfs/scrub/tempfile.c index 98820003b929..6bffaf9bc1e8 100644 --- a/fs/xfs/scrub/tempfile.c +++ b/fs/xfs/scrub/tempfile.c @@ -818,7 +818,7 @@ xrep_tempexch_trans_reserve( if (error) return error; - error = xfs_trans_reserve_more(sc->tp, tx->req.resblks, 0); + error = xfs_trans_reserve_blocks(sc->tp, tx->req.resblks, 0); if (error) return error; diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 1b36cf12d4e3..609b0fe3d4d3 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -131,6 +131,53 @@ xfs_trans_dup( return ntp; } +/* + * Reserve disk blocks and RT extents for a transaction. On success the + * requested blocks are decremented from the global free space counters and + * added to the transaction's block reservation. On failure, no space is + * reserved and the transaction is not modified, and callers must be able to + * cancel the transaction without shutting down the filesystem. + */ +int +xfs_trans_reserve_blocks( + struct xfs_trans *tp, + unsigned int blocks, + unsigned int rtextents) +{ + bool rsvd = tp->t_flags & XFS_TRANS_RESERVE; + + if (blocks && xfs_dec_fdblocks(tp->t_mountp, blocks, rsvd)) + return -ENOSPC; + if (rtextents && xfs_dec_frextents(tp->t_mountp, rtextents)) { + if (blocks) + xfs_add_fdblocks(tp->t_mountp, blocks); + return -ENOSPC; + } + tp->t_blk_res += blocks; + tp->t_rtx_res += rtextents; + return 0; +} + +/* + * Give back block and RT extent reservations to the free space counters. + * This is the inverse of xfs_trans_reserve_blocks(). + */ +void +xfs_trans_unreserve_blocks( + struct xfs_trans *tp, + unsigned int blocks, + unsigned int rtextents) +{ + if (blocks) { + xfs_add_fdblocks(tp->t_mountp, blocks); + tp->t_blk_res -= blocks; + } + if (rtextents) { + xfs_add_frextents(tp->t_mountp, rtextents); + tp->t_rtx_res -= rtextents; + } +} + /* * This is called to reserve free disk blocks and log space for the given * transaction before allocating any resources within the transaction. @@ -149,22 +196,13 @@ xfs_trans_reserve( uint rtextents) { struct xfs_mount *mp = tp->t_mountp; - int error = 0; - bool rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0; + int error; ASSERT(resp->tr_logres > 0); - /* - * Attempt to reserve the needed disk blocks by decrementing the number - * needed from the number available. This will fail if the count would - * go below zero. - */ - if (blocks > 0) { - error = xfs_dec_fdblocks(mp, blocks, rsvd); - if (error != 0) - return -ENOSPC; - tp->t_blk_res += blocks; - } + error = xfs_trans_reserve_blocks(tp, blocks, rtextents); + if (error) + return error; /* * Reserve the log space needed for this transaction. @@ -173,39 +211,15 @@ xfs_trans_reserve( tp->t_flags |= XFS_TRANS_PERM_LOG_RES; error = xfs_log_reserve(mp, resp->tr_logres, resp->tr_logcount, &tp->t_ticket, (tp->t_flags & XFS_TRANS_PERM_LOG_RES)); - if (error) - goto undo_blocks; + if (error) { + xfs_trans_unreserve_blocks(tp, blocks, rtextents); + tp->t_flags &= ~XFS_TRANS_PERM_LOG_RES; + return error; + } tp->t_log_res = resp->tr_logres; tp->t_log_count = resp->tr_logcount; - - /* - * Attempt to reserve the needed realtime extents by decrementing the - * number needed from the number available. This will fail if the - * count would go below zero. - */ - if (rtextents > 0) { - error = xfs_dec_frextents(mp, rtextents); - if (error) { - error = -ENOSPC; - goto undo_log; - } - tp->t_rtx_res += rtextents; - } - return 0; - -undo_log: - xfs_log_ticket_ungrant(mp->m_log, tp->t_ticket); - tp->t_ticket = NULL; - tp->t_log_res = 0; - tp->t_flags &= ~XFS_TRANS_PERM_LOG_RES; -undo_blocks: - if (blocks > 0) { - xfs_add_fdblocks(mp, blocks); - tp->t_blk_res = 0; - } - return error; } static struct xfs_trans * @@ -1115,38 +1129,9 @@ xfs_trans_alloc_inode( return error; } -/* - * Try to reserve more blocks for a transaction. - * - * This is for callers that need to attach resources to a transaction, scan - * those resources to determine the space reservation requirements, and then - * modify the attached resources. In other words, online repair. This can - * fail due to ENOSPC, so the caller must be able to cancel the transaction - * without shutting down the fs. - */ -int -xfs_trans_reserve_more( - struct xfs_trans *tp, - unsigned int blocks, - unsigned int rtextents) -{ - bool rsvd = tp->t_flags & XFS_TRANS_RESERVE; - - if (blocks && xfs_dec_fdblocks(tp->t_mountp, blocks, rsvd)) - return -ENOSPC; - if (rtextents && xfs_dec_frextents(tp->t_mountp, rtextents)) { - if (blocks) - xfs_add_fdblocks(tp->t_mountp, blocks); - return -ENOSPC; - } - tp->t_blk_res += blocks; - tp->t_rtx_res += rtextents; - return 0; -} - /* * Try to reserve more blocks and file quota for a transaction. Same - * conditions of usage as xfs_trans_reserve_more. + * conditions of usage as xfs_trans_reserve_blocks. */ int xfs_trans_reserve_more_inode( @@ -1162,7 +1147,7 @@ xfs_trans_reserve_more_inode( xfs_assert_ilocked(ip, XFS_ILOCK_EXCL); - error = xfs_trans_reserve_more(tp, dblocks, rtx); + error = xfs_trans_reserve_blocks(tp, dblocks, rtx); if (error) return error; @@ -1178,10 +1163,7 @@ xfs_trans_reserve_more_inode( return 0; /* Quota failed, give back the new reservation. */ - xfs_add_fdblocks(mp, dblocks); - tp->t_blk_res -= dblocks; - xfs_add_frextents(mp, rtx); - tp->t_rtx_res -= rtx; + xfs_trans_unreserve_blocks(tp, dblocks, rtx); return error; } diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index eb83c5dac032..de77b617bccf 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -167,7 +167,9 @@ typedef struct xfs_trans { int xfs_trans_alloc(struct xfs_mount *mp, struct xfs_trans_res *resp, uint blocks, uint rtextents, uint flags, struct xfs_trans **tpp); -int xfs_trans_reserve_more(struct xfs_trans *tp, +int xfs_trans_reserve_blocks(struct xfs_trans *tp, + unsigned int blocks, unsigned int rtextents); +void xfs_trans_unreserve_blocks(struct xfs_trans *tp, unsigned int blocks, unsigned int rtextents); struct xfs_trans *xfs_trans_alloc_empty(struct xfs_mount *mp); void xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t); -- 2.55.0