]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_repair: convert to libxfs_verify_agbno
authorDarrick J. Wong <darrick.wong@oracle.com>
Fri, 10 Jul 2020 19:35:45 +0000 (15:35 -0400)
committerEric Sandeen <sandeen@sandeen.net>
Fri, 10 Jul 2020 19:35:45 +0000 (15:35 -0400)
Convert the homegrown verify_agbno callers to use the libxfs function,
as needed.  In some places we drop the "bno != 0" checks because those
conditionals are checking btree roots; btree roots should never be
zero if the corresponding feature bit is set; and repair skips the if
clause entirely if the feature bit is disabled.

In effect, this strengthens repair to validate that AG btree pointers
neither point to the AG headers nor past the end of the AG.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
libxfs/libxfs_api_defs.h
repair/dinode.c
repair/dinode.h
repair/scan.c

index 7b264ff21569562cb3378b86b0a67ca2981a398f..c03f0efa9f384f389b26991d87d199467d1da4b3 100644 (file)
@@ -20,6 +20,7 @@
 #define xfs_agfl_walk                  libxfs_agfl_walk
 
 #define xfs_ag_init_headers            libxfs_ag_init_headers
+#define xfs_ag_block_count             libxfs_ag_block_count
 
 #define xfs_alloc_ag_max_usable                libxfs_alloc_ag_max_usable
 #define xfs_allocbt_maxrecs            libxfs_allocbt_maxrecs
index 1f1cc26b948b52ed381e6ba450c757d6a91b6908..b343534c9421d934fddad0ced11ab3c3c50981c8 100644 (file)
@@ -255,17 +255,6 @@ verify_dfsbno_range(xfs_mount_t    *mp,
        return (XR_DFSBNORANGE_VALID);
 }
 
-int
-verify_agbno(xfs_mount_t       *mp,
-               xfs_agnumber_t  agno,
-               xfs_agblock_t   agbno)
-{
-       xfs_sb_t        *sbp = &mp->m_sb;;
-
-       /* range check ag #, ag block.  range-checking offset is pointless */
-       return verify_ag_bno(sbp, agno, agbno) == 0;
-}
-
 static int
 process_rt_rec(
        xfs_mount_t             *mp,
index 98238357e3d7e38756266f20d375556cab82ee31..c8e563b5fdd66cdef5dfeaeecec4c7d4dd865859 100644 (file)
@@ -9,11 +9,6 @@
 struct blkmap;
 struct prefetch_args;
 
-int
-verify_agbno(xfs_mount_t       *mp,
-               xfs_agnumber_t  agno,
-               xfs_agblock_t   agbno);
-
 int
 verify_dfsbno(xfs_mount_t      *mp,
                xfs_fsblock_t   fsbno);
index 719ad035d663c47c6dcd2f78be529b61db7388bb..8e81c5523c43738f58d66501d9c5755b5d0224e4 100644 (file)
@@ -678,14 +678,14 @@ _("%s freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
                        len = be32_to_cpu(rp[i].ar_blockcount);
                        end = b + len;
 
-                       if (b == 0 || !verify_agbno(mp, agno, b)) {
+                       if (!libxfs_verify_agbno(mp, agno, b)) {
                                do_warn(
        _("invalid start block %u in record %u of %s btree block %u/%u\n"),
                                        b, i, name, agno, bno);
                                continue;
                        }
                        if (len == 0 || end <= b ||
-                           !verify_agbno(mp, agno, end - 1)) {
+                           !libxfs_verify_agbno(mp, agno, end - 1)) {
                                do_warn(
        _("invalid length %u in record %u of %s btree block %u/%u\n"),
                                        len, i, name, agno, bno);
@@ -950,6 +950,16 @@ rmap_in_order(
        return offset > lastoffset;
 }
 
+static inline bool
+verify_rmap_agbno(
+       struct xfs_mount        *mp,
+       xfs_agnumber_t          agno,
+       xfs_agblock_t           agbno)
+{
+       return agbno < libxfs_ag_block_count(mp, agno);
+}
+
+
 static void
 scan_rmapbt(
        struct xfs_btree_block  *block,
@@ -1068,14 +1078,14 @@ _("%s rmap btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
                        end = key.rm_startblock + key.rm_blockcount;
 
                        /* Make sure agbno & len make sense. */
-                       if (!verify_agbno(mp, agno, b)) {
+                       if (!verify_rmap_agbno(mp, agno, b)) {
                                do_warn(
        _("invalid start block %u in record %u of %s btree block %u/%u\n"),
                                        b, i, name, agno, bno);
                                continue;
                        }
                        if (len == 0 || end <= b ||
-                           !verify_agbno(mp, agno, end - 1)) {
+                           !verify_rmap_agbno(mp, agno, end - 1)) {
                                do_warn(
        _("invalid length %u in record %u of %s btree block %u/%u\n"),
                                        len, i, name, agno, bno);
@@ -1363,14 +1373,14 @@ _("leftover CoW extent has invalid startblock in record %u of %s btree block %u/
                        }
                        end = agb + len;
 
-                       if (!verify_agbno(mp, agno, agb)) {
+                       if (!libxfs_verify_agbno(mp, agno, agb)) {
                                do_warn(
        _("invalid start block %u in record %u of %s btree block %u/%u\n"),
                                        b, i, name, agno, bno);
                                continue;
                        }
                        if (len == 0 || end <= agb ||
-                           !verify_agbno(mp, agno, end - 1)) {
+                           !libxfs_verify_agbno(mp, agno, end - 1)) {
                                do_warn(
        _("invalid length %u in record %u of %s btree block %u/%u\n"),
                                        len, i, name, agno, bno);
@@ -2171,7 +2181,7 @@ scan_agfl(
 {
        struct agfl_state       *as = priv;
 
-       if (verify_agbno(mp, as->agno, bno))
+       if (libxfs_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"),
@@ -2244,7 +2254,7 @@ validate_agf(
        uint32_t                magic;
 
        bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]);
-       if (bno != 0 && verify_agbno(mp, agno, bno)) {
+       if (libxfs_verify_agbno(mp, agno, bno)) {
                magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_ABTB_CRC_MAGIC
                                                         : XFS_ABTB_MAGIC;
                scan_sbtree(bno, be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]),
@@ -2256,7 +2266,7 @@ validate_agf(
        }
 
        bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]);
-       if (bno != 0 && verify_agbno(mp, agno, bno)) {
+       if (libxfs_verify_agbno(mp, agno, bno)) {
                magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_ABTC_CRC_MAGIC
                                                         : XFS_ABTC_MAGIC;
                scan_sbtree(bno, be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]),
@@ -2276,7 +2286,7 @@ validate_agf(
                priv.last_rec.rm_owner = XFS_RMAP_OWN_UNKNOWN;
                priv.nr_blocks = 0;
                bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_RMAP]);
-               if (bno != 0 && verify_agbno(mp, agno, bno)) {
+               if (libxfs_verify_agbno(mp, agno, bno)) {
                        scan_sbtree(bno,
                                    be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]),
                                    agno, 0, scan_rmapbt, 1, XFS_RMAP_CRC_MAGIC,
@@ -2294,7 +2304,7 @@ validate_agf(
 
        if (xfs_sb_version_hasreflink(&mp->m_sb)) {
                bno = be32_to_cpu(agf->agf_refcount_root);
-               if (bno != 0 && verify_agbno(mp, agno, bno)) {
+               if (libxfs_verify_agbno(mp, agno, bno)) {
                        struct refc_priv        priv;
 
                        memset(&priv, 0, sizeof(priv));
@@ -2342,7 +2352,7 @@ validate_agi(
        uint32_t                magic;
 
        bno = be32_to_cpu(agi->agi_root);
-       if (bno != 0 && verify_agbno(mp, agno, bno)) {
+       if (libxfs_verify_agbno(mp, agno, bno)) {
                magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_IBT_CRC_MAGIC
                                                         : XFS_IBT_MAGIC;
                scan_sbtree(bno, be32_to_cpu(agi->agi_level),
@@ -2355,7 +2365,7 @@ validate_agi(
 
        if (xfs_sb_version_hasfinobt(&mp->m_sb)) {
                bno = be32_to_cpu(agi->agi_free_root);
-               if (bno != 0 && verify_agbno(mp, agno, bno)) {
+               if (libxfs_verify_agbno(mp, agno, bno)) {
                        magic = xfs_sb_version_hascrc(&mp->m_sb) ?
                                        XFS_FIBT_CRC_MAGIC : XFS_FIBT_MAGIC;
                        scan_sbtree(bno, be32_to_cpu(agi->agi_free_level),