xfs_repair: warn about suspicious btree levels in AG headers
Warn about suspicious AG btree levels in the AGF and AGI.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
diff --git a/repair/scan.c b/repair/scan.c
index 4a234de..5a4b8db 100644
--- a/repair/scan.c
+++ b/repair/scan.c
@@ -2261,6 +2261,13 @@
{
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 @@
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 @@
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 @@
}
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 @@
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 @@
}
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) ?