From 7ac2ff8bb3713c7cb43564c04384af2ee7cc1f8d Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 13 Feb 2023 09:14:52 +1100 Subject: xfs: perags need atomic operational state We currently don't have any flags or operational state in the xfs_perag except for the pagf_init and pagi_init flags. And the agflreset flag. Oh, there's also the pagf_metadata and pagi_inodeok flags, too. For controlling per-ag operations, we are going to need some atomic state flags. Hence add an opstate field similar to what we already have in the mount and log, and convert all these state flags across to atomic bit operations. Signed-off-by: Dave Chinner Reviewed-by: Allison Henderson Reviewed-by: Darrick J. Wong --- fs/xfs/scrub/repair.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/xfs/scrub/repair.c') diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 4b92f9253ccd..d0b1644efb89 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -206,7 +206,7 @@ xrep_calc_ag_resblks( return 0; pag = xfs_perag_get(mp, sm->sm_agno); - if (pag->pagi_init) { + if (xfs_perag_initialised_agi(pag)) { /* Use in-core icount if possible. */ icount = pag->pagi_count; } else { -- cgit v1.2.3 From 74c36a8689d3d8ca9d9e96759c9bbf337e049097 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 13 Feb 2023 09:14:53 +1100 Subject: xfs: use xfs_alloc_vextent_this_ag() where appropriate Change obvious callers of single AG allocation to use xfs_alloc_vextent_this_ag(). Drive the per-ag grabbing out to the callers, too, so that callers with active references don't need to do new lookups just for an allocation in a context that already has a perag reference. The only remaining caller that does single AG allocation through xfs_alloc_vextent() is xfs_bmap_btalloc() with XFS_ALLOCTYPE_NEAR_BNO. That is going to need more untangling before it can be converted cleanly. Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_ag.c | 3 ++- fs/xfs/libxfs/xfs_alloc.c | 26 +++++++++++-------- fs/xfs/libxfs/xfs_alloc.h | 6 +++++ fs/xfs/libxfs/xfs_bmap.c | 52 ++++++++++++++++++++++---------------- fs/xfs/libxfs/xfs_bmap_btree.c | 22 +++++++--------- fs/xfs/libxfs/xfs_ialloc.c | 9 ++++--- fs/xfs/libxfs/xfs_ialloc_btree.c | 3 ++- fs/xfs/libxfs/xfs_refcount_btree.c | 3 ++- fs/xfs/scrub/repair.c | 3 ++- 9 files changed, 74 insertions(+), 53 deletions(-) (limited to 'fs/xfs/scrub/repair.c') diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index a3bdcde95845..053d77a283f7 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -887,6 +887,7 @@ xfs_ag_shrink_space( struct xfs_alloc_arg args = { .tp = *tpp, .mp = mp, + .pag = pag, .type = XFS_ALLOCTYPE_THIS_BNO, .minlen = delta, .maxlen = delta, @@ -938,7 +939,7 @@ xfs_ag_shrink_space( return error; /* internal log shouldn't also show up in the free space btrees */ - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_this_ag(&args); if (!error && args.agbno == NULLAGBLOCK) error = -ENOSPC; diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index edcbf8fd10ea..7e4452c11421 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2723,7 +2723,6 @@ xfs_alloc_fix_freelist( targs.agbp = agbp; targs.agno = args->agno; targs.alignment = targs.minlen = targs.prod = 1; - targs.type = XFS_ALLOCTYPE_THIS_AG; targs.pag = pag; error = xfs_alloc_read_agfl(pag, tp, &agflbp); if (error) @@ -3271,14 +3270,17 @@ xfs_alloc_vextent_set_fsbno( /* * Allocate within a single AG only. */ -static int +int xfs_alloc_vextent_this_ag( - struct xfs_alloc_arg *args, - xfs_agnumber_t minimum_agno) + struct xfs_alloc_arg *args) { struct xfs_mount *mp = args->mp; + xfs_agnumber_t minimum_agno = 0; int error; + if (args->tp->t_highest_agno != NULLAGNUMBER) + minimum_agno = args->tp->t_highest_agno; + error = xfs_alloc_vextent_check_args(args); if (error) { if (error == -ENOSPC) @@ -3293,11 +3295,8 @@ xfs_alloc_vextent_this_ag( return 0; } - args->pag = xfs_perag_get(mp, args->agno); error = xfs_alloc_ag_vextent(args); - xfs_alloc_vextent_set_fsbno(args, minimum_agno); - xfs_perag_put(args->pag); return error; } @@ -3480,6 +3479,7 @@ xfs_alloc_vextent( struct xfs_alloc_arg *args) { xfs_agnumber_t minimum_agno = 0; + int error; if (args->tp->t_highest_agno != NULLAGNUMBER) minimum_agno = args->tp->t_highest_agno; @@ -3488,17 +3488,21 @@ xfs_alloc_vextent( case XFS_ALLOCTYPE_THIS_AG: case XFS_ALLOCTYPE_NEAR_BNO: case XFS_ALLOCTYPE_THIS_BNO: - return xfs_alloc_vextent_this_ag(args, minimum_agno); + args->pag = xfs_perag_get(args->mp, + XFS_FSB_TO_AGNO(args->mp, args->fsbno)); + error = xfs_alloc_vextent_this_ag(args); + xfs_perag_put(args->pag); + break; case XFS_ALLOCTYPE_START_BNO: return xfs_alloc_vextent_start_ag(args, minimum_agno); case XFS_ALLOCTYPE_FIRST_AG: return xfs_alloc_vextent_first_ag(args, minimum_agno); default: + error = -EFSCORRUPTED; ASSERT(0); - /* NOTREACHED */ + break; } - /* Should never get here */ - return -EFSCORRUPTED; + return error; } /* Ensure that the freelist is at full capacity. */ diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 2c3f762dfb58..0a9ad6cd18e2 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -124,6 +124,12 @@ int /* error */ xfs_alloc_vextent( xfs_alloc_arg_t *args); /* allocation argument structure */ +/* + * Allocate an extent in the specific AG defined by args->fsbno. If there is no + * space in that AG, then the allocation will fail. + */ +int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args); + /* * Free an extent. */ diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 87ad56e034c0..baf11bc4d091 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -789,6 +789,8 @@ xfs_bmap_local_to_extents( memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = ip->i_mount; + args.total = total; + args.minlen = args.maxlen = args.prod = 1; xfs_rmap_ino_owner(&args.oinfo, ip->i_ino, whichfork, 0); /* * Allocate a block. We know we need only one, since the @@ -3506,8 +3508,7 @@ xfs_bmap_btalloc( xfs_extlen_t orig_length; xfs_extlen_t blen; xfs_extlen_t nextminlen = 0; - int isaligned; - int tryagain; + int isaligned = 0; int error; int stripe_align; @@ -3528,7 +3529,6 @@ xfs_bmap_btalloc( xfs_bmap_adjacent(ap); - tryagain = isaligned = 0; args.fsbno = ap->blkno; args.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE; @@ -3576,9 +3576,9 @@ xfs_bmap_btalloc( * allocation with alignment turned on. */ atype = args.type; - tryagain = 1; args.type = XFS_ALLOCTYPE_THIS_BNO; args.alignment = 1; + /* * Compute the minlen+alignment for the * next case. Set slop so that the value @@ -3595,34 +3595,37 @@ xfs_bmap_btalloc( args.minlen - 1; else args.minalignslop = 0; + + args.pag = xfs_perag_get(mp, + XFS_FSB_TO_AGNO(mp, args.fsbno)); + error = xfs_alloc_vextent_this_ag(&args); + xfs_perag_put(args.pag); + if (error) + return error; + + if (args.fsbno != NULLFSBLOCK) + goto out_success; + /* + * Exact allocation failed. Now try with alignment + * turned on. + */ + args.pag = NULL; + args.type = atype; + args.fsbno = ap->blkno; + args.alignment = stripe_align; + args.minlen = nextminlen; + args.minalignslop = 0; + isaligned = 1; } } else { args.alignment = 1; args.minalignslop = 0; } - args.minleft = ap->minleft; - args.wasdel = ap->wasdel; - args.resv = XFS_AG_RESV_NONE; - args.datatype = ap->datatype; error = xfs_alloc_vextent(&args); if (error) return error; - if (tryagain && args.fsbno == NULLFSBLOCK) { - /* - * Exact allocation failed. Now try with alignment - * turned on. - */ - args.type = atype; - args.fsbno = ap->blkno; - args.alignment = stripe_align; - args.minlen = nextminlen; - args.minalignslop = 0; - isaligned = 1; - if ((error = xfs_alloc_vextent(&args))) - return error; - } if (isaligned && args.fsbno == NULLFSBLOCK) { /* * allocation failed, so turn off alignment and @@ -3650,8 +3653,13 @@ xfs_bmap_btalloc( return error; ap->tp->t_flags |= XFS_TRANS_LOWMODE; } + args.minleft = ap->minleft; + args.wasdel = ap->wasdel; + args.resv = XFS_AG_RESV_NONE; + args.datatype = ap->datatype; if (args.fsbno != NULLFSBLOCK) { +out_success: xfs_bmap_process_allocated_extent(ap, &args, orig_offset, orig_length); } else { diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index afd9b2d962a3..d42c1a1da1fc 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -21,6 +21,7 @@ #include "xfs_quota.h" #include "xfs_trace.h" #include "xfs_rmap.h" +#include "xfs_ag.h" static struct kmem_cache *xfs_bmbt_cur_cache; @@ -200,14 +201,18 @@ xfs_bmbt_alloc_block( union xfs_btree_ptr *new, int *stat) { - xfs_alloc_arg_t args; /* block allocation args */ - int error; /* error return value */ + struct xfs_alloc_arg args; + int error; memset(&args, 0, sizeof(args)); args.tp = cur->bc_tp; args.mp = cur->bc_mp; xfs_rmap_ino_bmbt_owner(&args.oinfo, cur->bc_ino.ip->i_ino, cur->bc_ino.whichfork); + args.minlen = args.maxlen = args.prod = 1; + args.wasdel = cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL; + if (!args.wasdel && args.tp->t_blk_res == 0) + return -ENOSPC; args.fsbno = be64_to_cpu(start->l); args.type = XFS_ALLOCTYPE_START_BNO; @@ -222,15 +227,9 @@ xfs_bmbt_alloc_block( args.minleft = xfs_bmapi_minleft(cur->bc_tp, cur->bc_ino.ip, cur->bc_ino.whichfork); - args.minlen = args.maxlen = args.prod = 1; - args.wasdel = cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL; - if (!args.wasdel && args.tp->t_blk_res == 0) { - error = -ENOSPC; - goto error0; - } error = xfs_alloc_vextent(&args); if (error) - goto error0; + return error; if (args.fsbno == NULLFSBLOCK && args.minleft) { /* @@ -243,7 +242,7 @@ xfs_bmbt_alloc_block( args.type = XFS_ALLOCTYPE_START_BNO; error = xfs_alloc_vextent(&args); if (error) - goto error0; + return error; cur->bc_tp->t_flags |= XFS_TRANS_LOWMODE; } if (WARN_ON_ONCE(args.fsbno == NULLFSBLOCK)) { @@ -262,9 +261,6 @@ xfs_bmbt_alloc_block( *stat = 1; return 0; - - error0: - return error; } STATIC int diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 20d2365524a4..74ad88853a8c 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -630,6 +630,7 @@ xfs_ialloc_ag_alloc( args.mp = tp->t_mountp; args.fsbno = NULLFSBLOCK; args.oinfo = XFS_RMAP_OINFO_INODES; + args.pag = pag; #ifdef DEBUG /* randomly do sparse inode allocations */ @@ -683,7 +684,8 @@ xfs_ialloc_ag_alloc( /* Allow space for the inode btree to split. */ args.minleft = igeo->inobt_maxlevels; - if ((error = xfs_alloc_vextent(&args))) + error = xfs_alloc_vextent_this_ag(&args); + if (error) return error; /* @@ -731,7 +733,8 @@ xfs_ialloc_ag_alloc( * Allow space for the inode btree to split. */ args.minleft = igeo->inobt_maxlevels; - if ((error = xfs_alloc_vextent(&args))) + error = xfs_alloc_vextent_this_ag(&args); + if (error) return error; } @@ -780,7 +783,7 @@ sparse_alloc: args.mp->m_sb.sb_inoalignmt) - igeo->ialloc_blks; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_this_ag(&args); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index 3675a0d29310..fa6cd2502970 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -103,6 +103,7 @@ __xfs_inobt_alloc_block( memset(&args, 0, sizeof(args)); args.tp = cur->bc_tp; args.mp = cur->bc_mp; + args.pag = cur->bc_ag.pag; args.oinfo = XFS_RMAP_OINFO_INOBT; args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_ag.pag->pag_agno, sbno); args.minlen = 1; @@ -111,7 +112,7 @@ __xfs_inobt_alloc_block( args.type = XFS_ALLOCTYPE_NEAR_BNO; args.resv = resv; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_this_ag(&args); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index d20abf0390fc..a980fb18bde2 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -67,6 +67,7 @@ xfs_refcountbt_alloc_block( memset(&args, 0, sizeof(args)); args.tp = cur->bc_tp; args.mp = cur->bc_mp; + args.pag = cur->bc_ag.pag; args.type = XFS_ALLOCTYPE_NEAR_BNO; args.fsbno = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_ag.pag->pag_agno, xfs_refc_block(args.mp)); @@ -74,7 +75,7 @@ xfs_refcountbt_alloc_block( args.minlen = args.maxlen = args.prod = 1; args.resv = XFS_AG_RESV_METADATA; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_this_ag(&args); if (error) goto out_error; trace_xfs_refcountbt_alloc_block(cur->bc_mp, cur->bc_ag.pag->pag_agno, diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index d0b1644efb89..5f4b50aac4bb 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -326,6 +326,7 @@ xrep_alloc_ag_block( args.tp = sc->tp; args.mp = sc->mp; + args.pag = sc->sa.pag; args.oinfo = *oinfo; args.fsbno = XFS_AGB_TO_FSB(args.mp, sc->sa.pag->pag_agno, 0); args.minlen = 1; @@ -334,7 +335,7 @@ xrep_alloc_ag_block( args.type = XFS_ALLOCTYPE_THIS_AG; args.resv = resv; - error = xfs_alloc_vextent(&args); + error = xfs_alloc_vextent_this_ag(&args); if (error) return error; if (args.fsbno == NULLFSBLOCK) -- cgit v1.2.3 From 5f36b2ce79f254dd00cdc88374271df7ce843d56 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 13 Feb 2023 09:14:54 +1100 Subject: xfs: introduce xfs_alloc_vextent_exact_bno() Two of the callers to xfs_alloc_vextent_this_ag() actually want exact block number allocation, not anywhere-in-ag allocation. Split this out from _this_ag() as a first class citizen so no external extent allocation code needs to care about args->type anymore. Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_ag.c | 6 ++--- fs/xfs/libxfs/xfs_alloc.c | 63 +++++++++++++++++++++++++++++++++++++++------- fs/xfs/libxfs/xfs_alloc.h | 13 +++++++--- fs/xfs/libxfs/xfs_bmap.c | 6 ++--- fs/xfs/libxfs/xfs_ialloc.c | 6 ++--- fs/xfs/scrub/repair.c | 4 +-- 6 files changed, 72 insertions(+), 26 deletions(-) (limited to 'fs/xfs/scrub/repair.c') diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index 053d77a283f7..86696a1c6891 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -888,7 +888,6 @@ xfs_ag_shrink_space( .tp = *tpp, .mp = mp, .pag = pag, - .type = XFS_ALLOCTYPE_THIS_BNO, .minlen = delta, .maxlen = delta, .oinfo = XFS_RMAP_OINFO_SKIP_UPDATE, @@ -920,8 +919,6 @@ xfs_ag_shrink_space( if (delta >= aglen) return -EINVAL; - args.fsbno = XFS_AGB_TO_FSB(mp, pag->pag_agno, aglen - delta); - /* * Make sure that the last inode cluster cannot overlap with the new * end of the AG, even if it's sparse. @@ -939,7 +936,8 @@ xfs_ag_shrink_space( return error; /* internal log shouldn't also show up in the free space btrees */ - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_exact_bno(&args, + XFS_AGB_TO_FSB(mp, pag->pag_agno, aglen - delta)); if (!error && args.agbno == NULLAGBLOCK) error = -ENOSPC; diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 85e3b65286ac..5093fa856f35 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3272,28 +3272,34 @@ xfs_alloc_vextent_set_fsbno( */ int xfs_alloc_vextent_this_ag( - struct xfs_alloc_arg *args) + struct xfs_alloc_arg *args, + xfs_agnumber_t agno) { struct xfs_mount *mp = args->mp; xfs_agnumber_t minimum_agno = 0; + xfs_rfsblock_t target = XFS_AGB_TO_FSB(mp, agno, 0); int error; if (args->tp->t_highest_agno != NULLAGNUMBER) minimum_agno = args->tp->t_highest_agno; - error = xfs_alloc_vextent_check_args(args, args->fsbno); + if (minimum_agno > agno) { + trace_xfs_alloc_vextent_skip_deadlock(args); + args->fsbno = NULLFSBLOCK; + return 0; + } + + error = xfs_alloc_vextent_check_args(args, target); if (error) { if (error == -ENOSPC) return 0; return error; } - args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); - if (minimum_agno > args->agno) { - trace_xfs_alloc_vextent_skip_deadlock(args); - args->fsbno = NULLFSBLOCK; - return 0; - } + args->agno = agno; + args->agbno = 0; + args->fsbno = target; + args->type = XFS_ALLOCTYPE_THIS_AG; error = xfs_alloc_ag_vextent(args); xfs_alloc_vextent_set_fsbno(args, minimum_agno); @@ -3472,12 +3478,51 @@ xfs_alloc_vextent_first_ag( start_agno = max(minimum_agno, XFS_FSB_TO_AGNO(mp, target)); args->type = XFS_ALLOCTYPE_THIS_AG; args->fsbno = target; - error = xfs_alloc_vextent_iterate_ags(args, minimum_agno, + error = xfs_alloc_vextent_iterate_ags(args, minimum_agno, start_agno, 0); xfs_alloc_vextent_set_fsbno(args, minimum_agno); return error; } +/* + * Allocate within a single AG only. + */ +int +xfs_alloc_vextent_exact_bno( + struct xfs_alloc_arg *args, + xfs_fsblock_t target) +{ + struct xfs_mount *mp = args->mp; + xfs_agnumber_t minimum_agno = 0; + int error; + + if (args->tp->t_highest_agno != NULLAGNUMBER) + minimum_agno = args->tp->t_highest_agno; + + error = xfs_alloc_vextent_check_args(args, target); + if (error) { + if (error == -ENOSPC) + return 0; + return error; + } + + args->agno = XFS_FSB_TO_AGNO(mp, target); + if (minimum_agno > args->agno) { + trace_xfs_alloc_vextent_skip_deadlock(args); + return 0; + } + + args->agbno = XFS_FSB_TO_AGBNO(mp, target); + args->fsbno = target; + args->type = XFS_ALLOCTYPE_THIS_BNO; + error = xfs_alloc_ag_vextent(args); + if (error) + return error; + + xfs_alloc_vextent_set_fsbno(args, minimum_agno); + return 0; +} + /* * Allocate an extent as close to the target as possible. If there are not * viable candidates in the AG, then fail the allocation. diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 45a428e770f0..63d5ad4ed8a3 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -114,10 +114,10 @@ xfs_alloc_log_agf( uint32_t fields);/* mask of fields to be logged (XFS_AGF_...) */ /* - * Allocate an extent in the specific AG defined by args->fsbno. If there is no - * space in that AG, then the allocation will fail. + * Allocate an extent anywhere in the specific AG given. If there is no + * space matching the requirements in that AG, then the allocation will fail. */ -int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args); +int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args, xfs_agnumber_t agno); /* * Allocate an extent as close to the target as possible. If there are not @@ -126,6 +126,13 @@ int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args); int xfs_alloc_vextent_near_bno(struct xfs_alloc_arg *args, xfs_fsblock_t target); +/* + * Allocate an extent exactly at the target given. If this is not possible + * then the allocation fails. + */ +int xfs_alloc_vextent_exact_bno(struct xfs_alloc_arg *args, + xfs_fsblock_t target); + /* * Best effort full filesystem allocation scan. * diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index da5809d3d004..c507645f3031 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3514,7 +3514,6 @@ xfs_bmap_btalloc_at_eof( xfs_extlen_t nextminlen = 0; atype = args->type; - args->type = XFS_ALLOCTYPE_THIS_BNO; args->alignment = 1; /* @@ -3532,8 +3531,8 @@ xfs_bmap_btalloc_at_eof( else args->minalignslop = 0; - args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, args->fsbno)); - error = xfs_alloc_vextent_this_ag(args); + args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, ap->blkno)); + error = xfs_alloc_vextent_exact_bno(args, ap->blkno); xfs_perag_put(args->pag); if (error) return error; @@ -3546,7 +3545,6 @@ xfs_bmap_btalloc_at_eof( */ args->pag = NULL; args->type = atype; - args->fsbno = ap->blkno; args->alignment = stripe_align; args->minlen = nextminlen; args->minalignslop = 0; diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index b85f038de9e3..82ea6aa5af10 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -662,8 +662,6 @@ xfs_ialloc_ag_alloc( goto sparse_alloc; if (likely(newino != NULLAGINO && (args.agbno < be32_to_cpu(agi->agi_length)))) { - args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno); - args.type = XFS_ALLOCTYPE_THIS_BNO; args.prod = 1; /* @@ -684,7 +682,9 @@ xfs_ialloc_ag_alloc( /* Allow space for the inode btree to split. */ args.minleft = igeo->inobt_maxlevels; - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_exact_bno(&args, + XFS_AGB_TO_FSB(args.mp, pag->pag_agno, + args.agbno)); if (error) return error; diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 5f4b50aac4bb..1b71174ec0d6 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -328,14 +328,12 @@ xrep_alloc_ag_block( args.mp = sc->mp; args.pag = sc->sa.pag; args.oinfo = *oinfo; - args.fsbno = XFS_AGB_TO_FSB(args.mp, sc->sa.pag->pag_agno, 0); args.minlen = 1; args.maxlen = 1; args.prod = 1; - args.type = XFS_ALLOCTYPE_THIS_AG; args.resv = resv; - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_this_ag(&args, sc->sa.pag->pag_agno); if (error) return error; if (args.fsbno == NULLFSBLOCK) -- cgit v1.2.3