diff options
author | Dave Chinner <dchinner@redhat.com> | 2023-02-12 23:14:54 +0100 |
---|---|---|
committer | Dave Chinner <dchinner@redhat.com> | 2023-02-12 23:14:54 +0100 |
commit | 5f36b2ce79f254dd00cdc88374271df7ce843d56 (patch) | |
tree | af462c68a7e91f992134c5b861f8215c28c0659e /fs/xfs/libxfs/xfs_alloc.c | |
parent | xfs: introduce xfs_alloc_vextent_near_bno() (diff) | |
download | linux-5f36b2ce79f254dd00cdc88374271df7ce843d56.tar.xz linux-5f36b2ce79f254dd00cdc88374271df7ce843d56.zip |
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 <dchinner@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs/libxfs/xfs_alloc.c')
-rw-r--r-- | fs/xfs/libxfs/xfs_alloc.c | 63 |
1 files changed, 54 insertions, 9 deletions
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,13 +3478,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. */ |