]> git.apps.os.sepia.ceph.com Git - xfsprogs-dev.git/commitdiff
xfs_repair: check low keys of rmap btrees
authorDarrick J. Wong <djwong@kernel.org>
Mon, 5 Jun 2023 15:36:12 +0000 (08:36 -0700)
committerCarlos Maiolino <cem@kernel.org>
Wed, 12 Jul 2023 07:15:19 +0000 (09:15 +0200)
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>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
repair/scan.c

index 7b72013153d5174ab039b233166dd3394ccb5674..d66ce60cbb310d38df9dcfade3eb495e0abf817f 100644 (file)
@@ -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 @@ advance:
        }
 
        /* 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 @@ advance:
                                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]);