]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs_repair: refactor phase4
authorChristoph Hellwig <hch@lst.de>
Mon, 5 Aug 2024 19:32:34 +0000 (12:32 -0700)
committerChristoph Hellwig <hch@lst.de>
Tue, 6 Aug 2024 12:53:50 +0000 (05:53 -0700)
Split out helpers to process all duplicate extents in an AG and the RT
duplicate extents.

Signed-off-by: Christoph Hellwig <hch@lst.de>
repair/phase4.c

index cfdea1460e54e67c85526eb754691687e3611de2..fabe5f54506c1a421ca70eba358aa44f549361fa 100644 (file)
@@ -225,20 +225,122 @@ process_rmap_data(
        destroy_work_queue(&wq);
 }
 
+static void
+process_dup_rt_extents(
+       struct xfs_mount        *mp)
+{
+       xfs_rtxnum_t            rt_start = 0;
+       xfs_rtxlen_t            rt_len = 0;
+       xfs_rtxnum_t            rtx;
+
+       for (rtx = 0; rtx < mp->m_sb.sb_rextents; rtx++)  {
+               int state;
+
+               state = get_rtbmap(rtx);
+               switch (state) {
+               case XR_E_BAD_STATE:
+               default:
+                       do_warn(
+       _("unknown rt extent state %d, extent %" PRIu64 "\n"),
+                               state, rtx);
+                       fallthrough;
+               case XR_E_METADATA:
+               case XR_E_UNKNOWN:
+               case XR_E_FREE1:
+               case XR_E_FREE:
+               case XR_E_INUSE:
+               case XR_E_INUSE_FS:
+               case XR_E_INO:
+               case XR_E_FS_MAP:
+                       if (rt_start == 0)
+                               continue;
+                       /*
+                        * Add extent and reset extent state.
+                        */
+                       add_rt_dup_extent(rt_start, rt_len);
+                       rt_start = 0;
+                       rt_len = 0;
+                       break;
+               case XR_E_MULT:
+                       switch (rt_start)  {
+                       case 0:
+                               rt_start = rtx;
+                               rt_len = 1;
+                               break;
+                       case XFS_MAX_BMBT_EXTLEN:
+                               /*
+                                * Large extent case.
+                                */
+                               add_rt_dup_extent(rt_start, rt_len);
+                               rt_start = rtx;
+                               rt_len = 1;
+                               break;
+                       default:
+                               rt_len++;
+                               break;
+                       }
+                       break;
+               }
+       }
+
+       /*
+        * Catch the tail case, extent hitting the end of the RTG.
+        */
+       if (rt_start != 0)
+               add_rt_dup_extent(rt_start, rt_len);
+}
+
+/*
+ * Set up duplicate extent list for an AG or RTG.
+ */
+static void
+process_dup_extents(
+       xfs_agnumber_t          agno,
+       xfs_agblock_t           agbno,
+       xfs_agblock_t           ag_end)
+{
+       do {
+               int             bstate;
+               xfs_extlen_t    blen;
+
+               bstate = get_bmap_ext(agno, agbno, ag_end, &blen);
+               switch (bstate) {
+               case XR_E_FREE1:
+                       if (no_modify)
+                               do_warn(
+_("free space (%u,%u-%u) only seen by one free space btree\n"),
+                                       agno, agbno, agbno + blen - 1);
+                       break;
+               case XR_E_METADATA:
+               case XR_E_UNKNOWN:
+               case XR_E_FREE:
+               case XR_E_INUSE:
+               case XR_E_INUSE_FS:
+               case XR_E_INO:
+               case XR_E_FS_MAP:
+                       break;
+               case XR_E_MULT:
+                       add_dup_extent(agno, agbno, blen);
+                       break;
+               case XR_E_BAD_STATE:
+               default:
+                       do_warn(
+_("unknown block state, ag %d, blocks %u-%u\n"),
+                               agno, agbno, agbno + blen - 1);
+                       break;
+               }
+
+               agbno += blen;
+       } while (agbno < ag_end);
+}
+
 void
 phase4(xfs_mount_t *mp)
 {
        ino_tree_node_t         *irec;
-       xfs_rtxnum_t            rtx;
-       xfs_rtxnum_t            rt_start;
-       xfs_rtxlen_t            rt_len;
        xfs_agnumber_t          i;
-       xfs_agblock_t           j;
-       xfs_agblock_t           ag_end;
-       xfs_extlen_t            blen;
        int                     ag_hdr_len = 4 * mp->m_sb.sb_sectsize;
        int                     ag_hdr_block;
-       int                     bstate;
 
        if (rmap_needs_work(mp))
                collect_rmaps = true;
@@ -284,102 +386,19 @@ phase4(xfs_mount_t *mp)
        }
 
        for (i = 0; i < mp->m_sb.sb_agcount; i++)  {
+               xfs_agblock_t           ag_end;
+
                ag_end = (i < mp->m_sb.sb_agcount - 1) ? mp->m_sb.sb_agblocks :
                        mp->m_sb.sb_dblocks -
                                (xfs_rfsblock_t) mp->m_sb.sb_agblocks * i;
 
-               /*
-                * set up duplicate extent list for this ag
-                */
-               for (j = ag_hdr_block; j < ag_end; j += blen)  {
-                       bstate = get_bmap_ext(i, j, ag_end, &blen);
-                       switch (bstate) {
-                       case XR_E_FREE1:
-                               if (no_modify)
-                                       do_warn(
-       _("free space (%u,%u-%u) only seen by one free space btree\n"),
-                                               i, j, j + blen - 1);
-                               break;
-                       case XR_E_BAD_STATE:
-                       default:
-                               do_warn(
-                               _("unknown block state, ag %d, blocks %u-%u\n"),
-                                       i, j, j + blen - 1);
-                               fallthrough;
-                       case XR_E_METADATA:
-                       case XR_E_UNKNOWN:
-                       case XR_E_FREE:
-                       case XR_E_INUSE:
-                       case XR_E_INUSE_FS:
-                       case XR_E_INO:
-                       case XR_E_FS_MAP:
-                               break;
-                       case XR_E_MULT:
-                               add_dup_extent(i, j, blen);
-                               break;
-                       }
-               }
+               process_dup_extents(i, ag_hdr_block, ag_end);
 
                PROG_RPT_INC(prog_rpt_done[i], 1);
        }
        print_final_rpt();
 
-       /*
-        * initialize realtime bitmap
-        */
-       rt_start = 0;
-       rt_len = 0;
-
-       for (rtx = 0; rtx < mp->m_sb.sb_rextents; rtx++)  {
-               bstate = get_rtbmap(rtx);
-               switch (bstate)  {
-               case XR_E_BAD_STATE:
-               default:
-                       do_warn(
-       _("unknown rt extent state, extent %" PRIu64 "\n"),
-                               rtx);
-                       fallthrough;
-               case XR_E_METADATA:
-               case XR_E_UNKNOWN:
-               case XR_E_FREE1:
-               case XR_E_FREE:
-               case XR_E_INUSE:
-               case XR_E_INUSE_FS:
-               case XR_E_INO:
-               case XR_E_FS_MAP:
-                       if (rt_start == 0)
-                               continue;
-                       else  {
-                               /*
-                                * add extent and reset extent state
-                                */
-                               add_rt_dup_extent(rt_start, rt_len);
-                               rt_start = 0;
-                               rt_len = 0;
-                       }
-                       break;
-               case XR_E_MULT:
-                       if (rt_start == 0)  {
-                               rt_start = rtx;
-                               rt_len = 1;
-                       } else if (rt_len == XFS_MAX_BMBT_EXTLEN)  {
-                               /*
-                                * large extent case
-                                */
-                               add_rt_dup_extent(rt_start, rt_len);
-                               rt_start = rtx;
-                               rt_len = 1;
-                       } else
-                               rt_len++;
-                       break;
-               }
-       }
-
-       /*
-        * catch tail-case, extent hitting the end of the ag
-        */
-       if (rt_start != 0)
-               add_rt_dup_extent(rt_start, rt_len);
+       process_dup_rt_extents(mp);
 
        /*
         * initialize bitmaps for all AGs
@@ -413,8 +432,7 @@ phase4(xfs_mount_t *mp)
        /*
         * free up memory used to track trealtime duplicate extents
         */
-       if (rt_start != 0)
-               free_rt_dup_extent_tree(mp);
+       free_rt_dup_extent_tree(mp);
 
        /*
         * ensure consistency of quota inode pointers in superblock,