mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-28 16:52:18 +00:00
xfs: switch perag iteration from the for_each macros to a while based iterator
The current for_each_perag* macros are a bit annoying in that they require the caller to both provide an object and an index iterator, and also somewhat obsfucate the underlying control flow mechanism. Switch to open coded while loops using new xfs_perag_next{,_from,_range} helpers that return the next pag structure to iterate on based on the previous one or NULL for the loop start. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
This commit is contained in:
parent
819928770b
commit
86437e6abb
@ -208,6 +208,34 @@ xfs_perag_rele(
|
||||
xfs_group_rele(pag_group(pag));
|
||||
}
|
||||
|
||||
static inline struct xfs_perag *
|
||||
xfs_perag_next_range(
|
||||
struct xfs_mount *mp,
|
||||
struct xfs_perag *pag,
|
||||
xfs_agnumber_t start_agno,
|
||||
xfs_agnumber_t end_agno)
|
||||
{
|
||||
return to_perag(xfs_group_next_range(mp, pag ? pag_group(pag) : NULL,
|
||||
start_agno, end_agno, XG_TYPE_AG));
|
||||
}
|
||||
|
||||
static inline struct xfs_perag *
|
||||
xfs_perag_next_from(
|
||||
struct xfs_mount *mp,
|
||||
struct xfs_perag *pag,
|
||||
xfs_agnumber_t start_agno)
|
||||
{
|
||||
return xfs_perag_next_range(mp, pag, start_agno, mp->m_sb.sb_agcount - 1);
|
||||
}
|
||||
|
||||
static inline struct xfs_perag *
|
||||
xfs_perag_next(
|
||||
struct xfs_mount *mp,
|
||||
struct xfs_perag *pag)
|
||||
{
|
||||
return xfs_perag_next_from(mp, pag, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Per-ag geometry infomation and validation
|
||||
*/
|
||||
@ -273,40 +301,6 @@ xfs_ag_contains_log(struct xfs_mount *mp, xfs_agnumber_t agno)
|
||||
agno == XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perag iteration APIs
|
||||
*/
|
||||
static inline struct xfs_perag *
|
||||
xfs_perag_next(
|
||||
struct xfs_perag *pag,
|
||||
xfs_agnumber_t *agno,
|
||||
xfs_agnumber_t end_agno)
|
||||
{
|
||||
struct xfs_mount *mp = pag_mount(pag);
|
||||
|
||||
*agno = pag_agno(pag) + 1;
|
||||
xfs_perag_rele(pag);
|
||||
while (*agno <= end_agno) {
|
||||
pag = xfs_perag_grab(mp, *agno);
|
||||
if (pag)
|
||||
return pag;
|
||||
(*agno)++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define for_each_perag_range(mp, agno, end_agno, pag) \
|
||||
for ((pag) = xfs_perag_grab((mp), (agno)); \
|
||||
(pag) != NULL; \
|
||||
(pag) = xfs_perag_next((pag), &(agno), (end_agno)))
|
||||
|
||||
#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))
|
||||
|
||||
static inline struct xfs_perag *
|
||||
xfs_perag_next_wrap(
|
||||
struct xfs_perag *pag,
|
||||
|
@ -1109,14 +1109,13 @@ int
|
||||
xfs_update_secondary_sbs(
|
||||
struct xfs_mount *mp)
|
||||
{
|
||||
struct xfs_perag *pag;
|
||||
xfs_agnumber_t agno = 1;
|
||||
struct xfs_perag *pag = NULL;
|
||||
int saved_error = 0;
|
||||
int error = 0;
|
||||
LIST_HEAD (buffer_list);
|
||||
|
||||
/* update secondary superblocks. */
|
||||
for_each_perag_from(mp, agno, pag) {
|
||||
while ((pag = xfs_perag_next_from(mp, pag, 1))) {
|
||||
struct xfs_buf *bp;
|
||||
|
||||
error = xfs_buf_get(mp->m_ddev_targp,
|
||||
@ -1146,7 +1145,7 @@ xfs_update_secondary_sbs(
|
||||
xfs_buf_relse(bp);
|
||||
|
||||
/* don't hold too many buffers at once */
|
||||
if (agno % 16)
|
||||
if (pag_agno(pag) % 16)
|
||||
continue;
|
||||
|
||||
error = xfs_buf_delwri_submit(&buffer_list);
|
||||
@ -1160,12 +1159,8 @@ xfs_update_secondary_sbs(
|
||||
}
|
||||
}
|
||||
error = xfs_buf_delwri_submit(&buffer_list);
|
||||
if (error) {
|
||||
xfs_warn(mp,
|
||||
"write error %d updating a secondary superblock near ag %d",
|
||||
error, agno);
|
||||
}
|
||||
|
||||
if (error)
|
||||
xfs_warn(mp, "error %d writing secondary superblocks", error);
|
||||
return saved_error ? saved_error : error;
|
||||
}
|
||||
|
||||
|
@ -170,13 +170,12 @@ xfs_icount_range(
|
||||
unsigned long long *max)
|
||||
{
|
||||
unsigned long long nr_inos = 0;
|
||||
struct xfs_perag *pag;
|
||||
xfs_agnumber_t agno;
|
||||
struct xfs_perag *pag = NULL;
|
||||
|
||||
/* root, rtbitmap, rtsum all live in the first chunk */
|
||||
*min = XFS_INODES_PER_CHUNK;
|
||||
|
||||
for_each_perag(mp, agno, pag)
|
||||
while ((pag = xfs_perag_next(mp, pag)))
|
||||
nr_inos += pag->agino_max - pag->agino_min + 1;
|
||||
*max = nr_inos;
|
||||
}
|
||||
|
@ -760,11 +760,10 @@ xchk_bmap_check_rmaps(
|
||||
struct xfs_scrub *sc,
|
||||
int whichfork)
|
||||
{
|
||||
struct xfs_perag *pag;
|
||||
xfs_agnumber_t agno;
|
||||
struct xfs_perag *pag = NULL;
|
||||
int error;
|
||||
|
||||
for_each_perag(sc->mp, agno, pag) {
|
||||
while ((pag = xfs_perag_next(sc->mp, pag))) {
|
||||
error = xchk_bmap_check_ag_rmaps(sc, whichfork, pag);
|
||||
if (error ||
|
||||
(sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) {
|
||||
|
@ -407,12 +407,11 @@ xrep_bmap_find_mappings(
|
||||
struct xrep_bmap *rb)
|
||||
{
|
||||
struct xfs_scrub *sc = rb->sc;
|
||||
struct xfs_perag *pag;
|
||||
xfs_agnumber_t agno;
|
||||
struct xfs_perag *pag = NULL;
|
||||
int error = 0;
|
||||
|
||||
/* Iterate the rmaps for extents. */
|
||||
for_each_perag(sc->mp, agno, pag) {
|
||||
while ((pag = xfs_perag_next(sc->mp, pag))) {
|
||||
error = xrep_bmap_scan_ag(rb, pag);
|
||||
if (error) {
|
||||
xfs_perag_rele(pag);
|
||||
|
@ -74,10 +74,9 @@ xchk_fscount_warmup(
|
||||
struct xfs_buf *agi_bp = NULL;
|
||||
struct xfs_buf *agf_bp = NULL;
|
||||
struct xfs_perag *pag = NULL;
|
||||
xfs_agnumber_t agno;
|
||||
int error = 0;
|
||||
|
||||
for_each_perag(mp, agno, pag) {
|
||||
while ((pag = xfs_perag_next(mp, pag))) {
|
||||
if (xchk_should_terminate(sc, &error))
|
||||
break;
|
||||
if (xfs_perag_initialised_agi(pag) &&
|
||||
@ -295,9 +294,8 @@ xchk_fscount_aggregate_agcounts(
|
||||
struct xchk_fscounters *fsc)
|
||||
{
|
||||
struct xfs_mount *mp = sc->mp;
|
||||
struct xfs_perag *pag;
|
||||
struct xfs_perag *pag = NULL;
|
||||
uint64_t delayed;
|
||||
xfs_agnumber_t agno;
|
||||
int tries = 8;
|
||||
int error = 0;
|
||||
|
||||
@ -306,7 +304,7 @@ xchk_fscount_aggregate_agcounts(
|
||||
fsc->ifree = 0;
|
||||
fsc->fdblocks = 0;
|
||||
|
||||
for_each_perag(mp, agno, pag) {
|
||||
while ((pag = xfs_perag_next(mp, pag))) {
|
||||
if (xchk_should_terminate(sc, &error))
|
||||
break;
|
||||
|
||||
@ -327,7 +325,7 @@ xchk_fscount_aggregate_agcounts(
|
||||
if (xfs_has_lazysbcount(sc->mp)) {
|
||||
fsc->fdblocks += pag->pagf_btreeblks;
|
||||
} else {
|
||||
error = xchk_fscount_btreeblks(sc, fsc, agno);
|
||||
error = xchk_fscount_btreeblks(sc, fsc, pag_agno(pag));
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
|
@ -160,12 +160,11 @@ STATIC void
|
||||
xchk_mark_all_healthy(
|
||||
struct xfs_mount *mp)
|
||||
{
|
||||
struct xfs_perag *pag;
|
||||
xfs_agnumber_t agno;
|
||||
struct xfs_perag *pag = NULL;
|
||||
|
||||
xfs_fs_mark_healthy(mp, XFS_SICK_FS_INDIRECT);
|
||||
xfs_rt_mark_healthy(mp, XFS_SICK_RT_INDIRECT);
|
||||
for_each_perag(mp, agno, pag)
|
||||
while ((pag = xfs_perag_next(mp, pag)))
|
||||
xfs_ag_mark_healthy(pag, XFS_SICK_AG_INDIRECT);
|
||||
}
|
||||
|
||||
@ -294,9 +293,7 @@ xchk_health_record(
|
||||
struct xfs_scrub *sc)
|
||||
{
|
||||
struct xfs_mount *mp = sc->mp;
|
||||
struct xfs_perag *pag;
|
||||
xfs_agnumber_t agno;
|
||||
|
||||
struct xfs_perag *pag = NULL;
|
||||
unsigned int sick;
|
||||
unsigned int checked;
|
||||
|
||||
@ -308,7 +305,7 @@ xchk_health_record(
|
||||
if (sick & XFS_SICK_RT_PRIMARY)
|
||||
xchk_set_corrupt(sc);
|
||||
|
||||
for_each_perag(mp, agno, pag) {
|
||||
while ((pag = xfs_perag_next(mp, pag))) {
|
||||
xfs_ag_measure_sickness(pag, &sick, &checked);
|
||||
if (sick & XFS_SICK_AG_PRIMARY)
|
||||
xchk_set_corrupt(sc);
|
||||
|
@ -761,14 +761,13 @@ STATIC int
|
||||
xrep_dinode_count_rmaps(
|
||||
struct xrep_inode *ri)
|
||||
{
|
||||
struct xfs_perag *pag;
|
||||
xfs_agnumber_t agno;
|
||||
struct xfs_perag *pag = NULL;
|
||||
int error;
|
||||
|
||||
if (!xfs_has_rmapbt(ri->sc->mp) || xfs_has_realtime(ri->sc->mp))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
for_each_perag(ri->sc->mp, agno, pag) {
|
||||
while ((pag = xfs_perag_next(ri->sc->mp, pag))) {
|
||||
error = xrep_dinode_count_ag_rmaps(ri, pag);
|
||||
if (error) {
|
||||
xfs_perag_rele(pag);
|
||||
|
@ -387,8 +387,8 @@ xfs_trim_datadev_extents(
|
||||
{
|
||||
xfs_agnumber_t start_agno, end_agno;
|
||||
xfs_agblock_t start_agbno, end_agbno;
|
||||
struct xfs_perag *pag = NULL;
|
||||
xfs_daddr_t ddev_end;
|
||||
struct xfs_perag *pag;
|
||||
int last_error = 0, error;
|
||||
|
||||
ddev_end = min_t(xfs_daddr_t, end,
|
||||
@ -399,10 +399,10 @@ xfs_trim_datadev_extents(
|
||||
end_agno = xfs_daddr_to_agno(mp, ddev_end);
|
||||
end_agbno = xfs_daddr_to_agbno(mp, ddev_end);
|
||||
|
||||
for_each_perag_range(mp, start_agno, end_agno, pag) {
|
||||
while ((pag = xfs_perag_next_range(mp, pag, start_agno, end_agno))) {
|
||||
xfs_agblock_t agend = pag->block_count;
|
||||
|
||||
if (start_agno == end_agno)
|
||||
if (pag_agno(pag) == end_agno)
|
||||
agend = end_agbno;
|
||||
error = xfs_trim_perag_extents(pag, start_agbno, agend, minlen);
|
||||
if (error)
|
||||
|
@ -629,11 +629,10 @@ void
|
||||
xfs_extent_busy_wait_all(
|
||||
struct xfs_mount *mp)
|
||||
{
|
||||
struct xfs_perag *pag;
|
||||
struct xfs_perag *pag = NULL;
|
||||
DEFINE_WAIT (wait);
|
||||
xfs_agnumber_t agno;
|
||||
|
||||
for_each_perag(mp, agno, pag) {
|
||||
while ((pag = xfs_perag_next(mp, pag))) {
|
||||
do {
|
||||
prepare_to_wait(&pag->pagb_wait, &wait, TASK_KILLABLE);
|
||||
if (RB_EMPTY_ROOT(&pag->pagb_tree))
|
||||
|
@ -460,11 +460,11 @@ __xfs_getfsmap_datadev(
|
||||
void *priv)
|
||||
{
|
||||
struct xfs_mount *mp = tp->t_mountp;
|
||||
struct xfs_perag *pag;
|
||||
struct xfs_perag *pag = NULL;
|
||||
struct xfs_btree_cur *bt_cur = NULL;
|
||||
xfs_fsblock_t start_fsb;
|
||||
xfs_fsblock_t end_fsb;
|
||||
xfs_agnumber_t start_ag, end_ag, ag;
|
||||
xfs_agnumber_t start_ag, end_ag;
|
||||
uint64_t eofs;
|
||||
int error = 0;
|
||||
|
||||
@ -512,8 +512,7 @@ __xfs_getfsmap_datadev(
|
||||
start_ag = XFS_FSB_TO_AGNO(mp, start_fsb);
|
||||
end_ag = XFS_FSB_TO_AGNO(mp, end_fsb);
|
||||
|
||||
ag = start_ag;
|
||||
for_each_perag_range(mp, ag, end_ag, pag) {
|
||||
while ((pag = xfs_perag_next_range(mp, pag, start_ag, end_ag))) {
|
||||
/*
|
||||
* Set the AG high key from the fsmap high key if this
|
||||
* is the last AG that we're querying.
|
||||
|
@ -528,13 +528,12 @@ int
|
||||
xfs_fs_reserve_ag_blocks(
|
||||
struct xfs_mount *mp)
|
||||
{
|
||||
xfs_agnumber_t agno;
|
||||
struct xfs_perag *pag;
|
||||
struct xfs_perag *pag = NULL;
|
||||
int error = 0;
|
||||
int err2;
|
||||
|
||||
mp->m_finobt_nores = false;
|
||||
for_each_perag(mp, agno, pag) {
|
||||
while ((pag = xfs_perag_next(mp, pag))) {
|
||||
err2 = xfs_ag_resv_init(pag, NULL);
|
||||
if (err2 && !error)
|
||||
error = err2;
|
||||
@ -556,9 +555,8 @@ void
|
||||
xfs_fs_unreserve_ag_blocks(
|
||||
struct xfs_mount *mp)
|
||||
{
|
||||
xfs_agnumber_t agno;
|
||||
struct xfs_perag *pag;
|
||||
struct xfs_perag *pag = NULL;
|
||||
|
||||
for_each_perag(mp, agno, pag)
|
||||
while ((pag = xfs_perag_next(mp, pag)))
|
||||
xfs_ag_resv_free(pag);
|
||||
}
|
||||
|
@ -28,8 +28,7 @@ void
|
||||
xfs_health_unmount(
|
||||
struct xfs_mount *mp)
|
||||
{
|
||||
struct xfs_perag *pag;
|
||||
xfs_agnumber_t agno;
|
||||
struct xfs_perag *pag = NULL;
|
||||
unsigned int sick = 0;
|
||||
unsigned int checked = 0;
|
||||
bool warn = false;
|
||||
@ -38,7 +37,7 @@ xfs_health_unmount(
|
||||
return;
|
||||
|
||||
/* Measure AG corruption levels. */
|
||||
for_each_perag(mp, agno, pag) {
|
||||
while ((pag = xfs_perag_next(mp, pag))) {
|
||||
xfs_ag_measure_sickness(pag, &sick, &checked);
|
||||
if (sick) {
|
||||
trace_xfs_ag_unfixed_corruption(pag, sick);
|
||||
|
@ -1383,13 +1383,12 @@ void
|
||||
xfs_blockgc_stop(
|
||||
struct xfs_mount *mp)
|
||||
{
|
||||
struct xfs_perag *pag;
|
||||
xfs_agnumber_t agno;
|
||||
struct xfs_perag *pag = NULL;
|
||||
|
||||
if (!xfs_clear_blockgc_enabled(mp))
|
||||
return;
|
||||
|
||||
for_each_perag(mp, agno, pag)
|
||||
while ((pag = xfs_perag_next(mp, pag)))
|
||||
cancel_delayed_work_sync(&pag->pag_blockgc_work);
|
||||
trace_xfs_blockgc_stop(mp, __return_address);
|
||||
}
|
||||
|
@ -540,23 +540,25 @@ xfs_iwalk_args(
|
||||
unsigned int flags)
|
||||
{
|
||||
struct xfs_mount *mp = iwag->mp;
|
||||
xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, iwag->startino);
|
||||
xfs_agnumber_t start_agno;
|
||||
int error;
|
||||
|
||||
ASSERT(agno < mp->m_sb.sb_agcount);
|
||||
start_agno = XFS_INO_TO_AGNO(iwag->mp, iwag->startino);
|
||||
ASSERT(start_agno < iwag->mp->m_sb.sb_agcount);
|
||||
ASSERT(!(flags & ~XFS_IWALK_FLAGS_ALL));
|
||||
|
||||
error = xfs_iwalk_alloc(iwag);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
for_each_perag_from(mp, agno, iwag->pag) {
|
||||
while ((iwag->pag = xfs_perag_next_from(mp, iwag->pag, start_agno))) {
|
||||
error = xfs_iwalk_ag(iwag);
|
||||
if (error || (flags & XFS_IWALK_SAME_AG)) {
|
||||
xfs_perag_rele(iwag->pag);
|
||||
break;
|
||||
}
|
||||
iwag->startino = XFS_AGINO_TO_INO(mp, agno + 1, 0);
|
||||
iwag->startino =
|
||||
XFS_AGINO_TO_INO(mp, pag_agno(iwag->pag) + 1, 0);
|
||||
}
|
||||
|
||||
xfs_iwalk_free(iwag);
|
||||
@ -644,19 +646,19 @@ xfs_iwalk_threaded(
|
||||
bool polled,
|
||||
void *data)
|
||||
{
|
||||
xfs_agnumber_t start_agno = XFS_INO_TO_AGNO(mp, startino);
|
||||
struct xfs_pwork_ctl pctl;
|
||||
struct xfs_perag *pag;
|
||||
xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, startino);
|
||||
struct xfs_perag *pag = NULL;
|
||||
int error;
|
||||
|
||||
ASSERT(agno < mp->m_sb.sb_agcount);
|
||||
ASSERT(start_agno < mp->m_sb.sb_agcount);
|
||||
ASSERT(!(flags & ~XFS_IWALK_FLAGS_ALL));
|
||||
|
||||
error = xfs_pwork_init(mp, &pctl, xfs_iwalk_ag_work, "xfs_iwalk");
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
for_each_perag_from(mp, agno, pag) {
|
||||
while ((pag = xfs_perag_next_from(mp, pag, start_agno))) {
|
||||
struct xfs_iwalk_ag *iwag;
|
||||
|
||||
if (xfs_pwork_ctl_want_abort(&pctl))
|
||||
|
@ -2845,10 +2845,9 @@ static void
|
||||
xlog_recover_process_iunlinks(
|
||||
struct xlog *log)
|
||||
{
|
||||
struct xfs_perag *pag;
|
||||
xfs_agnumber_t agno;
|
||||
struct xfs_perag *pag = NULL;
|
||||
|
||||
for_each_perag(log->l_mp, agno, pag)
|
||||
while ((pag = xfs_perag_next(log->l_mp, pag)))
|
||||
xlog_recover_iunlink_ag(pag);
|
||||
}
|
||||
|
||||
|
@ -894,14 +894,13 @@ int
|
||||
xfs_reflink_recover_cow(
|
||||
struct xfs_mount *mp)
|
||||
{
|
||||
struct xfs_perag *pag;
|
||||
xfs_agnumber_t agno;
|
||||
struct xfs_perag *pag = NULL;
|
||||
int error = 0;
|
||||
|
||||
if (!xfs_has_reflink(mp))
|
||||
return 0;
|
||||
|
||||
for_each_perag(mp, agno, pag) {
|
||||
while ((pag = xfs_perag_next(mp, pag))) {
|
||||
error = xfs_refcount_recover_cow_leftovers(mp, pag);
|
||||
if (error) {
|
||||
xfs_perag_rele(pag);
|
||||
|
Loading…
Reference in New Issue
Block a user