diff mbox series

[2/4] xfs_repair: check low keys of rmap btrees

Message ID 167243834765.692079.15547663887609909520.stgit@magnolia (mailing list archive)
State Superseded
Headers show
Series xfs: fix rmap btree key flag handling | expand

Commit Message

Darrick J. Wong Dec. 30, 2022, 10:12 p.m. UTC
From: Darrick J. Wong <djwong@kernel.org>

For whatever reason, we only check the high keys in an rmapbt node
block.  We should be checking the low keys and the high keys, so fix
this gap.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 repair/scan.c |   32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/repair/scan.c b/repair/scan.c
index 7b72013153d..d66ce60cbb3 100644
--- a/repair/scan.c
+++ b/repair/scan.c
@@ -992,6 +992,7 @@  scan_rmapbt(
 	uint64_t		lastowner = 0;
 	uint64_t		lastoffset = 0;
 	struct xfs_rmap_key	*kp;
+	struct xfs_rmap_irec	oldkey;
 	struct xfs_rmap_irec	key = {0};
 	struct xfs_perag	*pag;
 
@@ -1211,7 +1212,7 @@  _("%s rmap btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
 	}
 
 	/* check the node's high keys */
-	for (i = 0; !isroot && i < numrecs; i++) {
+	for (i = 0; i < numrecs; i++) {
 		kp = XFS_RMAP_HIGH_KEY_ADDR(block, i + 1);
 
 		key.rm_flags = 0;
@@ -1231,6 +1232,35 @@  _("%s rmap btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
 				i, agno, bno, name);
 	}
 
+	/* check for in-order keys */
+	for (i = 0; i < numrecs; i++)  {
+		kp = XFS_RMAP_KEY_ADDR(block, i + 1);
+
+		key.rm_flags = 0;
+		key.rm_startblock = be32_to_cpu(kp->rm_startblock);
+		key.rm_owner = be64_to_cpu(kp->rm_owner);
+		if (libxfs_rmap_irec_offset_unpack(be64_to_cpu(kp->rm_offset),
+				&key)) {
+			/* Look for impossible flags. */
+			do_warn(
+_("invalid flags in key %u of %s btree block %u/%u\n"),
+				i, name, agno, bno);
+			suspect++;
+			continue;
+		}
+		if (i == 0) {
+			oldkey = key;
+			continue;
+		}
+		if (rmap_diffkeys(&oldkey, &key) > 0) {
+			do_warn(
+_("out of order key %u in %s btree block (%u/%u)\n"),
+				i, name, agno, bno);
+			suspect++;
+		}
+		oldkey = key;
+	}
+
 	pag = libxfs_perag_get(mp, agno);
 	for (i = 0; i < numrecs; i++)  {
 		xfs_agblock_t		agbno = be32_to_cpu(pp[i]);