Commit db4710fd authored by Dave Chinner's avatar Dave Chinner
Browse files

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: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
parent 2a7f6d41
Loading
Loading
Loading
Loading
+31 −19
Original line number Diff line number Diff line
@@ -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;
	}

	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. */
+7 −7
Original line number Diff line number Diff line
@@ -113,19 +113,19 @@ xfs_alloc_log_agf(
	struct xfs_buf	*bp,	/* buffer for a.g. freelist header */
	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.
 *
+2 −4
Original line number Diff line number Diff line
@@ -3246,7 +3246,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);
@@ -3565,7 +3564,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)
@@ -3612,7 +3611,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
@@ -3653,7 +3651,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)
+10 −17
Original line number Diff line number Diff line
@@ -717,23 +717,17 @@ xfs_ialloc_ag_alloc(
			isaligned = 1;
		} 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;
	}
@@ -743,11 +737,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;
	}

@@ -759,9 +753,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;

@@ -783,7 +774,9 @@ xfs_ialloc_ag_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;

+2 −3
Original line number Diff line number Diff line
@@ -105,14 +105,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;

Loading