aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2023-05-09 11:30:25 +0200
committerCarlos Maiolino <cem@kernel.org>2023-05-10 14:14:31 +0200
commit156536950159c460d8d1bc19f3cde01c4fccadcb (patch)
tree237d1db56150991c998ac3e59b6db3563478931b
parent1a5a98d5d16121ed01da27d177f91b6531669a99 (diff)
downloadxfsprogs-dev-156536950159c460d8d1bc19f3cde01c4fccadcb.tar.gz
xfs: introduce xfs_alloc_vextent_near_bno()
Source kernel commit: db4710fd12248e5d4c3842520cd13f034136576b 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> Signed-off-by: Carlos Maiolino <cem@kernel.org>
-rw-r--r--libxfs/xfs_alloc.c50
-rw-r--r--libxfs/xfs_alloc.h14
-rw-r--r--libxfs/xfs_bmap.c6
-rw-r--r--libxfs/xfs_ialloc.c27
-rw-r--r--libxfs/xfs_ialloc_btree.c5
-rw-r--r--libxfs/xfs_refcount_btree.c7
6 files changed, 55 insertions, 54 deletions
diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c
index 798d7a5be2..797d1a2aa8 100644
--- a/libxfs/xfs_alloc.c
+++ b/libxfs/xfs_alloc.c
@@ -3475,35 +3475,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. */
diff --git a/libxfs/xfs_alloc.h b/libxfs/xfs_alloc.h
index 80e2c16f4c..45a428e770 100644
--- a/libxfs/xfs_alloc.h
+++ b/libxfs/xfs_alloc.h
@@ -114,19 +114,19 @@ xfs_alloc_log_agf(
uint32_t fields);/* mask of fields to be logged (XFS_AGF_...) */
/*
- * Allocate an extent (variable-size).
- */
-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);
/*
+ * 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_near_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 31b65f88f5..ea52414256 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -3239,7 +3239,6 @@ xfs_bmap_btalloc_filestreams(
int notinit = 0;
int error;
- args->type = XFS_ALLOCTYPE_NEAR_BNO;
args->total = ap->total;
start_agno = XFS_FSB_TO_AGNO(mp, ap->blkno);
@@ -3558,7 +3557,7 @@ xfs_bmap_btalloc_at_eof(
}
if (ag_only)
- error = xfs_alloc_vextent(args);
+ error = xfs_alloc_vextent_near_bno(args, ap->blkno);
else
error = xfs_alloc_vextent_start_ag(args, ap->blkno);
if (error)
@@ -3605,7 +3604,6 @@ xfs_bmap_btalloc_best_length(
ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino);
}
xfs_bmap_adjacent(ap);
- args->fsbno = ap->blkno;
/*
* Search for an allocation group with a single extent large enough for
@@ -3646,7 +3644,7 @@ xfs_bmap_btalloc_best_length(
}
if (is_filestream)
- error = xfs_alloc_vextent(args);
+ error = xfs_alloc_vextent_near_bno(args, ap->blkno);
else
error = xfs_alloc_vextent_start_ag(args, ap->blkno);
if (error)
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index c9a47296b9..77ea0ce261 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -713,22 +713,16 @@ xfs_ialloc_ag_alloc(
} else
args.alignment = igeo->cluster_align;
/*
- * Need to figure out where to allocate the inode blocks.
- * Ideally they should be spaced out through the a.g.
- * For now, just allocate blocks up front.
- */
- args.agbno = be32_to_cpu(agi->agi_root);
- args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno);
- /*
* Allocate a fixed-size extent of inodes.
*/
- args.type = XFS_ALLOCTYPE_NEAR_BNO;
args.prod = 1;
/*
* Allow space for the inode btree to split.
*/
args.minleft = igeo->inobt_maxlevels;
- error = xfs_alloc_vextent_this_ag(&args);
+ error = xfs_alloc_vextent_near_bno(&args,
+ XFS_AGB_TO_FSB(args.mp, pag->pag_agno,
+ be32_to_cpu(agi->agi_root)));
if (error)
return error;
}
@@ -738,11 +732,11 @@ xfs_ialloc_ag_alloc(
* alignment.
*/
if (isaligned && args.fsbno == NULLFSBLOCK) {
- args.type = XFS_ALLOCTYPE_NEAR_BNO;
- args.agbno = be32_to_cpu(agi->agi_root);
- args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno);
args.alignment = igeo->cluster_align;
- if ((error = xfs_alloc_vextent(&args)))
+ error = xfs_alloc_vextent_near_bno(&args,
+ XFS_AGB_TO_FSB(args.mp, pag->pag_agno,
+ be32_to_cpu(agi->agi_root)));
+ if (error)
return error;
}
@@ -754,9 +748,6 @@ xfs_ialloc_ag_alloc(
igeo->ialloc_min_blks < igeo->ialloc_blks &&
args.fsbno == NULLFSBLOCK) {
sparse_alloc:
- args.type = XFS_ALLOCTYPE_NEAR_BNO;
- args.agbno = be32_to_cpu(agi->agi_root);
- args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno);
args.alignment = args.mp->m_sb.sb_spino_align;
args.prod = 1;
@@ -778,7 +769,9 @@ sparse_alloc:
args.mp->m_sb.sb_inoalignmt) -
igeo->ialloc_blks;
- error = xfs_alloc_vextent_this_ag(&args);
+ error = xfs_alloc_vextent_near_bno(&args,
+ XFS_AGB_TO_FSB(args.mp, pag->pag_agno,
+ be32_to_cpu(agi->agi_root)));
if (error)
return error;
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index e10c1f078e..2f3d1e8d04 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -104,14 +104,13 @@ __xfs_inobt_alloc_block(
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;
args.maxlen = 1;
args.prod = 1;
- args.type = XFS_ALLOCTYPE_NEAR_BNO;
args.resv = resv;
- error = xfs_alloc_vextent_this_ag(&args);
+ error = xfs_alloc_vextent_near_bno(&args,
+ XFS_AGB_TO_FSB(args.mp, args.pag->pag_agno, sbno));
if (error)
return error;
diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c
index 970ff2dafb..2fbf2e2a72 100644
--- a/libxfs/xfs_refcount_btree.c
+++ b/libxfs/xfs_refcount_btree.c
@@ -67,14 +67,13 @@ xfs_refcountbt_alloc_block(
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));
args.oinfo = XFS_RMAP_OINFO_REFC;
args.minlen = args.maxlen = args.prod = 1;
args.resv = XFS_AG_RESV_METADATA;
- error = xfs_alloc_vextent_this_ag(&args);
+ error = xfs_alloc_vextent_near_bno(&args,
+ XFS_AGB_TO_FSB(args.mp, args.pag->pag_agno,
+ xfs_refc_block(args.mp)));
if (error)
goto out_error;
trace_xfs_refcountbt_alloc_block(cur->bc_mp, cur->bc_ag.pag->pag_agno,