Commit 5f36b2ce authored by Dave Chinner's avatar Dave Chinner
Browse files

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: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
parent db4710fd
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -888,7 +888,6 @@ xfs_ag_shrink_space(
		.tp	= *tpp,
		.mp	= mp,
		.pag	= pag,
		.type	= XFS_ALLOCTYPE_THIS_BNO,
		.minlen = delta,
		.maxlen = delta,
		.oinfo	= XFS_RMAP_OINFO_SKIP_UPDATE,
@@ -920,8 +919,6 @@ xfs_ag_shrink_space(
	if (delta >= aglen)
		return -EINVAL;

	args.fsbno = XFS_AGB_TO_FSB(mp, pag->pag_agno, aglen - delta);

	/*
	 * Make sure that the last inode cluster cannot overlap with the new
	 * end of the AG, even if it's sparse.
@@ -939,7 +936,8 @@ xfs_ag_shrink_space(
		return error;

	/* internal log shouldn't also show up in the free space btrees */
	error = xfs_alloc_vextent_this_ag(&args);
	error = xfs_alloc_vextent_exact_bno(&args,
			XFS_AGB_TO_FSB(mp, pag->pag_agno, aglen - delta));
	if (!error && args.agbno == NULLAGBLOCK)
		error = -ENOSPC;

+54 −9
Original line number Diff line number Diff line
@@ -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);
@@ -3478,6 +3484,45 @@ xfs_alloc_vextent_first_ag(
	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.
+10 −3
Original line number Diff line number Diff line
@@ -114,10 +114,10 @@ xfs_alloc_log_agf(
	uint32_t	fields);/* mask of fields to be logged (XFS_AGF_...) */

/*
 * Allocate an extent in the specific AG defined by args->fsbno. If there is no
 * space in that AG, then the allocation will fail.
 * Allocate an extent anywhere in the specific AG given. If there is no
 * space matching the requirements in that AG, then the allocation will fail.
 */
int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args);
int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args, xfs_agnumber_t agno);

/*
 * Allocate an extent as close to the target as possible. If there are not
@@ -126,6 +126,13 @@ int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args);
int xfs_alloc_vextent_near_bno(struct xfs_alloc_arg *args,
		xfs_fsblock_t target);

/*
 * Allocate an extent exactly at the target given. If this is not possible
 * then the allocation fails.
 */
int xfs_alloc_vextent_exact_bno(struct xfs_alloc_arg *args,
		xfs_fsblock_t target);

/*
 * Best effort full filesystem allocation scan.
 *
+2 −4
Original line number Diff line number Diff line
@@ -3514,7 +3514,6 @@ xfs_bmap_btalloc_at_eof(
		xfs_extlen_t	nextminlen = 0;

		atype = args->type;
		args->type = XFS_ALLOCTYPE_THIS_BNO;
		args->alignment = 1;

		/*
@@ -3532,8 +3531,8 @@ xfs_bmap_btalloc_at_eof(
		else
			args->minalignslop = 0;

		args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, args->fsbno));
		error = xfs_alloc_vextent_this_ag(args);
		args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, ap->blkno));
		error = xfs_alloc_vextent_exact_bno(args, ap->blkno);
		xfs_perag_put(args->pag);
		if (error)
			return error;
@@ -3546,7 +3545,6 @@ xfs_bmap_btalloc_at_eof(
		 */
		args->pag = NULL;
		args->type = atype;
		args->fsbno = ap->blkno;
		args->alignment = stripe_align;
		args->minlen = nextminlen;
		args->minalignslop = 0;
+3 −3
Original line number Diff line number Diff line
@@ -662,8 +662,6 @@ xfs_ialloc_ag_alloc(
		goto sparse_alloc;
	if (likely(newino != NULLAGINO &&
		  (args.agbno < be32_to_cpu(agi->agi_length)))) {
		args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno);
		args.type = XFS_ALLOCTYPE_THIS_BNO;
		args.prod = 1;

		/*
@@ -684,7 +682,9 @@ xfs_ialloc_ag_alloc(

		/* Allow space for the inode btree to split. */
		args.minleft = igeo->inobt_maxlevels;
		error = xfs_alloc_vextent_this_ag(&args);
		error = xfs_alloc_vextent_exact_bno(&args,
				XFS_AGB_TO_FSB(args.mp, pag->pag_agno,
						args.agbno));
		if (error)
			return error;

Loading