From eeb894a242c8d200b7ed4c8b7da3d54e24e02c6f Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Mon, 9 Feb 2026 20:27:35 +1030 Subject: [PATCH] fstests: btrfs: add a regression test for incorrect inode incompressible flag [BUG] Since kernel commit 59615e2c1f63 ("btrfs: reject single block sized compression early"), a single block write at file offset 0, which can not be inlined due the inode size, will mark the inode incompressible. [REGRESSION TEST] The new regression test will do: - Create and mount the fs with compression,max_inline=2k - Do the following operations: * Truncate the inode to 2 * blocksize This will rule out any future inlined writes. * Buffered write [0, 2K) Which will not be inlined. * Sync For affected kernels, this will set the inode with NOCOMPRESS and reject all future compression on that inode. * Buffered write [1M, 2M) For affected kernels, the range will not be compressed due to the NOCOMPRESS flag. - Unmount the fs - Make sure that: * The inode has no NOCOMPRESS flag * File extent at file offset 1M is being compressed Reviewed-by: Filipe Manana Signed-off-by: Qu Wenruo Reviewed-by: Zorro Lang Signed-off-by: Zorro Lang --- tests/btrfs/343 | 48 +++++++++++++++++++++++++++++++++++++++++++++ tests/btrfs/343.out | 2 ++ 2 files changed, 50 insertions(+) create mode 100755 tests/btrfs/343 create mode 100644 tests/btrfs/343.out diff --git a/tests/btrfs/343 b/tests/btrfs/343 new file mode 100755 index 00000000..53e6028b --- /dev/null +++ b/tests/btrfs/343 @@ -0,0 +1,48 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2026 SUSE S.A. All Rights Reserved. +# +# FS QA Test 343 +# +# A regression test to make sure a single-block write at file offset 0 won't +# incorrectly mark the inode incompressible. +# +. ./common/preamble +_begin_fstest auto quick compress + +_require_scratch +_require_btrfs_command inspect-internal dump-tree + +_fixed_by_kernel_commit xxxxxxxxxxxx \ + "btrfs: fix the inline compressed extent check in inode_need_compress()" + +_scratch_mkfs >>$seqres.full 2>&1 +_scratch_mount "-o compress,max_inline=2048" + +blocksize=$(_get_file_block_size $SCRATCH_MNT) + +# Create a sparse file which is 2 * blocksize, then try a small write at +# file offset 0 which should not be inlined. +# Sync so that [0, 2K) range is written, then write a larger range which +# should be able to be compressed. +$XFS_IO_PROG -f -c "truncate $((2 * $blocksize))" -c "pwrite 0 2k" -c sync \ + -c "pwrite 1m 1m" $SCRATCH_MNT/foobar >> $seqres.full +ino=$(stat -c "%i" $SCRATCH_MNT/foobar) +_scratch_unmount + +# Dump the fstree into seqres.full for debug. +$BTRFS_UTIL_PROG inspect-internal dump-tree -t 5 $SCRATCH_DEV >> $seqres.full + +# Check the NOCOMPRESS flag of the inode. +$BTRFS_UTIL_PROG inspect-internal dump-tree -t 5 $SCRATCH_DEV |\ +grep -A 4 -e "item .* key ($ino INODE_ITEM 0)" | grep -q NOCOMPRESS +[ $? -eq 0 ] && echo "inode $ino has NOCOMPRESS flag" + +# Check the file extent at fileoffset 1m. +$BTRFS_UTIL_PROG inspect-internal dump-tree -t 5 $SCRATCH_DEV |\ +grep -A 4 -e "item .* key ($ino EXTENT_DATA 1048576)" | grep -q "compression 0" +[ $? -eq 0 ] && echo "inode $ino file offset 1M is not compressed" + +echo "Silence is golden" +# success, all done +_exit 0 diff --git a/tests/btrfs/343.out b/tests/btrfs/343.out new file mode 100644 index 00000000..2eb30e4f --- /dev/null +++ b/tests/btrfs/343.out @@ -0,0 +1,2 @@ +QA output created by 343 +Silence is golden -- 2.47.3