Commit 81a1e1c3 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Carlos Maiolino
Browse files

xfs: streamline xfs_filestream_pick_ag



Directly return the error from xfs_bmap_longest_free_extent instead
of breaking from the loop and handling it there, and use a done
label to directly jump to the exist when we found a suitable perag
structure to reduce the indentation level and pag/max_pag check
complexity in the tail of the function.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarCarlos Maiolino <cem@kernel.org>
parent dc60992c
Loading
Loading
Loading
Loading
+46 −50
Original line number Diff line number Diff line
@@ -67,23 +67,29 @@ xfs_filestream_pick_ag(
	xfs_extlen_t		minfree, maxfree = 0;
	xfs_agnumber_t		agno;
	bool			first_pass = true;
	int			err;

	/* 2% of an AG's blocks must be free for it to be chosen. */
	minfree = mp->m_sb.sb_agblocks / 50;

restart:
	for_each_perag_wrap(mp, start_agno, agno, pag) {
		int		err;

		trace_xfs_filestream_scan(pag, pino);

		*longest = 0;
		err = xfs_bmap_longest_free_extent(pag, NULL, longest);
		if (err) {
			if (err != -EAGAIN)
				break;
			if (err == -EAGAIN) {
				/* Couldn't lock the AGF, skip this AG. */
				err = 0;
				continue;
			}
			xfs_perag_rele(pag);
			if (max_pag)
				xfs_perag_rele(max_pag);
			return err;
		}

		/* Keep track of the AG with the most free blocks. */
		if (pag->pagf_freeblks > maxfree) {
@@ -107,7 +113,9 @@ xfs_filestream_pick_ag(
			     !(flags & XFS_PICK_USERDATA) ||
			     (flags & XFS_PICK_LOWSPACE))) {
				/* Break out, retaining the reference on the AG. */
				break;
				if (max_pag)
					xfs_perag_rele(max_pag);
				goto done;
			}
		}

@@ -115,18 +123,10 @@ xfs_filestream_pick_ag(
		atomic_dec(&pag->pagf_fstrms);
	}

	if (err) {
		xfs_perag_rele(pag);
		if (max_pag)
			xfs_perag_rele(max_pag);
		return err;
	}

	if (!pag) {
	/*
		 * Allow a second pass to give xfs_bmap_longest_free_extent()
		 * another attempt at locking AGFs that it might have skipped
		 * over before we fail.
	 * Allow a second pass to give xfs_bmap_longest_free_extent() another
	 * attempt at locking AGFs that it might have skipped over before we
	 * fail.
	 */
	if (first_pass) {
		first_pass = false;
@@ -134,8 +134,8 @@ xfs_filestream_pick_ag(
	}

	/*
		 * We must be low on data space, so run a final lowspace
		 * optimised selection pass if we haven't already.
	 * We must be low on data space, so run a final lowspace optimised
	 * selection pass if we haven't already.
	 */
	if (!(flags & XFS_PICK_LOWSPACE)) {
		flags |= XFS_PICK_LOWSPACE;
@@ -143,10 +143,9 @@ xfs_filestream_pick_ag(
	}

	/*
		 * No unassociated AGs are available, so select the AG with the
		 * most free space, regardless of whether it's already in use by
		 * another filestream. It none suit, just use whatever AG we can
		 * grab.
	 * No unassociated AGs are available, so select the AG with the most
	 * free space, regardless of whether it's already in use by another
	 * filestream. It none suit, just use whatever AG we can grab.
	 */
	if (!max_pag) {
		for_each_perag_wrap(args->mp, 0, start_agno, pag) {
@@ -161,10 +160,7 @@ xfs_filestream_pick_ag(

	pag = max_pag;
	atomic_inc(&pag->pagf_fstrms);
	} else if (max_pag) {
		xfs_perag_rele(max_pag);
	}

done:
	trace_xfs_filestream_pick(pag, pino);
	args->pag = pag;
	return 0;