From: Jianyun Gao In xfs_rmap_map, the left-edge merge path already executes ltrec.rm_blockcount += len at line 1119 before checking whether the right record is also contiguous and can be merged. The subsequent overflow guard therefore must compare the already-incremented ltrec.rm_blockcount plus gtrec.rm_blockcount against XFS_RMAP_LEN_MAX, but it incorrectly adds len a second time: (unsigned long)ltrec.rm_blockcount + len + gtrec.rm_blockcount <= XFS_RMAP_LEN_MAX The extra len makes the check too strict: when the real merged length does not overflow but the inflated value exceeds XFS_RMAP_LEN_MAX, the three-way merge is rejected and the code falls back to a two-way merge, leaving the right record unmerged. This produces rmap btree fragmentation but does not corrupt on-disk metadata. Remove the spurious len from the overflow check. Fixes: 0a1b0b3855cf7 ("xfs: add an extent to the rmap btree") Cc: Signed-off-by: Jianyun Gao --- fs/xfs/libxfs/xfs_rmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index 14aef87837a9..c2b2f8e7502d 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -1120,7 +1120,7 @@ xfs_rmap_map( if (have_gt && bno + len == gtrec.rm_startblock && (ignore_off || offset + len == gtrec.rm_offset) && - (unsigned long)ltrec.rm_blockcount + len + + (unsigned long)ltrec.rm_blockcount + gtrec.rm_blockcount <= XFS_RMAP_LEN_MAX) { /* * right edge also contiguous, delete right record -- 2.34.1