* [PATCH v3] fstests: generic: add a test case to check fsverity reads
@ 2026-10-11 22:26 Qu Wenruo
2026-10-12 12:33 ` Christoph Hellwig
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Qu Wenruo @ 2026-10-11 22:26 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
v3:
- Disable signature verification temporarily for the test
Pointed out by Dhruva, as it's a user configurable behavior that if
signature is required, reading the file without a signature will lead
to an EPERM error.
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
---
tests/generic/807 | 65 +++++++++++++++++++++++++++++++++++++++++++
tests/generic/807.out | 2 ++
2 files changed, 67 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..bdd89a08
--- /dev/null
+++ b/tests/generic/807
@@ -0,0 +1,65 @@
+#! /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
+
+# Override the default cleanup function.
+_cleanup()
+{
+ cd /
+ _restore_fsverity_signatures
+ rm -f $tmp.*
+}
+
+_require_xfs_io_command "fpunch"
+_require_check_dmesg
+_require_scratch_verity
+_disable_fsverity_signatures
+
+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] 7+ messages in thread* Re: [PATCH v3] fstests: generic: add a test case to check fsverity reads
2026-10-11 22:26 [PATCH v3] fstests: generic: add a test case to check fsverity reads Qu Wenruo
@ 2026-10-12 12:33 ` Christoph Hellwig
2026-10-12 16:32 ` Dhruva G
2026-10-16 7:47 ` Eric Biggers
2 siblings, 0 replies; 7+ messages in thread
From: Christoph Hellwig @ 2026-10-12 12:33 UTC (permalink / raw)
To: Qu Wenruo; +Cc: linux-btrfs, fstests
Looks good:
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3] fstests: generic: add a test case to check fsverity reads
2026-10-11 22:26 [PATCH v3] fstests: generic: add a test case to check fsverity reads Qu Wenruo
2026-10-12 12:33 ` Christoph Hellwig
@ 2026-10-12 16:32 ` Dhruva G
2026-10-16 7:47 ` Eric Biggers
2 siblings, 0 replies; 7+ messages in thread
From: Dhruva G @ 2026-10-12 16:32 UTC (permalink / raw)
To: Qu Wenruo, linux-btrfs, fstests
On 12-10-2026 03:56, Qu Wenruo wrote:
> 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
> v3:
> - Disable signature verification temporarily for the test
> Pointed out by Dhruva, as it's a user configurable behavior that if
> signature is required, reading the file without a signature will lead
> to an EPERM error.
Thanks, looks good.
Tested-by: Dhruva Gole <goledhruva@gmail.com>
Reviewed-by: Dhruva Gole <goledhruva@gmail.com>
Regards,
Dhruva
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3] fstests: generic: add a test case to check fsverity reads
2026-10-11 22:26 [PATCH v3] fstests: generic: add a test case to check fsverity reads Qu Wenruo
2026-10-12 12:33 ` Christoph Hellwig
2026-10-12 16:32 ` Dhruva G
@ 2026-10-16 7:47 ` Eric Biggers
2026-10-16 8:05 ` Qu Wenruo
2 siblings, 1 reply; 7+ messages in thread
From: Eric Biggers @ 2026-10-16 7:47 UTC (permalink / raw)
To: Qu Wenruo; +Cc: linux-btrfs, fstests
On Mon, Oct 12, 2026 at 08:56:13AM +1030, Qu Wenruo wrote:
> +_fixed_by_fs_commit btrfs xxxxxxxxxxxx \
> + "btrfs: fix the fsverity callback where unexpected range is verified"
Even without that commit, 'kvm-xfstests -c btrfs generic/807' still
passes. Under what circumstances will this test fail?
> +# 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
How about using md5sum and putting the expected value in the .out file,
so the contents are validated too?
> +# Check for any kernel warnings from fs-verity on file corruption.
> +if _check_dmesg_for "FILE CORRUPTED!"; then
> + echo "fs-verity detected corruption"
> +fi
Is there a way to use the fserror support being added by
https://lore.kernel.org/fsverity/20261002223705.2175542-2-aalbersh@kernel.org/
instead of relying on the unstable text printed to the kernel log? If
the string is changed at all, this test will become ineffective.
- Eric
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3] fstests: generic: add a test case to check fsverity reads
2026-10-16 7:47 ` Eric Biggers
@ 2026-10-16 8:05 ` Qu Wenruo
2026-10-16 8:24 ` Eric Biggers
0 siblings, 1 reply; 7+ messages in thread
From: Qu Wenruo @ 2026-10-16 8:05 UTC (permalink / raw)
To: Eric Biggers; +Cc: linux-btrfs, fstests
在 2026/10/16 18:17, Eric Biggers 写道:
> On Mon, Oct 12, 2026 at 08:56:13AM +1030, Qu Wenruo wrote:
>> +_fixed_by_fs_commit btrfs xxxxxxxxxxxx \
>> + "btrfs: fix the fsverity callback where unexpected range is verified"
>
> Even without that commit, 'kvm-xfstests -c btrfs generic/807' still
> passes. Under what circumstances will this test fail?
It need as least 7.2 upstream, which enables large data folios for btrfs
by default.
And I can always reproduce it here, mind to provide more info about the
passed run?
>
>> +# 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
>
> How about using md5sum and putting the expected value in the .out file,
> so the contents are validated too?
That won't catch the problem.
The root problem is that, for a large folio, a read bio can only cover
part of the folio.
And at end io time, unpatched btrfs call fsverity_verify_folio() which
can have data that is still under read, thus fsverity will report errors.
However after each read, the correct data are already copied into the
page cache.
So after a fsverity verification failure, MM/VFS will retry the read,
and since other parts may have already copied the correct data into page
cache, eventually the incorrect fsverity_verify_folio() will succeed,
thus no read error is returned to the user space.
So md5sum will always be correct.
>
>> +# Check for any kernel warnings from fs-verity on file corruption.
>> +if _check_dmesg_for "FILE CORRUPTED!"; then
>> + echo "fs-verity detected corruption"
>> +fi
>
> Is there a way to use the fserror support being added by
> https://lore.kernel.org/fsverity/20261002223705.2175542-2-aalbersh@kernel.org/
> instead of relying on the unstable text printed to the kernel log? If
> the string is changed at all, this test will become ineffective.
That's a better idea, I'll need to check if it's possible grab fserror
info from btrfs.
Thanks,
Qu
>
> - Eric
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3] fstests: generic: add a test case to check fsverity reads
2026-10-16 8:05 ` Qu Wenruo
@ 2026-10-16 8:24 ` Eric Biggers
2026-10-16 8:54 ` Qu Wenruo
0 siblings, 1 reply; 7+ messages in thread
From: Eric Biggers @ 2026-10-16 8:24 UTC (permalink / raw)
To: Qu Wenruo; +Cc: linux-btrfs, fstests
On Fri, Oct 16, 2026 at 06:35:05PM +1030, Qu Wenruo wrote:
>
>
> 在 2026/10/16 18:17, Eric Biggers 写道:
> > On Mon, Oct 12, 2026 at 08:56:13AM +1030, Qu Wenruo wrote:
> > > +_fixed_by_fs_commit btrfs xxxxxxxxxxxx \
> > > + "btrfs: fix the fsverity callback where unexpected range is verified"
> >
> > Even without that commit, 'kvm-xfstests -c btrfs generic/807' still
> > passes. Under what circumstances will this test fail?
>
> It need as least 7.2 upstream, which enables large data folios for btrfs by
> default.
>
> And I can always reproduce it here, mind to provide more info about the
> passed run?
This is on the latest mainline (2f2f7eeef8b0). Not sure what else
you're looking for.
> > > +# 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
> >
> > How about using md5sum and putting the expected value in the .out file,
> > so the contents are validated too?
>
> That won't catch the problem.
I know, but it might as well be checked too.
- Eric
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3] fstests: generic: add a test case to check fsverity reads
2026-10-16 8:24 ` Eric Biggers
@ 2026-10-16 8:54 ` Qu Wenruo
0 siblings, 0 replies; 7+ messages in thread
From: Qu Wenruo @ 2026-10-16 8:54 UTC (permalink / raw)
To: Eric Biggers, Qu Wenruo; +Cc: linux-btrfs, fstests
在 2026/10/16 18:54, Eric Biggers 写道:
> On Fri, Oct 16, 2026 at 06:35:05PM +1030, Qu Wenruo wrote:
>>
>>
>> 在 2026/10/16 18:17, Eric Biggers 写道:
>>> On Mon, Oct 12, 2026 at 08:56:13AM +1030, Qu Wenruo wrote:
>>>> +_fixed_by_fs_commit btrfs xxxxxxxxxxxx \
>>>> + "btrfs: fix the fsverity callback where unexpected range is verified"
>>>
>>> Even without that commit, 'kvm-xfstests -c btrfs generic/807' still
>>> passes. Under what circumstances will this test fail?
>>
>> It need as least 7.2 upstream, which enables large data folios for btrfs by
>> default.
>>
>> And I can always reproduce it here, mind to provide more info about the
>> passed run?
>
> This is on the latest mainline (2f2f7eeef8b0). Not sure what else
> you're looking for.
It can be racy, since the fsverity call is at endio time, if all the
endio of the same large folio is called after all the reads of the folio
finished, it can also pass the verification.
But I don't think it's that possible, unless you have blazing fast storage.
As the first hole read should trigger the verification for the whole
folio and trigger an fsverity error immediately.
I can enlarge the file size, or even git it a loop to run multiple
times, but I just can't figure out why...
Or is it possible that the kernel config doesn't have
CONFIG_TRANSPARENT_HUGEPAGE?
>
>>>> +# 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
>>>
>>> How about using md5sum and putting the expected value in the .out file,
>>> so the contents are validated too?
>>
>> That won't catch the problem.
>
> I know, but it might as well be checked too.
I'm fine adding the md5sum output.
Thanks,
Qu
>
> - Eric
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-10-16 8:54 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-11 22:26 [PATCH v3] fstests: generic: add a test case to check fsverity reads Qu Wenruo
2026-10-12 12:33 ` Christoph Hellwig
2026-10-12 16:32 ` Dhruva G
2026-10-16 7:47 ` Eric Biggers
2026-10-16 8:05 ` Qu Wenruo
2026-10-16 8:24 ` Eric Biggers
2026-10-16 8:54 ` Qu Wenruo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox