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:
parent
dc60992ce7
commit
81a1e1c32e
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user