]> www.infradead.org Git - users/hch/xfs.git/commitdiff
xfs: switch perag iteration from the for_each macros to a while based iterator
authorChristoph Hellwig <hch@lst.de>
Fri, 20 Sep 2024 13:37:43 +0000 (15:37 +0200)
committerChristoph Hellwig <hch@lst.de>
Sun, 22 Sep 2024 05:37:31 +0000 (07:37 +0200)
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>
17 files changed:
fs/xfs/libxfs/xfs_ag.h
fs/xfs/libxfs/xfs_sb.c
fs/xfs/libxfs/xfs_types.c
fs/xfs/scrub/bmap.c
fs/xfs/scrub/bmap_repair.c
fs/xfs/scrub/fscounters.c
fs/xfs/scrub/health.c
fs/xfs/scrub/inode_repair.c
fs/xfs/xfs_discard.c
fs/xfs/xfs_extent_busy.c
fs/xfs/xfs_fsmap.c
fs/xfs/xfs_fsops.c
fs/xfs/xfs_health.c
fs/xfs/xfs_icache.c
fs/xfs/xfs_iwalk.c
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_reflink.c

index b08daa27fb5879f9db657ccc94a3f48b43cdc928..5e1f2c59740ddb45423c233f34deb19538391333 100644 (file)
@@ -202,6 +202,34 @@ xfs_perag_rele(
        xfs_group_rele(&pag->pag_group);
 }
 
+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->pag_group : 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
  */
@@ -267,40 +295,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->pag_group.xg_index + 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,
index d2012fbf07aa651f964cbefac30e881707d2daba..061c8c961d5bc9b473b31dc9aeb8447199eafc6a 100644 (file)
@@ -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;
 }
 
index c299b16c9365fab61b98e13bebc38607d9768f87..c91db4f51407437342696e8e114d6b5248a8ac48 100644 (file)
@@ -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;
 }
index a43912227dd478ae9afc54f8164c6465585d276f..fb022b403716b14ac62e5ace23600b626555b304 100644 (file)
@@ -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)) {
index b6cbe756b985e21fa3d76b9fdc5ee5882b28dae3..7d5efd4dd7d79ad5f2af6b0308c805815a387ea9 100644 (file)
@@ -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);
index 1d3e98346933e1100d951af3ce77618b1d00aa0f..28db0c83819c20416239d46700cfaa58cae9c09c 100644 (file)
@@ -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 @@ retry:
        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 @@ retry:
                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;
                }
index b712a8bd34f5435b87c448c0c2b8d399ec2236bf..112dd05e5551d3c1e39630f2ca3a36af56c98408 100644 (file)
@@ -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);
index 3e45b9b72312abaf49f0edc0617f784c8c004b7e..5da9e1a387a8bbc70416751ab8eeeaa3124ea352 100644 (file)
@@ -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);
index dfd6edcebb6ea48f432a68c34e3575124cc1f937..739ec69c44281cf6c68102bafb737f7ecee8c935 100644 (file)
@@ -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)
index 79b0f833c511e3ddc557f885f01dca16d1c934ac..3d5a57d7ac5e1417e50c624ea29da13767a6d0e0 100644 (file)
@@ -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))
index 918e1c38a15592cb7d26d8d09f591678d0cb3a4d..a26fb054346b68441c518e3c203525a033ee404c 100644 (file)
@@ -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.
index b247d895c276d2b436eafe16c1d8611422c531b7..82812a458cf10f6bcc8270aafcbee74dcc956de9 100644 (file)
@@ -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);
 }
index d6492128582a3e4158f72e942091d6e06109e380..ff5aca875ab0d0cb93316dae065989c6dc02bc66 100644 (file)
@@ -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);
index e9d7cd441f40caad4f2e7052d34fc207992659bc..40f821f145011822e83126e21d256b60cfbfb8bd 100644 (file)
@@ -1372,13 +1372,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);
 }
index ec2d56f1840fc6637beb6f4d1ad317a0ef9dcfd0..0463ef7ae09b5d2cdeb73ec6bc005c0af93cf8f5 100644 (file)
@@ -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);
        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))
index 16ce9b37daf6ae548dd85d100283f6b81dfa3183..dba11cc895bd2a1cbe4b87969b63d77ea22868e0 100644 (file)
@@ -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);
 }
 
index 0961ecf592c5bdf456b6f7688aa1bf6eb62b8c2c..5628e030af860466ff294feabe6591c25429142a 100644 (file)
@@ -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);