]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_repair: fix rmapbt record order check
authorDarrick J. Wong <darrick.wong@oracle.com>
Fri, 10 Jul 2020 19:35:45 +0000 (15:35 -0400)
committerEric Sandeen <sandeen@sandeen.net>
Fri, 10 Jul 2020 19:35:45 +0000 (15:35 -0400)
The rmapbt record order checks here don't quite work properly.  For
non-shared filesystems, we fail to check that the startblock of the nth
record comes entirely after the previous record.

However, for filesystems with shared blocks (reflink) we correctly check
that the startblock/owner/offset of the nth record comes after the
previous one.

Therefore, make the reflink fs checks use "laststartblock" to preserve
that functionality while making the non-reflink fs checks use
"lastblock" to fix the problem outlined above.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
repair/scan.c

index 7c46ab8991aec3f21f33c8ca7fefdfd24687cf3b..7508f7e8d8687dca0c581a5d0c2ebd51b5f6c62d 100644 (file)
@@ -925,15 +925,15 @@ struct rmap_priv {
 static bool
 rmap_in_order(
        xfs_agblock_t   b,
-       xfs_agblock_t   lastblock,
+       xfs_agblock_t   laststartblock,
        uint64_t        owner,
        uint64_t        lastowner,
        uint64_t        offset,
        uint64_t        lastoffset)
 {
-       if (b > lastblock)
+       if (b > laststartblock)
                return true;
-       else if (b < lastblock)
+       else if (b < laststartblock)
                return false;
 
        if (owner > lastowner)
@@ -964,6 +964,7 @@ scan_rmapbt(
        int                     hdr_errors = 0;
        int                     numrecs;
        int                     state;
+       xfs_agblock_t           laststartblock = 0;
        xfs_agblock_t           lastblock = 0;
        uint64_t                lastowner = 0;
        uint64_t                lastoffset = 0;
@@ -1101,14 +1102,15 @@ _("%s rmap btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
                        /* Check for out of order records. */
                        if (i == 0) {
 advance:
-                               lastblock = b;
+                               laststartblock = b;
+                               lastblock = end - 1;
                                lastowner = owner;
                                lastoffset = offset;
                        } else {
                                bool bad;
 
                                if (xfs_sb_version_hasreflink(&mp->m_sb))
-                                       bad = !rmap_in_order(b, lastblock,
+                                       bad = !rmap_in_order(b, laststartblock,
                                                        owner, lastowner,
                                                        offset, lastoffset);
                                else