Linux Btrfs filesystem development
 help / color / mirror / Atom feed
* [PATCH v2] fstests: generic: add a test case to check fsverity reads
@ 2026-10-10  9:04 Qu Wenruo
  2026-10-11 18:49 ` Dhruva G
  0 siblings, 1 reply; 3+ messages in thread
From: Qu Wenruo @ 2026-10-10  9:04 UTC (permalink / raw)
  To: linux-btrfs, fstests

There is a bug report that with the recently enabled large folios
support, fsverity enabled files on btrfs can trigger reproducible
warnings about file corruption, but in the end no error is returned to
user space.

It turns out to be a bug in the btrfs fsverity integration, where blocks
not included in the read range are passed to be verified.

This is a long-standing bug where btrfs fsverity always assumed that one
folio contains exactly one fs block, ignoring the fact that btrfs had
block size < page size support before fsverity support was added.

Add a new regression test case for it. The workload is pretty simple:

- Create a 32M file

- Punch a 64K hole for every 128K
  This will limit the read bio size to 64K, which is smaller than
  a lot of large folios, and thus can trigger the btrfs bug.

- Enable fsverity digest and drop page cache

- Read that file

- Verify there is no "FILE CORRUPTED!" warning

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
Changelog
v2:
- Do not use btrfs specific mount options to limit read bio size
  Use holes to limit the size of read bios instead, now the test case
  can be generic other than btrfs specific.

- Add the missing _require_check_dmesg call

v1:
https://lore.kernel.org/linux-btrfs/20261010032508.36935-1-wqu@suse.com/
---
 tests/generic/807     | 56 +++++++++++++++++++++++++++++++++++++++++++
 tests/generic/807.out |  2 ++
 2 files changed, 58 insertions(+)
 create mode 100755 tests/generic/807
 create mode 100644 tests/generic/807.out

diff --git a/tests/generic/807 b/tests/generic/807
new file mode 100755
index 00000000..24e22e8c
--- /dev/null
+++ b/tests/generic/807
@@ -0,0 +1,56 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2026 SUSE S.A.  All Rights Reserved.
+#
+# FS QA Test 807
+#
+# Verify that reading a large file with holes won't trigger fsverity warnings
+#
+. ./common/preamble
+_begin_fstest auto quick verity
+
+_fixed_by_fs_commit btrfs xxxxxxxxxxxx \
+	"btrfs: fix the fsverity callback where unexpected range is verified"
+
+. ./common/verity
+
+_require_xfs_io_command "fpunch"
+_require_check_dmesg
+_require_scratch_verity
+
+filesize=$(( 32 * 1024 * 1024 ))
+interval=$(( 128 * 1024 ))
+holesize=$(( 64 * 1024 ))
+
+_scratch_mkfs_verity >> $seqres.full
+_scratch_mount
+
+# Create a large enough file so that readahead is triggered, and
+# large folios are allocated during readahead.
+_pwrite_byte "0xcd" 0 "$filesize" "$SCRATCH_MNT/foobar" > /dev/null
+
+# Create a hole for every $interval bytes. This should limit the read to
+# $(( $interval - $holesize)), which should be much smaller than the maximum
+# folio size (2M for x86_64).
+for (( i = 0; i < $(( $filesize / $interval )); i++ )); do
+	$XFS_IO_PROG -c "fpunch $(( $i * $interval )) $holesize" \
+		"$SCRATCH_MNT/foobar" > /dev/null
+done
+
+_fsv_enable "$SCRATCH_MNT/foobar"
+
+# Cycle mount to drop page cache
+_scratch_cycle_mount
+
+# Read the file, unpatched btrfs will verify blocks outside the read range and
+# trigger fs-verity warnings.
+# But the read itself should still be fine, as the failed part will be retried.
+cat "$SCRATCH_MNT/foobar" > /dev/null
+
+# Check for any kernel warnings from fs-verity on file corruption.
+if _check_dmesg_for "FILE CORRUPTED!"; then
+	echo "fs-verity detected corruption"
+fi
+echo "Silence is golden"
+
+_exit 0
diff --git a/tests/generic/807.out b/tests/generic/807.out
new file mode 100644
index 00000000..3752a5f7
--- /dev/null
+++ b/tests/generic/807.out
@@ -0,0 +1,2 @@
+QA output created by 807
+Silence is golden
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] fstests: generic: add a test case to check fsverity reads
  2026-10-10  9:04 [PATCH v2] fstests: generic: add a test case to check fsverity reads Qu Wenruo
@ 2026-10-11 18:49 ` Dhruva G
  2026-10-11 21:23   ` Qu Wenruo
  0 siblings, 1 reply; 3+ messages in thread
From: Dhruva G @ 2026-10-11 18:49 UTC (permalink / raw)
  To: Qu Wenruo, linux-btrfs, fstests

On 10-10-2026 14:34, Qu Wenruo wrote:
> There is a bug report that with the recently enabled large folios

Do you want to perhaps add a link to this bug report? Just for more context,
no hard requirement as such.

> support, fsverity enabled files on btrfs can trigger reproducible
> warnings about file corruption, but in the end no error is returned to
> user space.
> 
> It turns out to be a bug in the btrfs fsverity integration, where blocks
> not included in the read range are passed to be verified.
> 
> This is a long-standing bug where btrfs fsverity always assumed that one
> folio contains exactly one fs block, ignoring the fact that btrfs had
> block size < page size support before fsverity support was added.
> 
> Add a new regression test case for it. The workload is pretty simple:
> 
> - Create a 32M file
> 
> - Punch a 64K hole for every 128K
>   This will limit the read bio size to 64K, which is smaller than
>   a lot of large folios, and thus can trigger the btrfs bug.
> 
> - Enable fsverity digest and drop page cache
> 
> - Read that file
> 
> - Verify there is no "FILE CORRUPTED!" warning
> 
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> ---
> Changelog
> v2:
> - Do not use btrfs specific mount options to limit read bio size
>   Use holes to limit the size of read bios instead, now the test case
>   can be generic other than btrfs specific.
> 
> - Add the missing _require_check_dmesg call
> 
> v1:
> https://lore.kernel.org/linux-btrfs/20261010032508.36935-1-wqu@suse.com/
> ---
>  tests/generic/807     | 56 +++++++++++++++++++++++++++++++++++++++++++
>  tests/generic/807.out |  2 ++
>  2 files changed, 58 insertions(+)
>  create mode 100755 tests/generic/807
>  create mode 100644 tests/generic/807.out
> 
> diff --git a/tests/generic/807 b/tests/generic/807
> new file mode 100755
> index 00000000..24e22e8c
> --- /dev/null
> +++ b/tests/generic/807
> @@ -0,0 +1,56 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2026 SUSE S.A.  All Rights Reserved.
> +#
> +# FS QA Test 807
> +#
> +# Verify that reading a large file with holes won't trigger fsverity warnings
> +#
> +. ./common/preamble
> +_begin_fstest auto quick verity
> +
> +_fixed_by_fs_commit btrfs xxxxxxxxxxxx \
> +	"btrfs: fix the fsverity callback where unexpected range is verified"
> +
> +. ./common/verity
> +
> +_require_xfs_io_command "fpunch"
> +_require_check_dmesg
> +_require_scratch_verity
> +
> +filesize=$(( 32 * 1024 * 1024 ))
> +interval=$(( 128 * 1024 ))
> +holesize=$(( 64 * 1024 ))
> +
> +_scratch_mkfs_verity >> $seqres.full
> +_scratch_mount
> +
> +# Create a large enough file so that readahead is triggered, and
> +# large folios are allocated during readahead.
> +_pwrite_byte "0xcd" 0 "$filesize" "$SCRATCH_MNT/foobar" > /dev/null
> +
> +# Create a hole for every $interval bytes. This should limit the read to
> +# $(( $interval - $holesize)), which should be much smaller than the maximum
> +# folio size (2M for x86_64).
> +for (( i = 0; i < $(( $filesize / $interval )); i++ )); do
> +	$XFS_IO_PROG -c "fpunch $(( $i * $interval )) $holesize" \
> +		"$SCRATCH_MNT/foobar" > /dev/null
> +done
> +
> +_fsv_enable "$SCRATCH_MNT/foobar"

Could this disable signature enforcement with _disable_fsverity_signatures
and restore it from _cleanup(), as generic/572 and generic/788 do?

With fs.verity.require_signatures=1, _require_scratch_verity() succeeds:
_fsv_can_enable() temporarily disables signature enforcement and then
restores it. The later _fsv_enable() therefore fails with EPERM because
foobar is unsigned. I reproduced the output mismatch in the local Btrfs
VM; the same test passed with require_signatures=0

> +
> +# Cycle mount to drop page cache
> +_scratch_cycle_mount
> +
> +# Read the file, unpatched btrfs will verify blocks outside the read range and
> +# trigger fs-verity warnings.
> +# But the read itself should still be fine, as the failed part will be retried.
> +cat "$SCRATCH_MNT/foobar" > /dev/null
> +
> +# Check for any kernel warnings from fs-verity on file corruption.
> +if _check_dmesg_for "FILE CORRUPTED!"; then
> +	echo "fs-verity detected corruption"
> +fi
> +echo "Silence is golden"
> +
> +_exit 0
> diff --git a/tests/generic/807.out b/tests/generic/807.out
> new file mode 100644
> index 00000000..3752a5f7
> --- /dev/null
> +++ b/tests/generic/807.out
> @@ -0,0 +1,2 @@
> +QA output created by 807
> +Silence is golden


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] fstests: generic: add a test case to check fsverity reads
  2026-10-11 18:49 ` Dhruva G
@ 2026-10-11 21:23   ` Qu Wenruo
  0 siblings, 0 replies; 3+ messages in thread
From: Qu Wenruo @ 2026-10-11 21:23 UTC (permalink / raw)
  To: Dhruva G, linux-btrfs, fstests



在 2026/10/12 05:19, Dhruva G 写道:
> On 10-10-2026 14:34, Qu Wenruo wrote:
>> There is a bug report that with the recently enabled large folios
> 
> Do you want to perhaps add a link to this bug report? Just for more context,
> no hard requirement as such.

If you want the report, just check the btrfs fix patch.

A regression test doesn't care about the initial report, only a kernel 
fix care.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-10-11 21:23 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-10  9:04 [PATCH v2] fstests: generic: add a test case to check fsverity reads Qu Wenruo
2026-10-11 18:49 ` Dhruva G
2026-10-11 21:23   ` Qu Wenruo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox