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 | db4710fd12248e5d4c3842520cd13f034136576b (patch) | |
tree | 140a8b7168b32dbf46a8040d1e48e162a527a00b /fs/xfs/libxfs/xfs_alloc.c | |
parent | xfs: use xfs_alloc_vextent_start_bno() where appropriate (diff) | |
download | linux-db4710fd12248e5d4c3842520cd13f034136576b.tar.xz linux-db4710fd12248e5d4c3842520cd13f034136576b.zip |
xfs: introduce xfs_alloc_vextent_near_bno()
The remaining callers of xfs_alloc_vextent() are all doing NEAR_BNO
allocations. We can replace that function with a new
xfs_alloc_vextent_near_bno() function that does this explicitly.
We also multiplex NEAR_BNO allocations through
xfs_alloc_vextent_this_ag via args->type. Replace all of these with
direct calls to xfs_alloc_vextent_near_bno(), too.
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 | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 008b3622b286..85e3b65286ac 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3479,35 +3479,47 @@ xfs_alloc_vextent_first_ag( } /* - * Allocate an extent (variable-size). - * Depending on the allocation type, we either look in a single allocation - * group or loop over the allocation groups to find the result. + * Allocate an extent as close to the target as possible. If there are not + * viable candidates in the AG, then fail the allocation. */ int -xfs_alloc_vextent( - struct xfs_alloc_arg *args) +xfs_alloc_vextent_near_bno( + struct xfs_alloc_arg *args, + xfs_fsblock_t target) { + struct xfs_mount *mp = args->mp; + bool need_pag = !args->pag; xfs_agnumber_t minimum_agno = 0; int error; if (args->tp->t_highest_agno != NULLAGNUMBER) minimum_agno = args->tp->t_highest_agno; - switch (args->type) { - case XFS_ALLOCTYPE_THIS_AG: - case XFS_ALLOCTYPE_NEAR_BNO: - case XFS_ALLOCTYPE_THIS_BNO: - 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; - default: - error = -EFSCORRUPTED; - ASSERT(0); - break; + error = xfs_alloc_vextent_check_args(args, target); + if (error) { + if (error == -ENOSPC) + return 0; + return error; } - 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->type = XFS_ALLOCTYPE_NEAR_BNO; + if (need_pag) + args->pag = xfs_perag_get(args->mp, args->agno); + error = xfs_alloc_ag_vextent(args); + if (need_pag) + xfs_perag_put(args->pag); + if (error) + return error; + + xfs_alloc_vextent_set_fsbno(args, minimum_agno); + return 0; } /* Ensure that the freelist is at full capacity. */ |