xfs: hoist xfs_scrub_agfl_walk to libxfs as xfs_agfl_walk

This function is basically a generic AGFL block iterator, so promote it
to libxfs ahead of online repair wanting to use it.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
This commit is contained in:
Darrick J. Wong 2018-05-14 06:34:34 -07:00
parent ddd10c2fe2
commit 9f3a080ef1
4 changed files with 55 additions and 69 deletions

View file

@ -3180,3 +3180,40 @@ xfs_alloc_has_record(
return xfs_btree_has_record(cur, &low, &high, exists);
}
/*
* Walk all the blocks in the AGFL. The @walk_fn can return any negative
* error code or XFS_BTREE_QUERY_RANGE_ABORT.
*/
int
xfs_agfl_walk(
struct xfs_mount *mp,
struct xfs_agf *agf,
struct xfs_buf *agflbp,
xfs_agfl_walk_fn walk_fn,
void *priv)
{
__be32 *agfl_bno;
unsigned int i;
int error;
agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp);
i = be32_to_cpu(agf->agf_flfirst);
/* Nothing to walk in an empty AGFL. */
if (agf->agf_flcount == cpu_to_be32(0))
return 0;
/* Otherwise, walk from first to last, wrapping as needed. */
for (;;) {
error = walk_fn(mp, be32_to_cpu(agfl_bno[i]), priv);
if (error)
return error;
if (i == be32_to_cpu(agf->agf_fllast))
break;
if (++i == xfs_agfl_size(mp))
i = 0;
}
return 0;
}