[PATCH 4/5] xfs: add infrastructure to support AF allocation algorithm

zhangshida posted 5 patches 2 weeks, 6 days ago
[PATCH 4/5] xfs: add infrastructure to support AF allocation algorithm
Posted by zhangshida 2 weeks, 6 days ago
From: Shida Zhang <zhangshida@kylinos.cn>

Add a function to search through all the AFs in a alloction.

Add two members in *args* to trace the current AF.

And properly initialize these members so as to keeping the
behavior exacly the same with the original code logic.

And for those bmbt alloction, we can slightly break the roles
imposed by AF, since it's allocating one block at a time.

Remember our goal to propose the concept of AF is to avoid a
badly fragmented filesystem to consume all the continuous free
space.

So just initialize it in a way like this alloctions are in a
AF ranging from [0, ag_count).

Signed-off-by: Shida Zhang <zhangshida@kylinos.cn>
---
 fs/xfs/libxfs/xfs_alloc.h      |  2 ++
 fs/xfs/libxfs/xfs_bmap.c       | 34 ++++++++++++++++++++++++++++++++++
 fs/xfs/libxfs/xfs_bmap_btree.c |  2 ++
 3 files changed, 38 insertions(+)

diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h
index 0165452e7cd0..ab34aceecc72 100644
--- a/fs/xfs/libxfs/xfs_alloc.h
+++ b/fs/xfs/libxfs/xfs_alloc.h
@@ -56,6 +56,8 @@ typedef struct xfs_alloc_arg {
 	bool		alloc_minlen_only; /* allocate exact minlen extent */
 	struct xfs_owner_info	oinfo;	/* owner of blocks being allocated */
 	enum xfs_ag_resv_type	resv;	/* block reservation to use */
+	xfs_agnumber_t	curr_af;	/* start agno of the allocation field */
+	xfs_agnumber_t	next_af;	/* next point of the allocation field */
 } xfs_alloc_arg_t;
 
 /*
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 36dd08d13293..b55b8670730c 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -683,6 +683,8 @@ xfs_bmap_extents_to_btree(
 	args.minlen = args.maxlen = args.prod = 1;
 	args.wasdel = wasdel;
 	*logflagsp = 0;
+	args.curr_af = 0;
+	args.next_af = mp->m_sb.sb_agcount;
 	error = xfs_alloc_vextent_start_ag(&args,
 				XFS_INO_TO_FSB(mp, ip->i_ino));
 	if (error)
@@ -830,6 +832,8 @@ xfs_bmap_local_to_extents(
 	 */
 	args.total = total;
 	args.minlen = args.maxlen = args.prod = 1;
+	args.curr_af = 0;
+	args.next_af = args.mp->m_sb.sb_agcount;
 	error = xfs_alloc_vextent_start_ag(&args,
 			XFS_INO_TO_FSB(args.mp, ip->i_ino));
 	if (error)
@@ -3630,6 +3634,8 @@ xfs_bmap_btalloc_low_space(
 
 	if (args->minlen > ap->minlen) {
 		args->minlen = ap->minlen;
+		args->curr_af = 0;
+		args->next_af = args->mp->m_sb.sb_agcount;
 		error = xfs_alloc_vextent_start_ag(args, ap->blkno);
 		if (error || args->fsbno != NULLFSBLOCK)
 			return error;
@@ -3735,6 +3741,32 @@ xfs_bmap_btalloc_best_length(
 	return xfs_bmap_btalloc_low_space(ap, args);
 }
 
+static int
+xfs_bmap_btalloc_best_length_iterate_afs(
+	struct xfs_bmalloca	*ap,
+	struct xfs_alloc_arg	*args,
+	int			stripe_align)
+{
+	struct xfs_mount	*mp = ap->ip->i_mount;
+	int			error;
+	unsigned int i;
+
+	args->curr_af = 0;
+
+	for (i = 0; args->curr_af < mp->m_sb.sb_agcount; i++) {
+		args->next_af = mp->m_sb.sb_agcount - mp->m_af[i];
+		error = xfs_bmap_btalloc_best_length(ap, args, stripe_align);
+		if (error || args->fsbno != NULLFSBLOCK)
+			break;
+
+		args->curr_af = args->next_af;
+		/* Exit LOWMODE when going to the next AF. */
+		ap->tp->t_flags &= ~XFS_TRANS_LOWMODE;
+	}
+
+	return error;
+}
+
 static int
 xfs_bmap_btalloc(
 	struct xfs_bmalloca	*ap)
@@ -3751,6 +3783,8 @@ xfs_bmap_btalloc(
 		.datatype	= ap->datatype,
 		.alignment	= 1,
 		.minalignslop	= 0,
+		.curr_af        = 0,
+		.next_af        = mp->m_sb.sb_agcount,
 	};
 	xfs_fileoff_t		orig_offset;
 	xfs_extlen_t		orig_length;
diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c
index 3464be771f95..4e57b6f897e8 100644
--- a/fs/xfs/libxfs/xfs_bmap_btree.c
+++ b/fs/xfs/libxfs/xfs_bmap_btree.c
@@ -234,6 +234,8 @@ xfs_bmbt_alloc_block(
 		args.minleft = xfs_bmapi_minleft(cur->bc_tp, cur->bc_ino.ip,
 					cur->bc_ino.whichfork);
 
+	args.curr_af = 0;
+	args.next_af = args.mp->m_sb.sb_agcount;
 	error = xfs_alloc_vextent_start_ag(&args, be64_to_cpu(start->l));
 	if (error)
 		return error;
-- 
2.33.0