]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_repair: warn about suspicious btree levels in AG headers
authorDarrick J. Wong <djwong@kernel.org>
Wed, 18 May 2022 02:48:12 +0000 (22:48 -0400)
committerEric Sandeen <sandeen@sandeen.net>
Wed, 18 May 2022 02:48:12 +0000 (22:48 -0400)
Warn about suspicious AG btree levels in the AGF and AGI.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
repair/scan.c

index 4a234dedcd903fb43085ee31328917be5ea4524f..5a4b8dbdff1c7dd1786080c304e5e68a1650a50f 100644 (file)
@@ -2261,6 +2261,13 @@ validate_agf(
 {
        xfs_agblock_t           bno;
        uint32_t                magic;
+       unsigned int            levels;
+
+       levels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]);
+       if (levels == 0 || levels > mp->m_alloc_maxlevels) {
+               do_warn(_("bad levels %u for btbno root, agno %d\n"),
+                       levels, agno);
+       }
 
        bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]);
        if (libxfs_verify_agbno(mp, agno, bno)) {
@@ -2274,6 +2281,12 @@ validate_agf(
                        bno, agno);
        }
 
+       levels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]);
+       if (levels == 0 || levels > mp->m_alloc_maxlevels) {
+               do_warn(_("bad levels %u for btbcnt root, agno %d\n"),
+                       levels, agno);
+       }
+
        bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]);
        if (libxfs_verify_agbno(mp, agno, bno)) {
                magic = xfs_has_crc(mp) ? XFS_ABTC_CRC_MAGIC
@@ -2288,7 +2301,6 @@ validate_agf(
 
        if (xfs_has_rmapbt(mp)) {
                struct rmap_priv        priv;
-               unsigned int            levels;
 
                memset(&priv.high_key, 0xFF, sizeof(priv.high_key));
                priv.high_key.rm_blockcount = 0;
@@ -2320,8 +2332,6 @@ validate_agf(
        }
 
        if (xfs_has_reflink(mp)) {
-               unsigned int    levels;
-
                levels = be32_to_cpu(agf->agf_refcount_level);
                if (levels == 0 || levels > mp->m_refc_maxlevels) {
                        do_warn(_("bad levels %u for refcountbt root, agno %d\n"),
@@ -2378,6 +2388,13 @@ validate_agi(
        xfs_agblock_t           bno;
        int                     i;
        uint32_t                magic;
+       unsigned int            levels;
+
+       levels = be32_to_cpu(agi->agi_level);
+       if (levels == 0 || levels > M_IGEO(mp)->inobt_maxlevels) {
+               do_warn(_("bad levels %u for inobt root, agno %d\n"),
+                       levels, agno);
+       }
 
        bno = be32_to_cpu(agi->agi_root);
        if (libxfs_verify_agbno(mp, agno, bno)) {
@@ -2392,6 +2409,12 @@ validate_agi(
        }
 
        if (xfs_has_finobt(mp)) {
+               levels = be32_to_cpu(agi->agi_free_level);
+               if (levels == 0 || levels > M_IGEO(mp)->inobt_maxlevels) {
+                       do_warn(_("bad levels %u for finobt root, agno %d\n"),
+                               levels, agno);
+               }
+
                bno = be32_to_cpu(agi->agi_free_root);
                if (libxfs_verify_agbno(mp, agno, bno)) {
                        magic = xfs_has_crc(mp) ?