xfs: introduce xfs_for_each_perag_wrap()
In several places we iterate every AG from a specific start agno and wrap back to the first AG when we reach the end of the filesystem to continue searching. We don't have a primitive for this iteration yet, so add one for conversion of these algorithms to per-ag based iteration. The filestream AG select code is a mess, and this initially makes it worse. The per-ag selection needs to be driven completely into the filestream code to clean this up and it will be done in a future patch that makes the filestream allocator use active per-ag references correctly. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org>
This commit is contained in:
@ -237,7 +237,6 @@ xfs_perag_next(
|
||||
#define for_each_perag_from(mp, agno, pag) \
|
||||
for_each_perag_range((mp), (agno), (mp)->m_sb.sb_agcount - 1, (pag))
|
||||
|
||||
|
||||
#define for_each_perag(mp, agno, pag) \
|
||||
(agno) = 0; \
|
||||
for_each_perag_from((mp), (agno), (pag))
|
||||
@ -249,6 +248,50 @@ xfs_perag_next(
|
||||
xfs_perag_rele(pag), \
|
||||
(pag) = xfs_perag_grab_tag((mp), (agno), (tag)))
|
||||
|
||||
static inline struct xfs_perag *
|
||||
xfs_perag_next_wrap(
|
||||
struct xfs_perag *pag,
|
||||
xfs_agnumber_t *agno,
|
||||
xfs_agnumber_t stop_agno,
|
||||
xfs_agnumber_t wrap_agno)
|
||||
{
|
||||
struct xfs_mount *mp = pag->pag_mount;
|
||||
|
||||
*agno = pag->pag_agno + 1;
|
||||
xfs_perag_rele(pag);
|
||||
while (*agno != stop_agno) {
|
||||
if (*agno >= wrap_agno)
|
||||
*agno = 0;
|
||||
if (*agno == stop_agno)
|
||||
break;
|
||||
|
||||
pag = xfs_perag_grab(mp, *agno);
|
||||
if (pag)
|
||||
return pag;
|
||||
(*agno)++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate all AGs from start_agno through wrap_agno, then 0 through
|
||||
* (start_agno - 1).
|
||||
*/
|
||||
#define for_each_perag_wrap_at(mp, start_agno, wrap_agno, agno, pag) \
|
||||
for ((agno) = (start_agno), (pag) = xfs_perag_grab((mp), (agno)); \
|
||||
(pag) != NULL; \
|
||||
(pag) = xfs_perag_next_wrap((pag), &(agno), (start_agno), \
|
||||
(wrap_agno)))
|
||||
|
||||
/*
|
||||
* Iterate all AGs from start_agno through to the end of the filesystem, then 0
|
||||
* through (start_agno - 1).
|
||||
*/
|
||||
#define for_each_perag_wrap(mp, start_agno, agno, pag) \
|
||||
for_each_perag_wrap_at((mp), (start_agno), (mp)->m_sb.sb_agcount, \
|
||||
(agno), (pag))
|
||||
|
||||
|
||||
struct aghdr_init_data {
|
||||
/* per ag data */
|
||||
xfs_agblock_t agno; /* ag to init */
|
||||
|
Reference in New Issue
Block a user