]> www.infradead.org Git - users/hch/xfs.git/commitdiff
xfs: don't coalesce file mappings that cross allocation group boundaries
authorDarrick J. Wong <djwong@kernel.org>
Wed, 26 Jun 2024 18:19:00 +0000 (11:19 -0700)
committerChristoph Hellwig <hch@lst.de>
Tue, 6 Aug 2024 13:05:17 +0000 (06:05 -0700)
The bmbt scrubber will combine file mappings if they are mergeable to
reduce the number of cross-referencing checks.  However, we shouldn't
combine mappings that cross rt group boundaries because that will cause
verifiers to trip incorrectly.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
fs/xfs/scrub/bmap.c

index 1946f0bcedda532c0835a866ef939e68537987eb..c127e605b0ebc9d64d483a37930db9ad2be51adb 100644 (file)
@@ -835,9 +835,12 @@ xchk_bmap_iext_mapping(
 /* Are these two mappings contiguous with each other? */
 static inline bool
 xchk_are_bmaps_contiguous(
+       const struct xchk_bmap_info     *info,
        const struct xfs_bmbt_irec      *b1,
        const struct xfs_bmbt_irec      *b2)
 {
+       struct xfs_mount                *mp = info->sc->mp;
+
        /* Don't try to combine unallocated mappings. */
        if (!xfs_bmap_is_real_extent(b1))
                return false;
@@ -851,6 +854,17 @@ xchk_are_bmaps_contiguous(
                return false;
        if (b1->br_state != b2->br_state)
                return false;
+
+       /*
+        * Don't combine bmaps that would cross rtgroup boundaries.  This is a
+        * valid state, but if combined they will fail rtb extent checks.
+        */
+       if (info->is_rt && xfs_has_rtgroups(mp)) {
+               if (xfs_rtb_to_rgno(mp, b1->br_startblock) !=
+                   xfs_rtb_to_rgno(mp, b2->br_startblock))
+                       return false;
+       }
+
        return true;
 }
 
@@ -888,7 +902,7 @@ xchk_bmap_iext_iter(
         * that we just read, if possible.
         */
        while (xfs_iext_peek_next_extent(ifp, &info->icur, &got)) {
-               if (!xchk_are_bmaps_contiguous(irec, &got))
+               if (!xchk_are_bmaps_contiguous(info, irec, &got))
                        break;
 
                if (!xchk_bmap_iext_mapping(info, &got)) {