[PATCH 08/16] xfs_repair: complain about bad interior btree pointers

Darrick J. Wong
2020-05-09T16:32:44Z

From: Darrick J. Wong <darrick.wong@oracle.com>

Actually complain about garbage btree node pointers, don't just silently
ignore them.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
libxfs/libxfs_api_defs.h | 1 +
repair/scan.c | 55 +++++++++++++++++++++++++++++++++-------------
2 files changed, 41 insertions(+), 15 deletions(-)

diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index 4462036b..7b264ff2 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -180,6 +180,7 @@
#define xfs_trans_roll_inode libxfs_trans_roll_inode
#define xfs_trans_roll libxfs_trans_roll

+#define xfs_verify_agbno libxfs_verify_agbno
#define xfs_verify_cksum libxfs_verify_cksum
#define xfs_verify_dir_ino libxfs_verify_dir_ino
#define xfs_verify_ino libxfs_verify_ino
diff --git a/repair/scan.c b/repair/scan.c
index fff54ecf..719ad035 100644
--- a/repair/scan.c
+++ b/repair/scan.c
@@ -779,6 +779,14 @@ _("%s freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
for (i = 0; i < numrecs; i++) {
xfs_agblock_t agbno = be32_to_cpu(pp[i]);

+ if (!libxfs_verify_agbno(mp, agno, agbno)) {
+ do_warn(
+ _("bad btree pointer (%u) in %sbt block %u/%u\n"),
+ agbno, name, agno, bno);
+ suspect++;
+ return;
+ }
+
/*
* XXX - put sibling detection right here.
* we know our sibling chain is good. So as we go,
@@ -788,10 +796,8 @@ _("%s freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
* pointer mismatch, try and extract as much data
* as possible.
*/
- if (agbno != 0 && verify_agbno(mp, agno, agbno)) {
- scan_sbtree(agbno, level, agno, suspect, scan_allocbt,
- 0, magic, priv, ops);
- }
+ scan_sbtree(agbno, level, agno, suspect, scan_allocbt, 0,
+ magic, priv, ops);
}
}

@@ -1234,10 +1240,16 @@ _("%s rmap btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
continue;
}

- if (agbno != 0 && verify_agbno(mp, agno, agbno)) {
- scan_sbtree(agbno, level, agno, suspect, scan_rmapbt, 0,
- magic, priv, ops);
+ if (!libxfs_verify_agbno(mp, agno, agbno)) {
+ do_warn(
+ _("bad btree pointer (%u) in %sbt block %u/%u\n"),
+ agbno, name, agno, bno);
+ suspect++;
+ return;
}
+
+ scan_sbtree(agbno, level, agno, suspect, scan_rmapbt, 0, magic,
+ priv, ops);
}

out:
@@ -1454,10 +1466,16 @@ _("extent (%u/%u) len %u claimed, state is %d\n"),
for (i = 0; i < numrecs; i++) {
xfs_agblock_t agbno = be32_to_cpu(pp[i]);

- if (agbno != 0 && verify_agbno(mp, agno, agbno)) {
- scan_sbtree(agbno, level, agno, suspect, scan_refcbt, 0,
- magic, priv, ops);
+ if (!libxfs_verify_agbno(mp, agno, agbno)) {
+ do_warn(
+ _("bad btree pointer (%u) in %sbt block %u/%u\n"),
+ agbno, name, agno, bno);
+ suspect++;
+ return;
}
+
+ scan_sbtree(agbno, level, agno, suspect, scan_refcbt, 0, magic,
+ priv, ops);
}
out:
if (suspect)
@@ -2125,11 +2143,18 @@ _("%sbt btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
}

for (i = 0; i < numrecs; i++) {
- if (be32_to_cpu(pp[i]) != 0 && verify_agbno(mp, agno,
- be32_to_cpu(pp[i])))
- scan_sbtree(be32_to_cpu(pp[i]), level, agno,
- suspect, scan_inobt, 0, magic, priv,
- ops);
+ xfs_agblock_t agbno = be32_to_cpu(pp[i]);
+
+ if (!libxfs_verify_agbno(mp, agno, agbno)) {
+ do_warn(
+ _("bad btree pointer (%u) in %sbt block %u/%u\n"),
+ agbno, name, agno, bno);
+ suspect++;
+ return;
+ }
+
+ scan_sbtree(be32_to_cpu(pp[i]), level, agno, suspect,
+ scan_inobt, 0, magic, priv, ops);
}
}