diff options
author | Dave Chinner <dchinner@redhat.com> | 2023-05-09 11:30:26 +0200 |
---|---|---|
committer | Carlos Maiolino <cem@kernel.org> | 2023-05-10 14:30:42 +0200 |
commit | c4e10f2b0807d62ae50f48405b7e98104f1a6ee6 (patch) | |
tree | f4f6676c176cd93f9b21041b421c8847ea8376b4 | |
parent | 156536950159c460d8d1bc19f3cde01c4fccadcb (diff) | |
download | xfsprogs-dev-c4e10f2b0807d62ae50f48405b7e98104f1a6ee6.tar.gz |
xfs: introduce xfs_alloc_vextent_exact_bno()
Source kernel commit: 5f36b2ce79f254dd00cdc88374271df7ce843d56
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 <dchinner@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
-rw-r--r-- | libxfs/xfs_ag.c | 6 | ||||
-rw-r--r-- | libxfs/xfs_alloc.c | 63 | ||||
-rw-r--r-- | libxfs/xfs_alloc.h | 13 | ||||
-rw-r--r-- | libxfs/xfs_bmap.c | 6 | ||||
-rw-r--r-- | libxfs/xfs_ialloc.c | 6 |
5 files changed, 71 insertions, 23 deletions
diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c index 554afdb17d..224ee005ca 100644 --- a/libxfs/xfs_ag.c +++ b/libxfs/xfs_ag.c @@ -886,7 +886,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, @@ -918,8 +917,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. @@ -937,7 +934,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/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c index 797d1a2aa8..993403c089 100644 --- a/libxfs/xfs_alloc.c +++ b/libxfs/xfs_alloc.c @@ -3268,28 +3268,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); @@ -3468,13 +3474,52 @@ 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/libxfs/xfs_alloc.h b/libxfs/xfs_alloc.h index 45a428e770..63d5ad4ed8 100644 --- a/libxfs/xfs_alloc.h +++ b/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 @@ -127,6 +127,13 @@ 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. * * Locality aware allocation will be attempted in the initial AG, but on failure diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index ea52414256..df63dc5c50 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -3507,7 +3507,6 @@ xfs_bmap_btalloc_at_eof( xfs_extlen_t nextminlen = 0; atype = args->type; - args->type = XFS_ALLOCTYPE_THIS_BNO; args->alignment = 1; /* @@ -3525,8 +3524,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; @@ -3539,7 +3538,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/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c index 77ea0ce261..791880a30e 100644 --- a/libxfs/xfs_ialloc.c +++ b/libxfs/xfs_ialloc.c @@ -657,8 +657,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; /* @@ -679,7 +677,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; |