1

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: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
This commit is contained in:
Christoph Hellwig 2024-10-23 15:37:23 +02:00 committed by Carlos Maiolino
parent dc60992ce7
commit 81a1e1c32e

View File

@ -67,22 +67,28 @@ xfs_filestream_pick_ag(
xfs_extlen_t minfree, maxfree = 0; xfs_extlen_t minfree, maxfree = 0;
xfs_agnumber_t agno; xfs_agnumber_t agno;
bool first_pass = true; bool first_pass = true;
int err;
/* 2% of an AG's blocks must be free for it to be chosen. */ /* 2% of an AG's blocks must be free for it to be chosen. */
minfree = mp->m_sb.sb_agblocks / 50; minfree = mp->m_sb.sb_agblocks / 50;
restart: restart:
for_each_perag_wrap(mp, start_agno, agno, pag) { for_each_perag_wrap(mp, start_agno, agno, pag) {
int err;
trace_xfs_filestream_scan(pag, pino); trace_xfs_filestream_scan(pag, pino);
*longest = 0; *longest = 0;
err = xfs_bmap_longest_free_extent(pag, NULL, longest); err = xfs_bmap_longest_free_extent(pag, NULL, longest);
if (err) { if (err) {
if (err != -EAGAIN) if (err == -EAGAIN) {
break; /* Couldn't lock the AGF, skip this AG. */
/* Couldn't lock the AGF, skip this AG. */ err = 0;
err = 0; continue;
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. */ /* Keep track of the AG with the most free blocks. */
@ -107,7 +113,9 @@ restart:
!(flags & XFS_PICK_USERDATA) || !(flags & XFS_PICK_USERDATA) ||
(flags & XFS_PICK_LOWSPACE))) { (flags & XFS_PICK_LOWSPACE))) {
/* Break out, retaining the reference on the AG. */ /* Break out, retaining the reference on the AG. */
break; if (max_pag)
xfs_perag_rele(max_pag);
goto done;
} }
} }
@ -115,56 +123,44 @@ restart:
atomic_dec(&pag->pagf_fstrms); atomic_dec(&pag->pagf_fstrms);
} }
if (err) { /*
xfs_perag_rele(pag); * Allow a second pass to give xfs_bmap_longest_free_extent() another
if (max_pag) * attempt at locking AGFs that it might have skipped over before we
xfs_perag_rele(max_pag); * fail.
return err; */
if (first_pass) {
first_pass = false;
goto restart;
} }
if (!pag) { /*
/* * We must be low on data space, so run a final lowspace optimised
* Allow a second pass to give xfs_bmap_longest_free_extent() * selection pass if we haven't already.
* another attempt at locking AGFs that it might have skipped */
* over before we fail. if (!(flags & XFS_PICK_LOWSPACE)) {
*/ flags |= XFS_PICK_LOWSPACE;
if (first_pass) { goto restart;
first_pass = false;
goto restart;
}
/*
* 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;
goto restart;
}
/*
* 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) {
max_pag = pag;
break;
}
/* Bail if there are no AGs at all to select from. */
if (!max_pag)
return -ENOSPC;
}
pag = max_pag;
atomic_inc(&pag->pagf_fstrms);
} else if (max_pag) {
xfs_perag_rele(max_pag);
} }
/*
* 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) {
max_pag = pag;
break;
}
/* Bail if there are no AGs at all to select from. */
if (!max_pag)
return -ENOSPC;
}
pag = max_pag;
atomic_inc(&pag->pagf_fstrms);
done:
trace_xfs_filestream_pick(pag, pino); trace_xfs_filestream_pick(pag, pino);
args->pag = pag; args->pag = pag;
return 0; return 0;