summaryrefslogtreecommitdiffstats
path: root/fs/xfs/libxfs/xfs_alloc.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2023-02-12 23:14:54 +0100
committerDave Chinner <dchinner@redhat.com>2023-02-12 23:14:54 +0100
commitdb4710fd12248e5d4c3842520cd13f034136576b (patch)
tree140a8b7168b32dbf46a8040d1e48e162a527a00b /fs/xfs/libxfs/xfs_alloc.c
parentxfs: use xfs_alloc_vextent_start_bno() where appropriate (diff)
downloadlinux-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.c50
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. */