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,23 +67,29 @@ 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. */
if (pag->pagf_freeblks > maxfree) { if (pag->pagf_freeblks > maxfree) {
@ -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,18 +123,10 @@ restart:
atomic_dec(&pag->pagf_fstrms); 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() * Allow a second pass to give xfs_bmap_longest_free_extent() another
* another attempt at locking AGFs that it might have skipped * attempt at locking AGFs that it might have skipped over before we
* over before we fail. * fail.
*/ */
if (first_pass) { if (first_pass) {
first_pass = false; first_pass = false;
@ -134,8 +134,8 @@ restart:
} }
/* /*
* We must be low on data space, so run a final lowspace * We must be low on data space, so run a final lowspace optimised
* optimised selection pass if we haven't already. * selection pass if we haven't already.
*/ */
if (!(flags & XFS_PICK_LOWSPACE)) { if (!(flags & XFS_PICK_LOWSPACE)) {
flags |= XFS_PICK_LOWSPACE; flags |= XFS_PICK_LOWSPACE;
@ -143,10 +143,9 @@ restart:
} }
/* /*
* No unassociated AGs are available, so select the AG with the * No unassociated AGs are available, so select the AG with the most
* most free space, regardless of whether it's already in use by * free space, regardless of whether it's already in use by another
* another filestream. It none suit, just use whatever AG we can * filestream. It none suit, just use whatever AG we can grab.
* grab.
*/ */
if (!max_pag) { if (!max_pag) {
for_each_perag_wrap(args->mp, 0, start_agno, pag) { for_each_perag_wrap(args->mp, 0, start_agno, pag) {
@ -161,10 +160,7 @@ restart:
pag = max_pag; pag = max_pag;
atomic_inc(&pag->pagf_fstrms); atomic_inc(&pag->pagf_fstrms);
} else if (max_pag) { done:
xfs_perag_rele(max_pag);
}
trace_xfs_filestream_pick(pag, pino); trace_xfs_filestream_pick(pag, pino);
args->pag = pag; args->pag = pag;
return 0; return 0;