From: Dave Chinner Date: Tue, 9 May 2023 09:29:57 +0000 (+0200) Subject: xfs: use xfs_alloc_vextent_this_ag() where appropriate X-Git-Tag: v6.3.0~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=04215b9fb594d93112201061d0d3d06cecbc37b4;p=thirdparty%2Fxfsprogs-dev.git xfs: use xfs_alloc_vextent_this_ag() where appropriate Source kernel commit: 74c36a8689d3d8ca9d9e96759c9bbf337e049097 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 Signed-off-by: Carlos Maiolino --- diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c index fb289ed2a..554afdb17 100644 --- a/libxfs/xfs_ag.c +++ b/libxfs/xfs_ag.c @@ -885,6 +885,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, @@ -936,7 +937,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/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c index 37f0a296e..8b15237b2 100644 --- a/libxfs/xfs_alloc.c +++ b/libxfs/xfs_alloc.c @@ -2719,7 +2719,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) @@ -3267,14 +3266,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) @@ -3289,11 +3291,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; } @@ -3476,6 +3475,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; @@ -3484,17 +3484,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/libxfs/xfs_alloc.h b/libxfs/xfs_alloc.h index 2c3f762df..0a9ad6cd1 100644 --- a/libxfs/xfs_alloc.h +++ b/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/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index 89948e4e2..a8083b5c4 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -782,6 +782,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 @@ -3499,8 +3501,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; @@ -3521,7 +3522,6 @@ xfs_bmap_btalloc( xfs_bmap_adjacent(ap); - tryagain = isaligned = 0; args.fsbno = ap->blkno; args.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE; @@ -3569,9 +3569,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 @@ -3588,34 +3588,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 @@ -3643,8 +3646,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/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c index 076c2066a..b93ffbea0 100644 --- a/libxfs/xfs_bmap_btree.c +++ b/libxfs/xfs_bmap_btree.c @@ -19,6 +19,7 @@ #include "xfs_bmap.h" #include "xfs_trace.h" #include "xfs_rmap.h" +#include "xfs_ag.h" static struct kmem_cache *xfs_bmbt_cur_cache; @@ -198,14 +199,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; @@ -220,15 +225,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) { /* @@ -241,7 +240,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)) { @@ -260,9 +259,6 @@ xfs_bmbt_alloc_block( *stat = 1; return 0; - - error0: - return error; } STATIC int diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c index 043bf2689..c9a47296b 100644 --- a/libxfs/xfs_ialloc.c +++ b/libxfs/xfs_ialloc.c @@ -625,6 +625,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 */ @@ -678,7 +679,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; /* @@ -726,7 +728,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; } @@ -775,7 +778,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/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c index cc4f6d6e1..e10c1f078 100644 --- a/libxfs/xfs_ialloc_btree.c +++ b/libxfs/xfs_ialloc_btree.c @@ -102,6 +102,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; @@ -110,7 +111,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/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c index a91026037..970ff2daf 100644 --- a/libxfs/xfs_refcount_btree.c +++ b/libxfs/xfs_refcount_btree.c @@ -66,6 +66,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)); @@ -73,7 +74,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,