[PATCH 2/6] xfs: alert the user about data/attr fork mappings that could be merged

Darrick J. Wong
2022-12-30T22:47:16Z

If the data or attr forks have mappings that could be merged, let the
user know that the structure could be optimized. This isn't a
filesystem corruption since the regular filesystem does not try to be
smart about merging bmbt records.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
fs/xfs/scrub/bmap.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)

diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c
index 14fe461cac4c..499e82110f2f 100644
--- a/fs/xfs/scrub/bmap.c
+++ b/fs/xfs/scrub/bmap.c
@@ -390,6 +390,29 @@ xchk_bmap_dirattr_extent(
xchk_fblock_set_corrupt(info->sc, info->whichfork, off);
}

+/* Are these two mappings mergeable? */
+static inline bool
+xchk_bmap_mergeable(
+ struct xchk_bmap_info *info,
+ const struct xfs_bmbt_irec *b2)
+{
+ const struct xfs_bmbt_irec *b1 = &info->prev_rec;
+
+ /* Skip uninitialized prev_rec and COW fork extents */
+ if (b1->br_blockcount == 0)
+ return false;
+ if (info->whichfork == XFS_COW_FORK)
+ return false;
+
+ if (b1->br_startoff + b1->br_blockcount != b2->br_startoff)
+ return false;
+ if (b1->br_startblock + b1->br_blockcount != b2->br_startblock)
+ return false;
+ if (b1->br_blockcount + b2->br_blockcount > BMBT_BLOCKCOUNT_MASK)
+ return false;
+ return b1->br_state == b2->br_state;
+}
+
/* Scrub a single extent record. */
STATIC void
xchk_bmap_iextent(
@@ -441,6 +464,10 @@ xchk_bmap_iextent(
if (info->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
return;

+ /* Notify the user of mergeable records in the data/attr forks. */
+ if (xchk_bmap_mergeable(info, irec))
+ xchk_ino_set_preen(info->sc, info->sc->ip->i_ino);
+
if (info->is_rt)
xchk_bmap_rt_iextent_xref(ip, info, irec);
else