Commit 45d06621 authored by Dave Chinner's avatar Dave Chinner Committed by Dave Chinner

xfs: pass perags through to the busy extent code

All of the callers of the busy extent API either have perag
references available to use so we can pass a perag to the busy
extent functions rather than having them have to do unnecessary
lookups.
Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
parent 7f8d3b3c
...@@ -1063,7 +1063,7 @@ xfs_alloc_ag_vextent_small( ...@@ -1063,7 +1063,7 @@ xfs_alloc_ag_vextent_small(
if (fbno == NULLAGBLOCK) if (fbno == NULLAGBLOCK)
goto out; goto out;
xfs_extent_busy_reuse(args->mp, args->agno, fbno, 1, xfs_extent_busy_reuse(args->mp, args->pag, fbno, 1,
(args->datatype & XFS_ALLOC_NOBUSY)); (args->datatype & XFS_ALLOC_NOBUSY));
if (args->datatype & XFS_ALLOC_USERDATA) { if (args->datatype & XFS_ALLOC_USERDATA) {
...@@ -1178,7 +1178,7 @@ xfs_alloc_ag_vextent( ...@@ -1178,7 +1178,7 @@ xfs_alloc_ag_vextent(
if (error) if (error)
return error; return error;
ASSERT(!xfs_extent_busy_search(args->mp, args->agno, ASSERT(!xfs_extent_busy_search(args->mp, args->pag,
args->agbno, args->len)); args->agbno, args->len));
} }
...@@ -3292,7 +3292,7 @@ xfs_alloc_vextent( ...@@ -3292,7 +3292,7 @@ xfs_alloc_vextent(
int int
xfs_free_extent_fix_freelist( xfs_free_extent_fix_freelist(
struct xfs_trans *tp, struct xfs_trans *tp,
xfs_agnumber_t agno, struct xfs_perag *pag,
struct xfs_buf **agbp) struct xfs_buf **agbp)
{ {
struct xfs_alloc_arg args; struct xfs_alloc_arg args;
...@@ -3301,7 +3301,8 @@ xfs_free_extent_fix_freelist( ...@@ -3301,7 +3301,8 @@ xfs_free_extent_fix_freelist(
memset(&args, 0, sizeof(struct xfs_alloc_arg)); memset(&args, 0, sizeof(struct xfs_alloc_arg));
args.tp = tp; args.tp = tp;
args.mp = tp->t_mountp; args.mp = tp->t_mountp;
args.agno = agno; args.agno = pag->pag_agno;
args.pag = pag;
/* /*
* validate that the block number is legal - the enables us to detect * validate that the block number is legal - the enables us to detect
...@@ -3310,17 +3311,12 @@ xfs_free_extent_fix_freelist( ...@@ -3310,17 +3311,12 @@ xfs_free_extent_fix_freelist(
if (args.agno >= args.mp->m_sb.sb_agcount) if (args.agno >= args.mp->m_sb.sb_agcount)
return -EFSCORRUPTED; return -EFSCORRUPTED;
args.pag = xfs_perag_get(args.mp, args.agno);
ASSERT(args.pag);
error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING); error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING);
if (error) if (error)
goto out; return error;
*agbp = args.agbp; *agbp = args.agbp;
out: return 0;
xfs_perag_put(args.pag);
return error;
} }
/* /*
...@@ -3344,6 +3340,7 @@ __xfs_free_extent( ...@@ -3344,6 +3340,7 @@ __xfs_free_extent(
struct xfs_agf *agf; struct xfs_agf *agf;
int error; int error;
unsigned int busy_flags = 0; unsigned int busy_flags = 0;
struct xfs_perag *pag;
ASSERT(len != 0); ASSERT(len != 0);
ASSERT(type != XFS_AG_RESV_AGFL); ASSERT(type != XFS_AG_RESV_AGFL);
...@@ -3352,33 +3349,37 @@ __xfs_free_extent( ...@@ -3352,33 +3349,37 @@ __xfs_free_extent(
XFS_ERRTAG_FREE_EXTENT)) XFS_ERRTAG_FREE_EXTENT))
return -EIO; return -EIO;
error = xfs_free_extent_fix_freelist(tp, agno, &agbp); pag = xfs_perag_get(mp, agno);
error = xfs_free_extent_fix_freelist(tp, pag, &agbp);
if (error) if (error)
return error; goto err;
agf = agbp->b_addr; agf = agbp->b_addr;
if (XFS_IS_CORRUPT(mp, agbno >= mp->m_sb.sb_agblocks)) { if (XFS_IS_CORRUPT(mp, agbno >= mp->m_sb.sb_agblocks)) {
error = -EFSCORRUPTED; error = -EFSCORRUPTED;
goto err; goto err_release;
} }
/* validate the extent size is legal now we have the agf locked */ /* validate the extent size is legal now we have the agf locked */
if (XFS_IS_CORRUPT(mp, agbno + len > be32_to_cpu(agf->agf_length))) { if (XFS_IS_CORRUPT(mp, agbno + len > be32_to_cpu(agf->agf_length))) {
error = -EFSCORRUPTED; error = -EFSCORRUPTED;
goto err; goto err_release;
} }
error = xfs_free_ag_extent(tp, agbp, agno, agbno, len, oinfo, type); error = xfs_free_ag_extent(tp, agbp, agno, agbno, len, oinfo, type);
if (error) if (error)
goto err; goto err_release;
if (skip_discard) if (skip_discard)
busy_flags |= XFS_EXTENT_BUSY_SKIP_DISCARD; busy_flags |= XFS_EXTENT_BUSY_SKIP_DISCARD;
xfs_extent_busy_insert(tp, agno, agbno, len, busy_flags); xfs_extent_busy_insert(tp, pag, agbno, len, busy_flags);
xfs_perag_put(pag);
return 0; return 0;
err: err_release:
xfs_trans_brelse(tp, agbp); xfs_trans_brelse(tp, agbp);
err:
xfs_perag_put(pag);
return error; return error;
} }
......
...@@ -214,7 +214,7 @@ int xfs_alloc_read_agfl(struct xfs_mount *mp, struct xfs_trans *tp, ...@@ -214,7 +214,7 @@ int xfs_alloc_read_agfl(struct xfs_mount *mp, struct xfs_trans *tp,
int xfs_free_agfl_block(struct xfs_trans *, xfs_agnumber_t, xfs_agblock_t, int xfs_free_agfl_block(struct xfs_trans *, xfs_agnumber_t, xfs_agblock_t,
struct xfs_buf *, struct xfs_owner_info *); struct xfs_buf *, struct xfs_owner_info *);
int xfs_alloc_fix_freelist(struct xfs_alloc_arg *args, int flags); int xfs_alloc_fix_freelist(struct xfs_alloc_arg *args, int flags);
int xfs_free_extent_fix_freelist(struct xfs_trans *tp, xfs_agnumber_t agno, int xfs_free_extent_fix_freelist(struct xfs_trans *tp, struct xfs_perag *pag,
struct xfs_buf **agbp); struct xfs_buf **agbp);
xfs_extlen_t xfs_prealloc_blocks(struct xfs_mount *mp); xfs_extlen_t xfs_prealloc_blocks(struct xfs_mount *mp);
......
...@@ -72,7 +72,7 @@ xfs_allocbt_alloc_block( ...@@ -72,7 +72,7 @@ xfs_allocbt_alloc_block(
} }
atomic64_inc(&cur->bc_mp->m_allocbt_blks); atomic64_inc(&cur->bc_mp->m_allocbt_blks);
xfs_extent_busy_reuse(cur->bc_mp, cur->bc_ag.agno, bno, 1, false); xfs_extent_busy_reuse(cur->bc_mp, cur->bc_ag.agbp->b_pag, bno, 1, false);
new->s = cpu_to_be32(bno); new->s = cpu_to_be32(bno);
...@@ -86,7 +86,6 @@ xfs_allocbt_free_block( ...@@ -86,7 +86,6 @@ xfs_allocbt_free_block(
struct xfs_buf *bp) struct xfs_buf *bp)
{ {
struct xfs_buf *agbp = cur->bc_ag.agbp; struct xfs_buf *agbp = cur->bc_ag.agbp;
struct xfs_agf *agf = agbp->b_addr;
xfs_agblock_t bno; xfs_agblock_t bno;
int error; int error;
...@@ -96,7 +95,7 @@ xfs_allocbt_free_block( ...@@ -96,7 +95,7 @@ xfs_allocbt_free_block(
return error; return error;
atomic64_dec(&cur->bc_mp->m_allocbt_blks); atomic64_dec(&cur->bc_mp->m_allocbt_blks);
xfs_extent_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1, xfs_extent_busy_insert(cur->bc_tp, agbp->b_pag, bno, 1,
XFS_EXTENT_BUSY_SKIP_DISCARD); XFS_EXTENT_BUSY_SKIP_DISCARD);
return 0; return 0;
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "xfs_trans_resv.h" #include "xfs_trans_resv.h"
#include "xfs_bit.h" #include "xfs_bit.h"
#include "xfs_mount.h" #include "xfs_mount.h"
#include "xfs_sb.h"
#include "xfs_defer.h" #include "xfs_defer.h"
#include "xfs_btree.h" #include "xfs_btree.h"
#include "xfs_trans.h" #include "xfs_trans.h"
...@@ -2363,31 +2364,32 @@ xfs_rmap_finish_one( ...@@ -2363,31 +2364,32 @@ xfs_rmap_finish_one(
struct xfs_btree_cur **pcur) struct xfs_btree_cur **pcur)
{ {
struct xfs_mount *mp = tp->t_mountp; struct xfs_mount *mp = tp->t_mountp;
struct xfs_perag *pag;
struct xfs_btree_cur *rcur; struct xfs_btree_cur *rcur;
struct xfs_buf *agbp = NULL; struct xfs_buf *agbp = NULL;
int error = 0; int error = 0;
xfs_agnumber_t agno;
struct xfs_owner_info oinfo; struct xfs_owner_info oinfo;
xfs_agblock_t bno; xfs_agblock_t bno;
bool unwritten; bool unwritten;
agno = XFS_FSB_TO_AGNO(mp, startblock); pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, startblock));
ASSERT(agno != NULLAGNUMBER);
bno = XFS_FSB_TO_AGBNO(mp, startblock); bno = XFS_FSB_TO_AGBNO(mp, startblock);
trace_xfs_rmap_deferred(mp, agno, type, bno, owner, whichfork, trace_xfs_rmap_deferred(mp, pag->pag_agno, type, bno, owner, whichfork,
startoff, blockcount, state); startoff, blockcount, state);
if (XFS_TEST_ERROR(false, mp, if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_RMAP_FINISH_ONE)) {
XFS_ERRTAG_RMAP_FINISH_ONE)) error = -EIO;
return -EIO; goto out_drop;
}
/* /*
* If we haven't gotten a cursor or the cursor AG doesn't match * If we haven't gotten a cursor or the cursor AG doesn't match
* the startblock, get one now. * the startblock, get one now.
*/ */
rcur = *pcur; rcur = *pcur;
if (rcur != NULL && rcur->bc_ag.agno != agno) { if (rcur != NULL && rcur->bc_ag.agno != pag->pag_agno) {
xfs_rmap_finish_one_cleanup(tp, rcur, 0); xfs_rmap_finish_one_cleanup(tp, rcur, 0);
rcur = NULL; rcur = NULL;
*pcur = NULL; *pcur = NULL;
...@@ -2398,13 +2400,15 @@ xfs_rmap_finish_one( ...@@ -2398,13 +2400,15 @@ xfs_rmap_finish_one(
* rmapbt, because a shape change could cause us to * rmapbt, because a shape change could cause us to
* allocate blocks. * allocate blocks.
*/ */
error = xfs_free_extent_fix_freelist(tp, agno, &agbp); error = xfs_free_extent_fix_freelist(tp, pag, &agbp);
if (error) if (error)
return error; goto out_drop;
if (XFS_IS_CORRUPT(tp->t_mountp, !agbp)) if (XFS_IS_CORRUPT(tp->t_mountp, !agbp)) {
return -EFSCORRUPTED; error = -EFSCORRUPTED;
goto out_drop;
}
rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, pag->pag_agno);
} }
*pcur = rcur; *pcur = rcur;
...@@ -2442,6 +2446,8 @@ xfs_rmap_finish_one( ...@@ -2442,6 +2446,8 @@ xfs_rmap_finish_one(
ASSERT(0); ASSERT(0);
error = -EFSCORRUPTED; error = -EFSCORRUPTED;
} }
out_drop:
xfs_perag_put(pag);
return error; return error;
} }
......
...@@ -100,8 +100,7 @@ xfs_rmapbt_alloc_block( ...@@ -100,8 +100,7 @@ xfs_rmapbt_alloc_block(
return 0; return 0;
} }
xfs_extent_busy_reuse(cur->bc_mp, cur->bc_ag.agno, bno, 1, xfs_extent_busy_reuse(cur->bc_mp, agbp->b_pag, bno, 1, false);
false);
new->s = cpu_to_be32(bno); new->s = cpu_to_be32(bno);
be32_add_cpu(&agf->agf_rmap_blocks, 1); be32_add_cpu(&agf->agf_rmap_blocks, 1);
...@@ -133,10 +132,10 @@ xfs_rmapbt_free_block( ...@@ -133,10 +132,10 @@ xfs_rmapbt_free_block(
if (error) if (error)
return error; return error;
xfs_extent_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1, pag = cur->bc_ag.agbp->b_pag;
xfs_extent_busy_insert(cur->bc_tp, pag, bno, 1,
XFS_EXTENT_BUSY_SKIP_DISCARD); XFS_EXTENT_BUSY_SKIP_DISCARD);
pag = cur->bc_ag.agbp->b_pag;
xfs_ag_resv_free_extent(pag, XFS_AG_RESV_RMAPBT, NULL, 1); xfs_ag_resv_free_extent(pag, XFS_AG_RESV_RMAPBT, NULL, 1);
return 0; return 0;
} }
......
...@@ -304,7 +304,7 @@ xrep_alloc_ag_block( ...@@ -304,7 +304,7 @@ xrep_alloc_ag_block(
return error; return error;
if (bno == NULLAGBLOCK) if (bno == NULLAGBLOCK)
return -ENOSPC; return -ENOSPC;
xfs_extent_busy_reuse(sc->mp, sc->sa.agno, bno, xfs_extent_busy_reuse(sc->mp, sc->sa.pag, bno,
1, false); 1, false);
*fsbno = XFS_AGB_TO_FSB(sc->mp, sc->sa.agno, bno); *fsbno = XFS_AGB_TO_FSB(sc->mp, sc->sa.agno, bno);
if (resv == XFS_AG_RESV_RMAPBT) if (resv == XFS_AG_RESV_RMAPBT)
...@@ -519,7 +519,7 @@ xrep_put_freelist( ...@@ -519,7 +519,7 @@ xrep_put_freelist(
agbno, 0); agbno, 0);
if (error) if (error)
return error; return error;
xfs_extent_busy_insert(sc->tp, sc->sa.agno, agbno, 1, xfs_extent_busy_insert(sc->tp, sc->sa.pag, agbno, 1,
XFS_EXTENT_BUSY_SKIP_DISCARD); XFS_EXTENT_BUSY_SKIP_DISCARD);
return 0; return 0;
......
...@@ -108,7 +108,7 @@ xfs_trim_extents( ...@@ -108,7 +108,7 @@ xfs_trim_extents(
* If any blocks in the range are still busy, skip the * If any blocks in the range are still busy, skip the
* discard and try again the next time. * discard and try again the next time.
*/ */
if (xfs_extent_busy_search(mp, agno, fbno, flen)) { if (xfs_extent_busy_search(mp, pag, fbno, flen)) {
trace_xfs_discard_busy(mp, agno, fbno, flen); trace_xfs_discard_busy(mp, agno, fbno, flen);
goto next_extent; goto next_extent;
} }
......
...@@ -22,28 +22,26 @@ ...@@ -22,28 +22,26 @@
void void
xfs_extent_busy_insert( xfs_extent_busy_insert(
struct xfs_trans *tp, struct xfs_trans *tp,
xfs_agnumber_t agno, struct xfs_perag *pag,
xfs_agblock_t bno, xfs_agblock_t bno,
xfs_extlen_t len, xfs_extlen_t len,
unsigned int flags) unsigned int flags)
{ {
struct xfs_extent_busy *new; struct xfs_extent_busy *new;
struct xfs_extent_busy *busyp; struct xfs_extent_busy *busyp;
struct xfs_perag *pag;
struct rb_node **rbp; struct rb_node **rbp;
struct rb_node *parent = NULL; struct rb_node *parent = NULL;
new = kmem_zalloc(sizeof(struct xfs_extent_busy), 0); new = kmem_zalloc(sizeof(struct xfs_extent_busy), 0);
new->agno = agno; new->agno = pag->pag_agno;
new->bno = bno; new->bno = bno;
new->length = len; new->length = len;
INIT_LIST_HEAD(&new->list); INIT_LIST_HEAD(&new->list);
new->flags = flags; new->flags = flags;
/* trace before insert to be able to see failed inserts */ /* trace before insert to be able to see failed inserts */
trace_xfs_extent_busy(tp->t_mountp, agno, bno, len); trace_xfs_extent_busy(tp->t_mountp, pag->pag_agno, bno, len);
pag = xfs_perag_get(tp->t_mountp, new->agno);
spin_lock(&pag->pagb_lock); spin_lock(&pag->pagb_lock);
rbp = &pag->pagb_tree.rb_node; rbp = &pag->pagb_tree.rb_node;
while (*rbp) { while (*rbp) {
...@@ -66,7 +64,6 @@ xfs_extent_busy_insert( ...@@ -66,7 +64,6 @@ xfs_extent_busy_insert(
list_add(&new->list, &tp->t_busy); list_add(&new->list, &tp->t_busy);
spin_unlock(&pag->pagb_lock); spin_unlock(&pag->pagb_lock);
xfs_perag_put(pag);
} }
/* /*
...@@ -81,21 +78,17 @@ xfs_extent_busy_insert( ...@@ -81,21 +78,17 @@ xfs_extent_busy_insert(
int int
xfs_extent_busy_search( xfs_extent_busy_search(
struct xfs_mount *mp, struct xfs_mount *mp,
xfs_agnumber_t agno, struct xfs_perag *pag,
xfs_agblock_t bno, xfs_agblock_t bno,
xfs_extlen_t len) xfs_extlen_t len)
{ {
struct xfs_perag *pag;
struct rb_node *rbp; struct rb_node *rbp;
struct xfs_extent_busy *busyp; struct xfs_extent_busy *busyp;
int match = 0; int match = 0;
pag = xfs_perag_get(mp, agno); /* find closest start bno overlap */
spin_lock(&pag->pagb_lock); spin_lock(&pag->pagb_lock);
rbp = pag->pagb_tree.rb_node; rbp = pag->pagb_tree.rb_node;
/* find closest start bno overlap */
while (rbp) { while (rbp) {
busyp = rb_entry(rbp, struct xfs_extent_busy, rb_node); busyp = rb_entry(rbp, struct xfs_extent_busy, rb_node);
if (bno < busyp->bno) { if (bno < busyp->bno) {
...@@ -115,7 +108,6 @@ xfs_extent_busy_search( ...@@ -115,7 +108,6 @@ xfs_extent_busy_search(
} }
} }
spin_unlock(&pag->pagb_lock); spin_unlock(&pag->pagb_lock);
xfs_perag_put(pag);
return match; return match;
} }
...@@ -281,17 +273,14 @@ xfs_extent_busy_update_extent( ...@@ -281,17 +273,14 @@ xfs_extent_busy_update_extent(
void void
xfs_extent_busy_reuse( xfs_extent_busy_reuse(
struct xfs_mount *mp, struct xfs_mount *mp,
xfs_agnumber_t agno, struct xfs_perag *pag,
xfs_agblock_t fbno, xfs_agblock_t fbno,
xfs_extlen_t flen, xfs_extlen_t flen,
bool userdata) bool userdata)
{ {
struct xfs_perag *pag;
struct rb_node *rbp; struct rb_node *rbp;
ASSERT(flen > 0); ASSERT(flen > 0);
pag = xfs_perag_get(mp, agno);
spin_lock(&pag->pagb_lock); spin_lock(&pag->pagb_lock);
restart: restart:
rbp = pag->pagb_tree.rb_node; rbp = pag->pagb_tree.rb_node;
...@@ -314,7 +303,6 @@ xfs_extent_busy_reuse( ...@@ -314,7 +303,6 @@ xfs_extent_busy_reuse(
goto restart; goto restart;
} }
spin_unlock(&pag->pagb_lock); spin_unlock(&pag->pagb_lock);
xfs_perag_put(pag);
} }
/* /*
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#define __XFS_EXTENT_BUSY_H__ #define __XFS_EXTENT_BUSY_H__
struct xfs_mount; struct xfs_mount;
struct xfs_perag;
struct xfs_trans; struct xfs_trans;
struct xfs_alloc_arg; struct xfs_alloc_arg;
...@@ -31,7 +32,7 @@ struct xfs_extent_busy { ...@@ -31,7 +32,7 @@ struct xfs_extent_busy {
}; };
void void
xfs_extent_busy_insert(struct xfs_trans *tp, xfs_agnumber_t agno, xfs_extent_busy_insert(struct xfs_trans *tp, struct xfs_perag *pag,
xfs_agblock_t bno, xfs_extlen_t len, unsigned int flags); xfs_agblock_t bno, xfs_extlen_t len, unsigned int flags);
void void
...@@ -39,11 +40,11 @@ xfs_extent_busy_clear(struct xfs_mount *mp, struct list_head *list, ...@@ -39,11 +40,11 @@ xfs_extent_busy_clear(struct xfs_mount *mp, struct list_head *list,
bool do_discard); bool do_discard);
int int
xfs_extent_busy_search(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_extent_busy_search(struct xfs_mount *mp, struct xfs_perag *pag,
xfs_agblock_t bno, xfs_extlen_t len); xfs_agblock_t bno, xfs_extlen_t len);
void void
xfs_extent_busy_reuse(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_extent_busy_reuse(struct xfs_mount *mp, struct xfs_perag *pag,
xfs_agblock_t fbno, xfs_extlen_t flen, bool userdata); xfs_agblock_t fbno, xfs_extlen_t flen, bool userdata);
bool bool
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment