xfs: stricter btree height checking when scanning for btree roots
authorDarrick J. Wong <djwong@kernel.org>
Thu, 16 Sep 2021 19:21:56 +0000 (12:21 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Thu, 14 Oct 2021 16:19:32 +0000 (09:19 -0700)
When we're scanning for btree roots to rebuild the AG headers, make sure
that the proposed tree does not exceed the maximum height for that btree
type (and not just XFS_BTREE_MAXLEVELS).

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Chandan Babu R <chandan.babu@oracle.com>
fs/xfs/scrub/agheader_repair.c
fs/xfs/scrub/repair.h

index 0f8deee..05c2714 100644 (file)
@@ -122,7 +122,7 @@ xrep_check_btree_root(
        xfs_agnumber_t                  agno = sc->sm->sm_agno;
 
        return xfs_verify_agbno(mp, agno, fab->root) &&
-              fab->height <= XFS_BTREE_MAXLEVELS;
+              fab->height <= fab->maxlevels;
 }
 
 /*
@@ -339,18 +339,22 @@ xrep_agf(
                [XREP_AGF_BNOBT] = {
                        .rmap_owner = XFS_RMAP_OWN_AG,
                        .buf_ops = &xfs_bnobt_buf_ops,
+                       .maxlevels = sc->mp->m_ag_maxlevels,
                },
                [XREP_AGF_CNTBT] = {
                        .rmap_owner = XFS_RMAP_OWN_AG,
                        .buf_ops = &xfs_cntbt_buf_ops,
+                       .maxlevels = sc->mp->m_ag_maxlevels,
                },
                [XREP_AGF_RMAPBT] = {
                        .rmap_owner = XFS_RMAP_OWN_AG,
                        .buf_ops = &xfs_rmapbt_buf_ops,
+                       .maxlevels = sc->mp->m_rmap_maxlevels,
                },
                [XREP_AGF_REFCOUNTBT] = {
                        .rmap_owner = XFS_RMAP_OWN_REFC,
                        .buf_ops = &xfs_refcountbt_buf_ops,
+                       .maxlevels = sc->mp->m_refc_maxlevels,
                },
                [XREP_AGF_END] = {
                        .buf_ops = NULL,
@@ -881,10 +885,12 @@ xrep_agi(
                [XREP_AGI_INOBT] = {
                        .rmap_owner = XFS_RMAP_OWN_INOBT,
                        .buf_ops = &xfs_inobt_buf_ops,
+                       .maxlevels = M_IGEO(sc->mp)->inobt_maxlevels,
                },
                [XREP_AGI_FINOBT] = {
                        .rmap_owner = XFS_RMAP_OWN_INOBT,
                        .buf_ops = &xfs_finobt_buf_ops,
+                       .maxlevels = M_IGEO(sc->mp)->inobt_maxlevels,
                },
                [XREP_AGI_END] = {
                        .buf_ops = NULL
index 3bb152d..840f74e 100644 (file)
@@ -44,6 +44,9 @@ struct xrep_find_ag_btree {
        /* in: buffer ops */
        const struct xfs_buf_ops        *buf_ops;
 
+       /* in: maximum btree height */
+       unsigned int                    maxlevels;
+
        /* out: the highest btree block found and the tree height */
        xfs_agblock_t                   root;
        unsigned int                    height;