]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
misc: use xfs_agfl_walk where appropriate
authorDarrick J. Wong <darrick.wong@oracle.com>
Wed, 1 Aug 2018 22:06:45 +0000 (17:06 -0500)
committerEric Sandeen <sandeen@redhat.com>
Wed, 1 Aug 2018 22:06:45 +0000 (17:06 -0500)
Use the xfs_agfl_walk function to iterate every block in the AGFL,
instead of open-coding it db and repair.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
db/check.c
db/freesp.c
libxfs/libxfs_api_defs.h
repair/scan.c

index 9846d6724e05d69f058445cc173651be15b22c6f..76c28d49347ff7dfe390cc75425378a5bf47dd73 100644 (file)
@@ -4010,16 +4010,30 @@ pop1_out:
        pop_cur();
 }
 
+struct agfl_state {
+       xfs_agnumber_t  agno;
+       unsigned int    count;
+};
+
+static int
+scan_agfl(
+       struct xfs_mount        *mp,
+       xfs_agblock_t           bno,
+       void                    *priv)
+{
+       struct agfl_state       *as = priv;
+
+       set_dbmap(as->agno, bno, 1, DBM_FREELIST, as->agno, XFS_AGFL_BLOCK(mp));
+       as->count++;
+       return 0;
+}
+
 static void
 scan_freelist(
-       xfs_agf_t       *agf)
+       xfs_agf_t               *agf)
 {
-       xfs_agnumber_t  seqno = be32_to_cpu(agf->agf_seqno);
-       xfs_agfl_t      *agfl;
-       xfs_agblock_t   bno;
-       uint            count;
-       int             i;
-       __be32          *freelist;
+       xfs_agnumber_t          seqno = be32_to_cpu(agf->agf_seqno);
+       struct agfl_state       state;
 
        if (XFS_SB_BLOCK(mp) != XFS_AGFL_BLOCK(mp) &&
            XFS_AGF_BLOCK(mp) != XFS_AGFL_BLOCK(mp) &&
@@ -4032,46 +4046,36 @@ scan_freelist(
        set_cur(&typtab[TYP_AGFL],
                XFS_AG_DADDR(mp, seqno, XFS_AGFL_DADDR(mp)),
                XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL);
-       if ((agfl = iocur_top->data) == NULL) {
+       if (iocur_top->data == NULL) {
                dbprintf(_("can't read agfl block for ag %u\n"), seqno);
                serious_error++;
                pop_cur();
                return;
        }
-       i = be32_to_cpu(agf->agf_flfirst);
 
        /* verify agf values before proceeding */
        if (be32_to_cpu(agf->agf_flfirst) >= libxfs_agfl_size(mp) ||
            be32_to_cpu(agf->agf_fllast) >= libxfs_agfl_size(mp)) {
                dbprintf(_("agf %d freelist blocks bad, skipping "
-                         "freelist scan\n"), i);
+                         "freelist scan\n"), seqno);
                pop_cur();
                return;
        }
 
        /* open coded XFS_BUF_TO_AGFL_BNO */
-       freelist = xfs_sb_version_hascrc(&((mp)->m_sb)) ? &agfl->agfl_bno[0]
-                                                       : (__be32 *)agfl;
-       count = 0;
-       for (;;) {
-               bno = be32_to_cpu(freelist[i]);
-               set_dbmap(seqno, bno, 1, DBM_FREELIST, seqno,
-                       XFS_AGFL_BLOCK(mp));
-               count++;
-               if (i == be32_to_cpu(agf->agf_fllast))
-                       break;
-               if (++i == libxfs_agfl_size(mp))
-                       i = 0;
-       }
-       if (count != be32_to_cpu(agf->agf_flcount)) {
+       state.count = 0;
+       state.agno = seqno;
+       libxfs_agfl_walk(mp, agf, iocur_top->bp, scan_agfl, &state);
+       if (state.count != be32_to_cpu(agf->agf_flcount)) {
                if (!sflag)
                        dbprintf(_("freeblk count %u != flcount %u in ag %u\n"),
-                               count, be32_to_cpu(agf->agf_flcount),
-                               seqno);
+                                       state.count,
+                                       be32_to_cpu(agf->agf_flcount),
+                                       seqno);
                error++;
        }
-       fdblocks += count;
-       agf_aggr_freeblks += count;
+       fdblocks += state.count;
+       agf_aggr_freeblks += state.count;
        pop_cur();
 }
 
index de0d5e10ecaea5b197cdb2e61dd6bdadbfd426ac..903c60d7380a181dde01036ffe95fa2706e82dd5 100644 (file)
@@ -219,45 +219,38 @@ scan_ag(
        pop_cur();
 }
 
+static int
+scan_agfl(
+       struct xfs_mount        *mp,
+       xfs_agblock_t           bno,
+       void                    *priv)
+{
+       addtohist(*(xfs_agnumber_t *)priv, bno, 1);
+       return 0;
+}
+
 static void
 scan_freelist(
        xfs_agf_t       *agf)
 {
        xfs_agnumber_t  seqno = be32_to_cpu(agf->agf_seqno);
-       xfs_agfl_t      *agfl;
-       xfs_agblock_t   bno;
-       int             i;
-       __be32          *agfl_bno;
 
        if (be32_to_cpu(agf->agf_flcount) == 0)
                return;
        push_cur();
        set_cur(&typtab[TYP_AGFL], XFS_AG_DADDR(mp, seqno, XFS_AGFL_DADDR(mp)),
                                XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL);
-       agfl = iocur_top->data;
-       i = be32_to_cpu(agf->agf_flfirst);
-
-       /* open coded XFS_BUF_TO_AGFL_BNO */
-       agfl_bno = xfs_sb_version_hascrc(&mp->m_sb) ? &agfl->agfl_bno[0]
-                                                  : (__be32 *)agfl;
 
        /* verify agf values before proceeding */
        if (be32_to_cpu(agf->agf_flfirst) >= libxfs_agfl_size(mp) ||
            be32_to_cpu(agf->agf_fllast) >= libxfs_agfl_size(mp)) {
                dbprintf(_("agf %d freelist blocks bad, skipping "
-                         "freelist scan\n"), i);
+                         "freelist scan\n"), seqno);
                pop_cur();
                return;
        }
 
-       for (;;) {
-               bno = be32_to_cpu(agfl_bno[i]);
-               addtohist(seqno, bno, 1);
-               if (i == be32_to_cpu(agf->agf_fllast))
-                       break;
-               if (++i == libxfs_agfl_size(mp))
-                       i = 0;
-       }
+       libxfs_agfl_walk(mp, agf, iocur_top->bp, scan_agfl, &seqno);
        pop_cur();
 }
 
index d368eab3e36131386f21b228863e4d4a39f7a8d9..47e21d2030a35a1d9c3648019ea69c8884ba9e14 100644 (file)
@@ -53,6 +53,7 @@
 #define xfs_attr_remove                        libxfs_attr_remove
 #define xfs_attr_leaf_newentsize       libxfs_attr_leaf_newentsize
 
+#define xfs_agfl_walk                  libxfs_agfl_walk
 #define xfs_alloc_fix_freelist         libxfs_alloc_fix_freelist
 #define xfs_alloc_min_freelist         libxfs_alloc_min_freelist
 #define xfs_alloc_read_agf             libxfs_alloc_read_agf
index 4b44a12b861cf35ac6ad8c7855fa0132d79be664..4bcc626ae59fbefeeda8a2d1e3f7e9177e678cbe 100644 (file)
@@ -2095,17 +2095,36 @@ _("inode btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
        }
 }
 
+struct agfl_state {
+       unsigned int    count;
+       xfs_agnumber_t  agno;
+};
+
+static int
+scan_agfl(
+       struct xfs_mount        *mp,
+       xfs_agblock_t           bno,
+       void                    *priv)
+{
+       struct agfl_state       *as = priv;
+
+       if (verify_agbno(mp, as->agno, bno))
+               set_bmap(as->agno, bno, XR_E_FREE);
+       else
+               do_warn(_("bad agbno %u in agfl, agno %d\n"),
+                       bno, as->agno);
+       as->count++;
+       return 0;
+}
+
 static void
 scan_freelist(
-       xfs_agf_t       *agf,
-       struct aghdr_cnts *agcnts)
+       xfs_agf_t               *agf,
+       struct aghdr_cnts       *agcnts)
 {
-       xfs_buf_t       *agflbuf;
-       xfs_agnumber_t  agno;
-       xfs_agblock_t   bno;
-       int             count;
-       int             i;
-       __be32          *freelist;
+       xfs_buf_t               *agflbuf;
+       xfs_agnumber_t          agno;
+       struct agfl_state       state;
 
        agno = be32_to_cpu(agf->agf_seqno);
 
@@ -2127,39 +2146,26 @@ scan_freelist(
        if (agflbuf->b_error == -EFSBADCRC)
                do_warn(_("agfl has bad CRC for ag %d\n"), agno);
 
-       freelist = XFS_BUF_TO_AGFL_BNO(mp, agflbuf);
-       i = be32_to_cpu(agf->agf_flfirst);
-
        if (no_modify) {
                /* agf values not fixed in verify_set_agf, so recheck */
                if (be32_to_cpu(agf->agf_flfirst) >= libxfs_agfl_size(mp) ||
                    be32_to_cpu(agf->agf_fllast) >= libxfs_agfl_size(mp)) {
                        do_warn(_("agf %d freelist blocks bad, skipping "
-                                 "freelist scan\n"), i);
+                                 "freelist scan\n"), agno);
                        return;
                }
        }
 
-       count = 0;
-       for (;;) {
-               bno = be32_to_cpu(freelist[i]);
-               if (verify_agbno(mp, agno, bno))
-                       set_bmap(agno, bno, XR_E_FREE);
-               else
-                       do_warn(_("bad agbno %u in agfl, agno %d\n"),
-                               bno, agno);
-               count++;
-               if (i == be32_to_cpu(agf->agf_fllast))
-                       break;
-               if (++i == libxfs_agfl_size(mp))
-                       i = 0;
-       }
-       if (count != be32_to_cpu(agf->agf_flcount)) {
-               do_warn(_("freeblk count %d != flcount %d in ag %d\n"), count,
-                       be32_to_cpu(agf->agf_flcount), agno);
+       state.count = 0;
+       state.agno = agno;
+       libxfs_agfl_walk(mp, agf, agflbuf, scan_agfl, &state);
+       if (state.count != be32_to_cpu(agf->agf_flcount)) {
+               do_warn(_("freeblk count %d != flcount %d in ag %d\n"),
+                               state.count, be32_to_cpu(agf->agf_flcount),
+                               agno);
        }
 
-       agcnts->fdblocks += count;
+       agcnts->fdblocks += state.count;
 
        libxfs_putbuf(agflbuf);
 }