* [PATCH] generic: test overwriting file with mmap on a full filesystem
@ 2025-07-09 8:53 fdmanana
2025-07-10 7:29 ` Zorro Lang
2025-07-10 17:03 ` [PATCH v2] " fdmanana
0 siblings, 2 replies; 14+ messages in thread
From: fdmanana @ 2025-07-09 8:53 UTC (permalink / raw)
To: fstests; +Cc: linux-btrfs, Filipe Manana
From: Filipe Manana <fdmanana@suse.com>
Test that overwriting a file with mmap when the filesystem has no more
space available for data allocation works. The motivation here is to check
that NOCOW mode of a COW filesystem (such as btrfs) works as expected.
This currently fails with btrfs but it's fixed by a kernel patch that has
the subject:
btrfs: fix -ENOSPC mmap write failure on NOCOW files/extents
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
tests/generic/211 | 58 +++++++++++++++++++++++++++++++++++++++++++
tests/generic/211.out | 6 +++++
2 files changed, 64 insertions(+)
create mode 100755 tests/generic/211
create mode 100644 tests/generic/211.out
diff --git a/tests/generic/211 b/tests/generic/211
new file mode 100755
index 00000000..c77508fe
--- /dev/null
+++ b/tests/generic/211
@@ -0,0 +1,58 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 SUSE Linux Products GmbH. All Rights Reserved.
+#
+# FS QA Test 211
+#
+# Test that overwriting a file with mmap when the filesystem has no more space
+# available for data allocation works. The motivation here is to check that
+# NOCOW mode of a COW filesystem (such as btrfs) works as expected.
+#
+. ./common/preamble
+_begin_fstest auto quick rw mmap
+
+. ./common/filter
+
+_require_scratch
+
+[ "$FSTYP" = "btrfs" ] && _fixed_by_kernel_commit xxxxxxxxxxxx \
+ "btrfs: fix -ENOSPC mmap write failure on NOCOW files/extents"
+
+# Use a 512M fs so that it's fast to fill it with data but not too small such
+# that on btrfs it results in a fs with mixed block groups - we want to have
+# dedicated block groups for data and metadata, so that after filling all the
+# data block groups we can do a NOCOW write with mmap (if we have enough free
+# metadata space available).
+fs_size=$(_small_fs_size_mb 512)
+_scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1 || \
+ _fail "mkfs failed"
+_scratch_mount
+
+touch $SCRATCH_MNT/foobar
+
+# Set the file to NOCOW mode on btrfs, which must be done while the file is
+# empty, otherwise it fails.
+if [ $FSTYP == "btrfs" ]; then
+ _require_chattr C
+ $CHATTR_PROG +C $SCRATCH_MNT/foobar
+fi
+
+# Add initial data to the file we will later overwrite with mmap.
+$XFS_IO_PROG -c "pwrite -S 0xab 0 1M" $SCRATCH_MNT/foobar | _filter_xfs_io
+
+# Now fill all the remaining space with data.
+blksz=$(_get_block_size $SCRATCH_MNT)
+dd if=/dev/zero of=$SCRATCH_MNT/filler bs=$blksz >>$seqres.full 2>&1
+
+# Overwrite the file with a mmap write. Should succeed.
+$XFS_IO_PROG -c "mmap -w 0 1M" \
+ -c "mwrite -S 0xcd 0 1M" \
+ -c "munmap" \
+ $SCRATCH_MNT/foobar
+
+# Cycle mount and dump the file's content. We expect to see the new data.
+_scratch_cycle_mount
+_hexdump $SCRATCH_MNT/foobar
+
+# success, all done
+_exit 0
diff --git a/tests/generic/211.out b/tests/generic/211.out
new file mode 100644
index 00000000..71cdf0f8
--- /dev/null
+++ b/tests/generic/211.out
@@ -0,0 +1,6 @@
+QA output created by 211
+wrote 1048576/1048576 bytes at offset 0
+XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+000000 cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd >................<
+*
+100000
--
2.47.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH] generic: test overwriting file with mmap on a full filesystem
2025-07-09 8:53 [PATCH] generic: test overwriting file with mmap on a full filesystem fdmanana
@ 2025-07-10 7:29 ` Zorro Lang
2025-07-10 7:45 ` Qu Wenruo
2025-07-10 11:47 ` Filipe Manana
2025-07-10 17:03 ` [PATCH v2] " fdmanana
1 sibling, 2 replies; 14+ messages in thread
From: Zorro Lang @ 2025-07-10 7:29 UTC (permalink / raw)
To: fdmanana; +Cc: fstests, linux-btrfs, Filipe Manana
On Wed, Jul 09, 2025 at 09:53:50AM +0100, fdmanana@kernel.org wrote:
> From: Filipe Manana <fdmanana@suse.com>
>
> Test that overwriting a file with mmap when the filesystem has no more
> space available for data allocation works. The motivation here is to check
> that NOCOW mode of a COW filesystem (such as btrfs) works as expected.
>
> This currently fails with btrfs but it's fixed by a kernel patch that has
> the subject:
>
> btrfs: fix -ENOSPC mmap write failure on NOCOW files/extents
>
> Signed-off-by: Filipe Manana <fdmanana@suse.com>
> ---
> tests/generic/211 | 58 +++++++++++++++++++++++++++++++++++++++++++
> tests/generic/211.out | 6 +++++
> 2 files changed, 64 insertions(+)
> create mode 100755 tests/generic/211
> create mode 100644 tests/generic/211.out
>
> diff --git a/tests/generic/211 b/tests/generic/211
> new file mode 100755
> index 00000000..c77508fe
> --- /dev/null
> +++ b/tests/generic/211
> @@ -0,0 +1,58 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 SUSE Linux Products GmbH. All Rights Reserved.
> +#
> +# FS QA Test 211
> +#
> +# Test that overwriting a file with mmap when the filesystem has no more space
> +# available for data allocation works. The motivation here is to check that
> +# NOCOW mode of a COW filesystem (such as btrfs) works as expected.
> +#
> +. ./common/preamble
> +_begin_fstest auto quick rw mmap
> +
> +. ./common/filter
> +
> +_require_scratch
> +
> +[ "$FSTYP" = "btrfs" ] && _fixed_by_kernel_commit xxxxxxxxxxxx \
> + "btrfs: fix -ENOSPC mmap write failure on NOCOW files/extents"
> +
> +# Use a 512M fs so that it's fast to fill it with data but not too small such
> +# that on btrfs it results in a fs with mixed block groups - we want to have
> +# dedicated block groups for data and metadata, so that after filling all the
> +# data block groups we can do a NOCOW write with mmap (if we have enough free
> +# metadata space available).
> +fs_size=$(_small_fs_size_mb 512)
> +_scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1 || \
> + _fail "mkfs failed"
_scratch_mkfs_sized calls _notrun if it fails:
_scratch_mkfs_sized()
{
_try_scratch_mkfs_sized "$@" || _notrun "_scratch_mkfs_sized failed with ($*)"
}
So you can let it _notrun:
_scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1
or you'd like to _fail:
_try_scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1 || \
_fail "mkfs failed"
> +_scratch_mount
> +
> +touch $SCRATCH_MNT/foobar
> +
> +# Set the file to NOCOW mode on btrfs, which must be done while the file is
> +# empty, otherwise it fails.
> +if [ $FSTYP == "btrfs" ]; then
> + _require_chattr C
> + $CHATTR_PROG +C $SCRATCH_MNT/foobar
> +fi
> +
> +# Add initial data to the file we will later overwrite with mmap.
> +$XFS_IO_PROG -c "pwrite -S 0xab 0 1M" $SCRATCH_MNT/foobar | _filter_xfs_io
> +
> +# Now fill all the remaining space with data.
> +blksz=$(_get_block_size $SCRATCH_MNT)
> +dd if=/dev/zero of=$SCRATCH_MNT/filler bs=$blksz >>$seqres.full 2>&1
As this's a generic test case, I'm wondering if the common/populate:_fill_fs()
helps?
Thanks,
Zorro
> +
> +# Overwrite the file with a mmap write. Should succeed.
> +$XFS_IO_PROG -c "mmap -w 0 1M" \
> + -c "mwrite -S 0xcd 0 1M" \
> + -c "munmap" \
> + $SCRATCH_MNT/foobar
> +
> +# Cycle mount and dump the file's content. We expect to see the new data.
> +_scratch_cycle_mount
> +_hexdump $SCRATCH_MNT/foobar
> +
> +# success, all done
> +_exit 0
> diff --git a/tests/generic/211.out b/tests/generic/211.out
> new file mode 100644
> index 00000000..71cdf0f8
> --- /dev/null
> +++ b/tests/generic/211.out
> @@ -0,0 +1,6 @@
> +QA output created by 211
> +wrote 1048576/1048576 bytes at offset 0
> +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> +000000 cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd >................<
> +*
> +100000
> --
> 2.47.2
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] generic: test overwriting file with mmap on a full filesystem
2025-07-10 7:29 ` Zorro Lang
@ 2025-07-10 7:45 ` Qu Wenruo
2025-07-10 11:47 ` Filipe Manana
1 sibling, 0 replies; 14+ messages in thread
From: Qu Wenruo @ 2025-07-10 7:45 UTC (permalink / raw)
To: Zorro Lang, fdmanana; +Cc: fstests, linux-btrfs, Filipe Manana
在 2025/7/10 16:59, Zorro Lang 写道:
> On Wed, Jul 09, 2025 at 09:53:50AM +0100, fdmanana@kernel.org wrote:
>> From: Filipe Manana <fdmanana@suse.com>
>>
>> Test that overwriting a file with mmap when the filesystem has no more
>> space available for data allocation works. The motivation here is to check
>> that NOCOW mode of a COW filesystem (such as btrfs) works as expected.
>>
>> This currently fails with btrfs but it's fixed by a kernel patch that has
>> the subject:
>>
>> btrfs: fix -ENOSPC mmap write failure on NOCOW files/extents
>>
>> Signed-off-by: Filipe Manana <fdmanana@suse.com>
>> ---
>> tests/generic/211 | 58 +++++++++++++++++++++++++++++++++++++++++++
>> tests/generic/211.out | 6 +++++
>> 2 files changed, 64 insertions(+)
>> create mode 100755 tests/generic/211
>> create mode 100644 tests/generic/211.out
>>
>> diff --git a/tests/generic/211 b/tests/generic/211
>> new file mode 100755
>> index 00000000..c77508fe
>> --- /dev/null
>> +++ b/tests/generic/211
>> @@ -0,0 +1,58 @@
>> +#! /bin/bash
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Copyright (c) 2025 SUSE Linux Products GmbH. All Rights Reserved.
>> +#
>> +# FS QA Test 211
>> +#
>> +# Test that overwriting a file with mmap when the filesystem has no more space
>> +# available for data allocation works. The motivation here is to check that
>> +# NOCOW mode of a COW filesystem (such as btrfs) works as expected.
>> +#
>> +. ./common/preamble
>> +_begin_fstest auto quick rw mmap
>> +
>> +. ./common/filter
>> +
>> +_require_scratch
>> +
>> +[ "$FSTYP" = "btrfs" ] && _fixed_by_kernel_commit xxxxxxxxxxxx \
>> + "btrfs: fix -ENOSPC mmap write failure on NOCOW files/extents"
>> +
>> +# Use a 512M fs so that it's fast to fill it with data but not too small such
>> +# that on btrfs it results in a fs with mixed block groups - we want to have
>> +# dedicated block groups for data and metadata, so that after filling all the
>> +# data block groups we can do a NOCOW write with mmap (if we have enough free
>> +# metadata space available).
>> +fs_size=$(_small_fs_size_mb 512)
>> +_scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1 || \
>> + _fail "mkfs failed"
>
> _scratch_mkfs_sized calls _notrun if it fails:
>
> _scratch_mkfs_sized()
> {
> _try_scratch_mkfs_sized "$@" || _notrun "_scratch_mkfs_sized failed with ($*)"
> }
>
> So you can let it _notrun:
> _scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1
>
> or you'd like to _fail:
>
> _try_scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1 || \
> _fail "mkfs failed"
>
>> +_scratch_mount
>> +
>> +touch $SCRATCH_MNT/foobar
>> +
>> +# Set the file to NOCOW mode on btrfs, which must be done while the file is
>> +# empty, otherwise it fails.
>> +if [ $FSTYP == "btrfs" ]; then
>> + _require_chattr C
>> + $CHATTR_PROG +C $SCRATCH_MNT/foobar
>> +fi
>> +
>> +# Add initial data to the file we will later overwrite with mmap.
>> +$XFS_IO_PROG -c "pwrite -S 0xab 0 1M" $SCRATCH_MNT/foobar | _filter_xfs_io
>> +
>> +# Now fill all the remaining space with data.
>> +blksz=$(_get_block_size $SCRATCH_MNT)
>> +dd if=/dev/zero of=$SCRATCH_MNT/filler bs=$blksz >>$seqres.full 2>&1
>
> As this's a generic test case, I'm wondering if the common/populate:_fill_fs()
> helps?
I believe that helper is a little overkilled, we don't want unnecessary
files to take up our metadata space so it may cause false ENOSPC, at
least for btrfs.
Just writing until ENOSPC should result the minimal amount of metadata
space usage here.
Or do other filesystems have some extra data reservation behavior that
requires such retry to fully exhaust the space?
Thanks,
Qu
>
> Thanks,
> Zorro
>
>> +
>> +# Overwrite the file with a mmap write. Should succeed.
>> +$XFS_IO_PROG -c "mmap -w 0 1M" \
>> + -c "mwrite -S 0xcd 0 1M" \
>> + -c "munmap" \
>> + $SCRATCH_MNT/foobar
>> +
>> +# Cycle mount and dump the file's content. We expect to see the new data.
>> +_scratch_cycle_mount
>> +_hexdump $SCRATCH_MNT/foobar
>> +
>> +# success, all done
>> +_exit 0
>> diff --git a/tests/generic/211.out b/tests/generic/211.out
>> new file mode 100644
>> index 00000000..71cdf0f8
>> --- /dev/null
>> +++ b/tests/generic/211.out
>> @@ -0,0 +1,6 @@
>> +QA output created by 211
>> +wrote 1048576/1048576 bytes at offset 0
>> +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>> +000000 cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd >................<
>> +*
>> +100000
>> --
>> 2.47.2
>>
>>
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] generic: test overwriting file with mmap on a full filesystem
2025-07-10 7:29 ` Zorro Lang
2025-07-10 7:45 ` Qu Wenruo
@ 2025-07-10 11:47 ` Filipe Manana
2025-07-10 16:07 ` Zorro Lang
1 sibling, 1 reply; 14+ messages in thread
From: Filipe Manana @ 2025-07-10 11:47 UTC (permalink / raw)
To: Zorro Lang; +Cc: fstests, linux-btrfs, Filipe Manana
On Thu, Jul 10, 2025 at 8:29 AM Zorro Lang <zlang@redhat.com> wrote:
>
> On Wed, Jul 09, 2025 at 09:53:50AM +0100, fdmanana@kernel.org wrote:
> > From: Filipe Manana <fdmanana@suse.com>
> >
> > Test that overwriting a file with mmap when the filesystem has no more
> > space available for data allocation works. The motivation here is to check
> > that NOCOW mode of a COW filesystem (such as btrfs) works as expected.
> >
> > This currently fails with btrfs but it's fixed by a kernel patch that has
> > the subject:
> >
> > btrfs: fix -ENOSPC mmap write failure on NOCOW files/extents
> >
> > Signed-off-by: Filipe Manana <fdmanana@suse.com>
> > ---
> > tests/generic/211 | 58 +++++++++++++++++++++++++++++++++++++++++++
> > tests/generic/211.out | 6 +++++
> > 2 files changed, 64 insertions(+)
> > create mode 100755 tests/generic/211
> > create mode 100644 tests/generic/211.out
> >
> > diff --git a/tests/generic/211 b/tests/generic/211
> > new file mode 100755
> > index 00000000..c77508fe
> > --- /dev/null
> > +++ b/tests/generic/211
> > @@ -0,0 +1,58 @@
> > +#! /bin/bash
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (c) 2025 SUSE Linux Products GmbH. All Rights Reserved.
> > +#
> > +# FS QA Test 211
> > +#
> > +# Test that overwriting a file with mmap when the filesystem has no more space
> > +# available for data allocation works. The motivation here is to check that
> > +# NOCOW mode of a COW filesystem (such as btrfs) works as expected.
> > +#
> > +. ./common/preamble
> > +_begin_fstest auto quick rw mmap
> > +
> > +. ./common/filter
> > +
> > +_require_scratch
> > +
> > +[ "$FSTYP" = "btrfs" ] && _fixed_by_kernel_commit xxxxxxxxxxxx \
> > + "btrfs: fix -ENOSPC mmap write failure on NOCOW files/extents"
> > +
> > +# Use a 512M fs so that it's fast to fill it with data but not too small such
> > +# that on btrfs it results in a fs with mixed block groups - we want to have
> > +# dedicated block groups for data and metadata, so that after filling all the
> > +# data block groups we can do a NOCOW write with mmap (if we have enough free
> > +# metadata space available).
> > +fs_size=$(_small_fs_size_mb 512)
> > +_scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1 || \
> > + _fail "mkfs failed"
>
> _scratch_mkfs_sized calls _notrun if it fails:
>
> _scratch_mkfs_sized()
> {
> _try_scratch_mkfs_sized "$@" || _notrun "_scratch_mkfs_sized failed with ($*)"
> }
>
> So you can let it _notrun:
> _scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1
>
> or you'd like to _fail:
>
> _try_scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1 || \
> _fail "mkfs failed"
The fail makes more sense to me - having the _scratch_mkfs_sized()
calling _notrun doesn't make sense to me at the moment.
>
> > +_scratch_mount
> > +
> > +touch $SCRATCH_MNT/foobar
> > +
> > +# Set the file to NOCOW mode on btrfs, which must be done while the file is
> > +# empty, otherwise it fails.
> > +if [ $FSTYP == "btrfs" ]; then
> > + _require_chattr C
> > + $CHATTR_PROG +C $SCRATCH_MNT/foobar
> > +fi
> > +
> > +# Add initial data to the file we will later overwrite with mmap.
> > +$XFS_IO_PROG -c "pwrite -S 0xab 0 1M" $SCRATCH_MNT/foobar | _filter_xfs_io
> > +
> > +# Now fill all the remaining space with data.
> > +blksz=$(_get_block_size $SCRATCH_MNT)
> > +dd if=/dev/zero of=$SCRATCH_MNT/filler bs=$blksz >>$seqres.full 2>&1
>
> As this's a generic test case, I'm wondering if the common/populate:_fill_fs()
> helps?
Because the intention is to exhaust data space and leave enough
metadata space free so that the NOCOW write can be done, as Qu already
replied before.
In btrfs we have space divided in two sections (block groups): one for
data and one for metadata.
Metadata is always COWed in btrfs by design, data can be NOCOWed
(chattr +C or prealloc extents for the first write) - as longs as
there's enough metadata space available (every data write requires
updating some metadata).
If this is too specific or hard to comprehend, I can move the test
case into tests/btrfs/ (we have a few similar to this scenario iirc).
Let me know if I shall move it into tests/btrfs/.
Thanks.
>
> Thanks,
> Zorro
>
> > +
> > +# Overwrite the file with a mmap write. Should succeed.
> > +$XFS_IO_PROG -c "mmap -w 0 1M" \
> > + -c "mwrite -S 0xcd 0 1M" \
> > + -c "munmap" \
> > + $SCRATCH_MNT/foobar
> > +
> > +# Cycle mount and dump the file's content. We expect to see the new data.
> > +_scratch_cycle_mount
> > +_hexdump $SCRATCH_MNT/foobar
> > +
> > +# success, all done
> > +_exit 0
> > diff --git a/tests/generic/211.out b/tests/generic/211.out
> > new file mode 100644
> > index 00000000..71cdf0f8
> > --- /dev/null
> > +++ b/tests/generic/211.out
> > @@ -0,0 +1,6 @@
> > +QA output created by 211
> > +wrote 1048576/1048576 bytes at offset 0
> > +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> > +000000 cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd >................<
> > +*
> > +100000
> > --
> > 2.47.2
> >
> >
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] generic: test overwriting file with mmap on a full filesystem
2025-07-10 11:47 ` Filipe Manana
@ 2025-07-10 16:07 ` Zorro Lang
2025-07-10 17:02 ` Filipe Manana
0 siblings, 1 reply; 14+ messages in thread
From: Zorro Lang @ 2025-07-10 16:07 UTC (permalink / raw)
To: Filipe Manana; +Cc: fstests, linux-btrfs, Filipe Manana, Qu Wenruo
On Thu, Jul 10, 2025 at 12:47:30PM +0100, Filipe Manana wrote:
> On Thu, Jul 10, 2025 at 8:29 AM Zorro Lang <zlang@redhat.com> wrote:
> >
> > On Wed, Jul 09, 2025 at 09:53:50AM +0100, fdmanana@kernel.org wrote:
> > > From: Filipe Manana <fdmanana@suse.com>
> > >
> > > Test that overwriting a file with mmap when the filesystem has no more
> > > space available for data allocation works. The motivation here is to check
> > > that NOCOW mode of a COW filesystem (such as btrfs) works as expected.
> > >
> > > This currently fails with btrfs but it's fixed by a kernel patch that has
> > > the subject:
> > >
> > > btrfs: fix -ENOSPC mmap write failure on NOCOW files/extents
> > >
> > > Signed-off-by: Filipe Manana <fdmanana@suse.com>
> > > ---
> > > tests/generic/211 | 58 +++++++++++++++++++++++++++++++++++++++++++
> > > tests/generic/211.out | 6 +++++
> > > 2 files changed, 64 insertions(+)
> > > create mode 100755 tests/generic/211
> > > create mode 100644 tests/generic/211.out
> > >
> > > diff --git a/tests/generic/211 b/tests/generic/211
> > > new file mode 100755
> > > index 00000000..c77508fe
> > > --- /dev/null
> > > +++ b/tests/generic/211
> > > @@ -0,0 +1,58 @@
> > > +#! /bin/bash
> > > +# SPDX-License-Identifier: GPL-2.0
> > > +# Copyright (c) 2025 SUSE Linux Products GmbH. All Rights Reserved.
> > > +#
> > > +# FS QA Test 211
> > > +#
> > > +# Test that overwriting a file with mmap when the filesystem has no more space
> > > +# available for data allocation works. The motivation here is to check that
> > > +# NOCOW mode of a COW filesystem (such as btrfs) works as expected.
> > > +#
> > > +. ./common/preamble
> > > +_begin_fstest auto quick rw mmap
> > > +
> > > +. ./common/filter
> > > +
> > > +_require_scratch
> > > +
> > > +[ "$FSTYP" = "btrfs" ] && _fixed_by_kernel_commit xxxxxxxxxxxx \
> > > + "btrfs: fix -ENOSPC mmap write failure on NOCOW files/extents"
> > > +
> > > +# Use a 512M fs so that it's fast to fill it with data but not too small such
> > > +# that on btrfs it results in a fs with mixed block groups - we want to have
> > > +# dedicated block groups for data and metadata, so that after filling all the
> > > +# data block groups we can do a NOCOW write with mmap (if we have enough free
> > > +# metadata space available).
> > > +fs_size=$(_small_fs_size_mb 512)
> > > +_scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1 || \
> > > + _fail "mkfs failed"
> >
> > _scratch_mkfs_sized calls _notrun if it fails:
> >
> > _scratch_mkfs_sized()
> > {
> > _try_scratch_mkfs_sized "$@" || _notrun "_scratch_mkfs_sized failed with ($*)"
> > }
> >
> > So you can let it _notrun:
> > _scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1
> >
> > or you'd like to _fail:
> >
> > _try_scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1 || \
> > _fail "mkfs failed"
>
> The fail makes more sense to me - having the _scratch_mkfs_sized()
> calling _notrun doesn't make sense to me at the moment.
OK, so you can use _try_scratch_mkfs_sized.
>
> >
> > > +_scratch_mount
> > > +
> > > +touch $SCRATCH_MNT/foobar
> > > +
> > > +# Set the file to NOCOW mode on btrfs, which must be done while the file is
> > > +# empty, otherwise it fails.
> > > +if [ $FSTYP == "btrfs" ]; then
> > > + _require_chattr C
> > > + $CHATTR_PROG +C $SCRATCH_MNT/foobar
> > > +fi
> > > +
> > > +# Add initial data to the file we will later overwrite with mmap.
> > > +$XFS_IO_PROG -c "pwrite -S 0xab 0 1M" $SCRATCH_MNT/foobar | _filter_xfs_io
> > > +
> > > +# Now fill all the remaining space with data.
> > > +blksz=$(_get_block_size $SCRATCH_MNT)
> > > +dd if=/dev/zero of=$SCRATCH_MNT/filler bs=$blksz >>$seqres.full 2>&1
> >
> > As this's a generic test case, I'm wondering if the common/populate:_fill_fs()
> > helps?
>
> Because the intention is to exhaust data space and leave enough
> metadata space free so that the NOCOW write can be done, as Qu already
> replied before.
> In btrfs we have space divided in two sections (block groups): one for
> data and one for metadata.
> Metadata is always COWed in btrfs by design, data can be NOCOWed
> (chattr +C or prealloc extents for the first write) - as longs as
> there's enough metadata space available (every data write requires
> updating some metadata).
>
> If this is too specific or hard to comprehend, I can move the test
> case into tests/btrfs/ (we have a few similar to this scenario iirc).
> Let me know if I shall move it into tests/btrfs/.
Thanks for the detailed explanation from you and Qu:) If so, maybe
_get_file_block_size better than _get_block_size?
I think we can keep this case in generic directory, it's a btrfs bug reproducer
and it won't break other fs test. If someone fs hopes to change that "fill fs"
part, we can use if...else... so maybe you can add more comments about why btrfs
need this dd operation rather than _fill_fs things, to avoid others change this
part in the future.
Thanks,
Zorro
>
> Thanks.
>
> >
> > Thanks,
> > Zorro
> >
> > > +
> > > +# Overwrite the file with a mmap write. Should succeed.
> > > +$XFS_IO_PROG -c "mmap -w 0 1M" \
> > > + -c "mwrite -S 0xcd 0 1M" \
> > > + -c "munmap" \
> > > + $SCRATCH_MNT/foobar
> > > +
> > > +# Cycle mount and dump the file's content. We expect to see the new data.
> > > +_scratch_cycle_mount
> > > +_hexdump $SCRATCH_MNT/foobar
> > > +
> > > +# success, all done
> > > +_exit 0
> > > diff --git a/tests/generic/211.out b/tests/generic/211.out
> > > new file mode 100644
> > > index 00000000..71cdf0f8
> > > --- /dev/null
> > > +++ b/tests/generic/211.out
> > > @@ -0,0 +1,6 @@
> > > +QA output created by 211
> > > +wrote 1048576/1048576 bytes at offset 0
> > > +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> > > +000000 cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd >................<
> > > +*
> > > +100000
> > > --
> > > 2.47.2
> > >
> > >
> >
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] generic: test overwriting file with mmap on a full filesystem
2025-07-10 16:07 ` Zorro Lang
@ 2025-07-10 17:02 ` Filipe Manana
0 siblings, 0 replies; 14+ messages in thread
From: Filipe Manana @ 2025-07-10 17:02 UTC (permalink / raw)
To: Zorro Lang; +Cc: fstests, linux-btrfs, Filipe Manana, Qu Wenruo
On Thu, Jul 10, 2025 at 5:08 PM Zorro Lang <zlang@redhat.com> wrote:
>
> On Thu, Jul 10, 2025 at 12:47:30PM +0100, Filipe Manana wrote:
> > On Thu, Jul 10, 2025 at 8:29 AM Zorro Lang <zlang@redhat.com> wrote:
> > >
> > > On Wed, Jul 09, 2025 at 09:53:50AM +0100, fdmanana@kernel.org wrote:
> > > > From: Filipe Manana <fdmanana@suse.com>
> > > >
> > > > Test that overwriting a file with mmap when the filesystem has no more
> > > > space available for data allocation works. The motivation here is to check
> > > > that NOCOW mode of a COW filesystem (such as btrfs) works as expected.
> > > >
> > > > This currently fails with btrfs but it's fixed by a kernel patch that has
> > > > the subject:
> > > >
> > > > btrfs: fix -ENOSPC mmap write failure on NOCOW files/extents
> > > >
> > > > Signed-off-by: Filipe Manana <fdmanana@suse.com>
> > > > ---
> > > > tests/generic/211 | 58 +++++++++++++++++++++++++++++++++++++++++++
> > > > tests/generic/211.out | 6 +++++
> > > > 2 files changed, 64 insertions(+)
> > > > create mode 100755 tests/generic/211
> > > > create mode 100644 tests/generic/211.out
> > > >
> > > > diff --git a/tests/generic/211 b/tests/generic/211
> > > > new file mode 100755
> > > > index 00000000..c77508fe
> > > > --- /dev/null
> > > > +++ b/tests/generic/211
> > > > @@ -0,0 +1,58 @@
> > > > +#! /bin/bash
> > > > +# SPDX-License-Identifier: GPL-2.0
> > > > +# Copyright (c) 2025 SUSE Linux Products GmbH. All Rights Reserved.
> > > > +#
> > > > +# FS QA Test 211
> > > > +#
> > > > +# Test that overwriting a file with mmap when the filesystem has no more space
> > > > +# available for data allocation works. The motivation here is to check that
> > > > +# NOCOW mode of a COW filesystem (such as btrfs) works as expected.
> > > > +#
> > > > +. ./common/preamble
> > > > +_begin_fstest auto quick rw mmap
> > > > +
> > > > +. ./common/filter
> > > > +
> > > > +_require_scratch
> > > > +
> > > > +[ "$FSTYP" = "btrfs" ] && _fixed_by_kernel_commit xxxxxxxxxxxx \
> > > > + "btrfs: fix -ENOSPC mmap write failure on NOCOW files/extents"
> > > > +
> > > > +# Use a 512M fs so that it's fast to fill it with data but not too small such
> > > > +# that on btrfs it results in a fs with mixed block groups - we want to have
> > > > +# dedicated block groups for data and metadata, so that after filling all the
> > > > +# data block groups we can do a NOCOW write with mmap (if we have enough free
> > > > +# metadata space available).
> > > > +fs_size=$(_small_fs_size_mb 512)
> > > > +_scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1 || \
> > > > + _fail "mkfs failed"
> > >
> > > _scratch_mkfs_sized calls _notrun if it fails:
> > >
> > > _scratch_mkfs_sized()
> > > {
> > > _try_scratch_mkfs_sized "$@" || _notrun "_scratch_mkfs_sized failed with ($*)"
> > > }
> > >
> > > So you can let it _notrun:
> > > _scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1
> > >
> > > or you'd like to _fail:
> > >
> > > _try_scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1 || \
> > > _fail "mkfs failed"
> >
> > The fail makes more sense to me - having the _scratch_mkfs_sized()
> > calling _notrun doesn't make sense to me at the moment.
>
> OK, so you can use _try_scratch_mkfs_sized.
>
> >
> > >
> > > > +_scratch_mount
> > > > +
> > > > +touch $SCRATCH_MNT/foobar
> > > > +
> > > > +# Set the file to NOCOW mode on btrfs, which must be done while the file is
> > > > +# empty, otherwise it fails.
> > > > +if [ $FSTYP == "btrfs" ]; then
> > > > + _require_chattr C
> > > > + $CHATTR_PROG +C $SCRATCH_MNT/foobar
> > > > +fi
> > > > +
> > > > +# Add initial data to the file we will later overwrite with mmap.
> > > > +$XFS_IO_PROG -c "pwrite -S 0xab 0 1M" $SCRATCH_MNT/foobar | _filter_xfs_io
> > > > +
> > > > +# Now fill all the remaining space with data.
> > > > +blksz=$(_get_block_size $SCRATCH_MNT)
> > > > +dd if=/dev/zero of=$SCRATCH_MNT/filler bs=$blksz >>$seqres.full 2>&1
> > >
> > > As this's a generic test case, I'm wondering if the common/populate:_fill_fs()
> > > helps?
> >
> > Because the intention is to exhaust data space and leave enough
> > metadata space free so that the NOCOW write can be done, as Qu already
> > replied before.
> > In btrfs we have space divided in two sections (block groups): one for
> > data and one for metadata.
> > Metadata is always COWed in btrfs by design, data can be NOCOWed
> > (chattr +C or prealloc extents for the first write) - as longs as
> > there's enough metadata space available (every data write requires
> > updating some metadata).
> >
> > If this is too specific or hard to comprehend, I can move the test
> > case into tests/btrfs/ (we have a few similar to this scenario iirc).
> > Let me know if I shall move it into tests/btrfs/.
>
> Thanks for the detailed explanation from you and Qu:) If so, maybe
> _get_file_block_size better than _get_block_size?
>
> I think we can keep this case in generic directory, it's a btrfs bug reproducer
> and it won't break other fs test. If someone fs hopes to change that "fill fs"
> part, we can use if...else... so maybe you can add more comments about why btrfs
> need this dd operation rather than _fill_fs things, to avoid others change this
> part in the future.
Ok, I'll update the comment above dd to be more detailed, about why dd
and not __populate_fill_fs().
Thanks.
>
> Thanks,
> Zorro
>
> >
> > Thanks.
> >
> > >
> > > Thanks,
> > > Zorro
> > >
> > > > +
> > > > +# Overwrite the file with a mmap write. Should succeed.
> > > > +$XFS_IO_PROG -c "mmap -w 0 1M" \
> > > > + -c "mwrite -S 0xcd 0 1M" \
> > > > + -c "munmap" \
> > > > + $SCRATCH_MNT/foobar
> > > > +
> > > > +# Cycle mount and dump the file's content. We expect to see the new data.
> > > > +_scratch_cycle_mount
> > > > +_hexdump $SCRATCH_MNT/foobar
> > > > +
> > > > +# success, all done
> > > > +_exit 0
> > > > diff --git a/tests/generic/211.out b/tests/generic/211.out
> > > > new file mode 100644
> > > > index 00000000..71cdf0f8
> > > > --- /dev/null
> > > > +++ b/tests/generic/211.out
> > > > @@ -0,0 +1,6 @@
> > > > +QA output created by 211
> > > > +wrote 1048576/1048576 bytes at offset 0
> > > > +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> > > > +000000 cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd >................<
> > > > +*
> > > > +100000
> > > > --
> > > > 2.47.2
> > > >
> > > >
> > >
> >
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v2] generic: test overwriting file with mmap on a full filesystem
2025-07-09 8:53 [PATCH] generic: test overwriting file with mmap on a full filesystem fdmanana
2025-07-10 7:29 ` Zorro Lang
@ 2025-07-10 17:03 ` fdmanana
2025-07-10 18:24 ` Zorro Lang
` (2 more replies)
1 sibling, 3 replies; 14+ messages in thread
From: fdmanana @ 2025-07-10 17:03 UTC (permalink / raw)
To: fstests; +Cc: linux-btrfs, Filipe Manana
From: Filipe Manana <fdmanana@suse.com>
Test that overwriting a file with mmap when the filesystem has no more
space available for data allocation works. The motivation here is to check
that NOCOW mode of a COW filesystem (such as btrfs) works as expected.
This currently fails with btrfs but it's fixed by a kernel patch that has
the subject:
btrfs: fix -ENOSPC mmap write failure on NOCOW files/extents
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
V2: Use _try_scratch_mkfs_sized;
Use _get_file_block_size instead of _get_block_size;
Add a more detailed comment about why dd is used to fill the fs.
tests/generic/211 | 63 +++++++++++++++++++++++++++++++++++++++++++
tests/generic/211.out | 6 +++++
2 files changed, 69 insertions(+)
create mode 100755 tests/generic/211
create mode 100644 tests/generic/211.out
diff --git a/tests/generic/211 b/tests/generic/211
new file mode 100755
index 00000000..e87d1e01
--- /dev/null
+++ b/tests/generic/211
@@ -0,0 +1,63 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 SUSE Linux Products GmbH. All Rights Reserved.
+#
+# FS QA Test 211
+#
+# Test that overwriting a file with mmap when the filesystem has no more space
+# available for data allocation works. The motivation here is to check that
+# NOCOW mode of a COW filesystem (such as btrfs) works as expected.
+#
+. ./common/preamble
+_begin_fstest auto quick rw mmap
+
+. ./common/filter
+
+_require_scratch
+
+[ "$FSTYP" = "btrfs" ] && _fixed_by_kernel_commit xxxxxxxxxxxx \
+ "btrfs: fix -ENOSPC mmap write failure on NOCOW files/extents"
+
+# Use a 512M fs so that it's fast to fill it with data but not too small such
+# that on btrfs it results in a fs with mixed block groups - we want to have
+# dedicated block groups for data and metadata, so that after filling all the
+# data block groups we can do a NOCOW write with mmap (if we have enough free
+# metadata space available).
+fs_size=$(_small_fs_size_mb 512)
+_try_scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1 || \
+ _fail "mkfs failed"
+_scratch_mount
+
+touch $SCRATCH_MNT/foobar
+
+# Set the file to NOCOW mode on btrfs, which must be done while the file is
+# empty, otherwise it fails.
+if [ $FSTYP == "btrfs" ]; then
+ _require_chattr C
+ $CHATTR_PROG +C $SCRATCH_MNT/foobar
+fi
+
+# Add initial data to the file we will later overwrite with mmap.
+$XFS_IO_PROG -c "pwrite -S 0xab 0 1M" $SCRATCH_MNT/foobar | _filter_xfs_io
+
+# Now fill all the remaining space with data. We use dd because we want to fill
+# only data space in btrfs - creating files with __populate_fill_fs() would also
+# fill metadata space. We want to exhaust data space on btrfs but still have
+# metadata space available, as metadata is always COWed on btrfs, so that the
+# mmap writes below succeed (metadata space available but no more data space
+# available).
+blksz=$(_get_file_block_size $SCRATCH_MNT)
+dd if=/dev/zero of=$SCRATCH_MNT/filler bs=$blksz >>$seqres.full 2>&1
+
+# Overwrite the file with a mmap write. Should succeed.
+$XFS_IO_PROG -c "mmap -w 0 1M" \
+ -c "mwrite -S 0xcd 0 1M" \
+ -c "munmap" \
+ $SCRATCH_MNT/foobar
+
+# Cycle mount and dump the file's content. We expect to see the new data.
+_scratch_cycle_mount
+_hexdump $SCRATCH_MNT/foobar
+
+# success, all done
+_exit 0
diff --git a/tests/generic/211.out b/tests/generic/211.out
new file mode 100644
index 00000000..71cdf0f8
--- /dev/null
+++ b/tests/generic/211.out
@@ -0,0 +1,6 @@
+QA output created by 211
+wrote 1048576/1048576 bytes at offset 0
+XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+000000 cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd >................<
+*
+100000
--
2.47.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v2] generic: test overwriting file with mmap on a full filesystem
2025-07-10 17:03 ` [PATCH v2] " fdmanana
@ 2025-07-10 18:24 ` Zorro Lang
2025-07-10 22:00 ` Qu Wenruo
2025-07-22 6:55 ` Christoph Hellwig
2 siblings, 0 replies; 14+ messages in thread
From: Zorro Lang @ 2025-07-10 18:24 UTC (permalink / raw)
To: fdmanana; +Cc: fstests, linux-btrfs, Filipe Manana
On Thu, Jul 10, 2025 at 06:03:43PM +0100, fdmanana@kernel.org wrote:
> From: Filipe Manana <fdmanana@suse.com>
>
> Test that overwriting a file with mmap when the filesystem has no more
> space available for data allocation works. The motivation here is to check
> that NOCOW mode of a COW filesystem (such as btrfs) works as expected.
>
> This currently fails with btrfs but it's fixed by a kernel patch that has
> the subject:
>
> btrfs: fix -ENOSPC mmap write failure on NOCOW files/extents
>
> Signed-off-by: Filipe Manana <fdmanana@suse.com>
> ---
>
> V2: Use _try_scratch_mkfs_sized;
> Use _get_file_block_size instead of _get_block_size;
> Add a more detailed comment about why dd is used to fill the fs.
Thanks Filipe, it's going to be merged into patches-in-queue branch, and
will be push in next fstests release (this weekend hopefully)
Reviewed-by: Zorro Lang <zlang@redhat.com>
>
> tests/generic/211 | 63 +++++++++++++++++++++++++++++++++++++++++++
> tests/generic/211.out | 6 +++++
> 2 files changed, 69 insertions(+)
> create mode 100755 tests/generic/211
> create mode 100644 tests/generic/211.out
>
> diff --git a/tests/generic/211 b/tests/generic/211
> new file mode 100755
> index 00000000..e87d1e01
> --- /dev/null
> +++ b/tests/generic/211
> @@ -0,0 +1,63 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 SUSE Linux Products GmbH. All Rights Reserved.
> +#
> +# FS QA Test 211
> +#
> +# Test that overwriting a file with mmap when the filesystem has no more space
> +# available for data allocation works. The motivation here is to check that
> +# NOCOW mode of a COW filesystem (such as btrfs) works as expected.
> +#
> +. ./common/preamble
> +_begin_fstest auto quick rw mmap
> +
> +. ./common/filter
> +
> +_require_scratch
> +
> +[ "$FSTYP" = "btrfs" ] && _fixed_by_kernel_commit xxxxxxxxxxxx \
> + "btrfs: fix -ENOSPC mmap write failure on NOCOW files/extents"
> +
> +# Use a 512M fs so that it's fast to fill it with data but not too small such
> +# that on btrfs it results in a fs with mixed block groups - we want to have
> +# dedicated block groups for data and metadata, so that after filling all the
> +# data block groups we can do a NOCOW write with mmap (if we have enough free
> +# metadata space available).
> +fs_size=$(_small_fs_size_mb 512)
> +_try_scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1 || \
> + _fail "mkfs failed"
> +_scratch_mount
> +
> +touch $SCRATCH_MNT/foobar
> +
> +# Set the file to NOCOW mode on btrfs, which must be done while the file is
> +# empty, otherwise it fails.
> +if [ $FSTYP == "btrfs" ]; then
> + _require_chattr C
> + $CHATTR_PROG +C $SCRATCH_MNT/foobar
> +fi
> +
> +# Add initial data to the file we will later overwrite with mmap.
> +$XFS_IO_PROG -c "pwrite -S 0xab 0 1M" $SCRATCH_MNT/foobar | _filter_xfs_io
> +
> +# Now fill all the remaining space with data. We use dd because we want to fill
> +# only data space in btrfs - creating files with __populate_fill_fs() would also
> +# fill metadata space. We want to exhaust data space on btrfs but still have
> +# metadata space available, as metadata is always COWed on btrfs, so that the
> +# mmap writes below succeed (metadata space available but no more data space
> +# available).
> +blksz=$(_get_file_block_size $SCRATCH_MNT)
> +dd if=/dev/zero of=$SCRATCH_MNT/filler bs=$blksz >>$seqres.full 2>&1
> +
> +# Overwrite the file with a mmap write. Should succeed.
> +$XFS_IO_PROG -c "mmap -w 0 1M" \
> + -c "mwrite -S 0xcd 0 1M" \
> + -c "munmap" \
> + $SCRATCH_MNT/foobar
> +
> +# Cycle mount and dump the file's content. We expect to see the new data.
> +_scratch_cycle_mount
> +_hexdump $SCRATCH_MNT/foobar
> +
> +# success, all done
> +_exit 0
> diff --git a/tests/generic/211.out b/tests/generic/211.out
> new file mode 100644
> index 00000000..71cdf0f8
> --- /dev/null
> +++ b/tests/generic/211.out
> @@ -0,0 +1,6 @@
> +QA output created by 211
> +wrote 1048576/1048576 bytes at offset 0
> +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> +000000 cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd >................<
> +*
> +100000
> --
> 2.47.2
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] generic: test overwriting file with mmap on a full filesystem
2025-07-10 17:03 ` [PATCH v2] " fdmanana
2025-07-10 18:24 ` Zorro Lang
@ 2025-07-10 22:00 ` Qu Wenruo
2025-07-22 6:55 ` Christoph Hellwig
2 siblings, 0 replies; 14+ messages in thread
From: Qu Wenruo @ 2025-07-10 22:00 UTC (permalink / raw)
To: fdmanana, fstests; +Cc: linux-btrfs, Filipe Manana
在 2025/7/11 02:33, fdmanana@kernel.org 写道:
> From: Filipe Manana <fdmanana@suse.com>
>
> Test that overwriting a file with mmap when the filesystem has no more
> space available for data allocation works. The motivation here is to check
> that NOCOW mode of a COW filesystem (such as btrfs) works as expected.
>
> This currently fails with btrfs but it's fixed by a kernel patch that has
> the subject:
>
> btrfs: fix -ENOSPC mmap write failure on NOCOW files/extents
>
> Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Thanks,
Qu
> ---
>
> V2: Use _try_scratch_mkfs_sized;
> Use _get_file_block_size instead of _get_block_size;
> Add a more detailed comment about why dd is used to fill the fs.
>
> tests/generic/211 | 63 +++++++++++++++++++++++++++++++++++++++++++
> tests/generic/211.out | 6 +++++
> 2 files changed, 69 insertions(+)
> create mode 100755 tests/generic/211
> create mode 100644 tests/generic/211.out
>
> diff --git a/tests/generic/211 b/tests/generic/211
> new file mode 100755
> index 00000000..e87d1e01
> --- /dev/null
> +++ b/tests/generic/211
> @@ -0,0 +1,63 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 SUSE Linux Products GmbH. All Rights Reserved.
> +#
> +# FS QA Test 211
> +#
> +# Test that overwriting a file with mmap when the filesystem has no more space
> +# available for data allocation works. The motivation here is to check that
> +# NOCOW mode of a COW filesystem (such as btrfs) works as expected.
> +#
> +. ./common/preamble
> +_begin_fstest auto quick rw mmap
> +
> +. ./common/filter
> +
> +_require_scratch
> +
> +[ "$FSTYP" = "btrfs" ] && _fixed_by_kernel_commit xxxxxxxxxxxx \
> + "btrfs: fix -ENOSPC mmap write failure on NOCOW files/extents"
> +
> +# Use a 512M fs so that it's fast to fill it with data but not too small such
> +# that on btrfs it results in a fs with mixed block groups - we want to have
> +# dedicated block groups for data and metadata, so that after filling all the
> +# data block groups we can do a NOCOW write with mmap (if we have enough free
> +# metadata space available).
> +fs_size=$(_small_fs_size_mb 512)
> +_try_scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1 || \
> + _fail "mkfs failed"
> +_scratch_mount
> +
> +touch $SCRATCH_MNT/foobar
> +
> +# Set the file to NOCOW mode on btrfs, which must be done while the file is
> +# empty, otherwise it fails.
> +if [ $FSTYP == "btrfs" ]; then
> + _require_chattr C
> + $CHATTR_PROG +C $SCRATCH_MNT/foobar
> +fi
> +
> +# Add initial data to the file we will later overwrite with mmap.
> +$XFS_IO_PROG -c "pwrite -S 0xab 0 1M" $SCRATCH_MNT/foobar | _filter_xfs_io
> +
> +# Now fill all the remaining space with data. We use dd because we want to fill
> +# only data space in btrfs - creating files with __populate_fill_fs() would also
> +# fill metadata space. We want to exhaust data space on btrfs but still have
> +# metadata space available, as metadata is always COWed on btrfs, so that the
> +# mmap writes below succeed (metadata space available but no more data space
> +# available).
> +blksz=$(_get_file_block_size $SCRATCH_MNT)
> +dd if=/dev/zero of=$SCRATCH_MNT/filler bs=$blksz >>$seqres.full 2>&1
> +
> +# Overwrite the file with a mmap write. Should succeed.
> +$XFS_IO_PROG -c "mmap -w 0 1M" \
> + -c "mwrite -S 0xcd 0 1M" \
> + -c "munmap" \
> + $SCRATCH_MNT/foobar
> +
> +# Cycle mount and dump the file's content. We expect to see the new data.
> +_scratch_cycle_mount
> +_hexdump $SCRATCH_MNT/foobar
> +
> +# success, all done
> +_exit 0
> diff --git a/tests/generic/211.out b/tests/generic/211.out
> new file mode 100644
> index 00000000..71cdf0f8
> --- /dev/null
> +++ b/tests/generic/211.out
> @@ -0,0 +1,6 @@
> +QA output created by 211
> +wrote 1048576/1048576 bytes at offset 0
> +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> +000000 cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd >................<
> +*
> +100000
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] generic: test overwriting file with mmap on a full filesystem
2025-07-10 17:03 ` [PATCH v2] " fdmanana
2025-07-10 18:24 ` Zorro Lang
2025-07-10 22:00 ` Qu Wenruo
@ 2025-07-22 6:55 ` Christoph Hellwig
2025-07-22 7:50 ` Johannes Thumshirn
2025-07-22 10:27 ` Filipe Manana
2 siblings, 2 replies; 14+ messages in thread
From: Christoph Hellwig @ 2025-07-22 6:55 UTC (permalink / raw)
To: fdmanana
Cc: fstests, linux-btrfs, Filipe Manana, linux-xfs,
johannes.thumshirn, naohiro.aota
I just noticed this test failing on zoned xfs in current for-next.
That's because for out of place overwrite file systems writing at
ENOSPC will obviously fail, and I think the test acknowledges that
by forcing nocow for btrfs.
But that leaves "real" out of place write file systems affected, which
should also include zone btrfs, but the test actually fails there
in mkfs already due to some reason.
Can you please rework the patch to see that setting the nocow flag
works first and only try with that or something like that?
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] generic: test overwriting file with mmap on a full filesystem
2025-07-22 6:55 ` Christoph Hellwig
@ 2025-07-22 7:50 ` Johannes Thumshirn
2025-07-22 8:16 ` hch
2025-07-22 10:27 ` Filipe Manana
1 sibling, 1 reply; 14+ messages in thread
From: Johannes Thumshirn @ 2025-07-22 7:50 UTC (permalink / raw)
To: hch@infradead.org, fdmanana@kernel.org
Cc: fstests@vger.kernel.org, linux-btrfs@vger.kernel.org,
Filipe Manana, linux-xfs@vger.kernel.org, Naohiro Aota
On 22.07.25 08:56, Christoph Hellwig wrote:
> I just noticed this test failing on zoned xfs in current for-next.
>
> That's because for out of place overwrite file systems writing at
> ENOSPC will obviously fail, and I think the test acknowledges that
> by forcing nocow for btrfs.
>
> But that leaves "real" out of place write file systems affected, which
> should also include zone btrfs, but the test actually fails there
> in mkfs already due to some reason.
It probably fails the _try_scratch_mkfs_sized() call because that goes
into _check_minimal_fs_size() and that should _notrun if $fssize <
$MIN_FSSIZE.
> Can you please rework the patch to see that setting the nocow flag
> works first and only try with that or something like that?
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] generic: test overwriting file with mmap on a full filesystem
2025-07-22 7:50 ` Johannes Thumshirn
@ 2025-07-22 8:16 ` hch
0 siblings, 0 replies; 14+ messages in thread
From: hch @ 2025-07-22 8:16 UTC (permalink / raw)
To: Johannes Thumshirn
Cc: hch@infradead.org, fdmanana@kernel.org, fstests@vger.kernel.org,
linux-btrfs@vger.kernel.org, Filipe Manana,
linux-xfs@vger.kernel.org, Naohiro Aota
On Tue, Jul 22, 2025 at 07:50:48AM +0000, Johannes Thumshirn wrote:
> On 22.07.25 08:56, Christoph Hellwig wrote:
> > I just noticed this test failing on zoned xfs in current for-next.
> >
> > That's because for out of place overwrite file systems writing at
> > ENOSPC will obviously fail, and I think the test acknowledges that
> > by forcing nocow for btrfs.
> >
> > But that leaves "real" out of place write file systems affected, which
> > should also include zone btrfs, but the test actually fails there
> > in mkfs already due to some reason.
>
> It probably fails the _try_scratch_mkfs_sized() call because that goes
> into _check_minimal_fs_size() and that should _notrun if $fssize <
> $MIN_FSSIZE.
Btw, it would be really helpful to improve the test coverage if btrfs did
the same adjustment for the nimimum size as zone xfs, where mkfs run up
the requested size to the zone size and then adds the required extra
zones that don't show up in the user capacity. That way all the small
size based tests just work.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] generic: test overwriting file with mmap on a full filesystem
2025-07-22 6:55 ` Christoph Hellwig
2025-07-22 7:50 ` Johannes Thumshirn
@ 2025-07-22 10:27 ` Filipe Manana
2025-07-23 5:48 ` Christoph Hellwig
1 sibling, 1 reply; 14+ messages in thread
From: Filipe Manana @ 2025-07-22 10:27 UTC (permalink / raw)
To: Christoph Hellwig
Cc: fstests, linux-btrfs, Filipe Manana, linux-xfs,
johannes.thumshirn, naohiro.aota
On Tue, Jul 22, 2025 at 7:56 AM Christoph Hellwig <hch@infradead.org> wrote:
>
> I just noticed this test failing on zoned xfs in current for-next.
>
> That's because for out of place overwrite file systems writing at
> ENOSPC will obviously fail, and I think the test acknowledges that
> by forcing nocow for btrfs.
>
> But that leaves "real" out of place write file systems affected, which
> should also include zone btrfs, but the test actually fails there
> in mkfs already due to some reason.
If the mkfs fails, it's probably _small_fs_size_mb that needs to be
updated with a sane size for zoned btrfs.
Johannes at Aota could give some advice there.
>
> Can you please rework the patch to see that setting the nocow flag
> works first and only try with that or something like that?
Reworking it is late as it's already in for-next, but we can add a
patch to skip it on zoned xfs:
1) The quickest way would be to add to the test:
_require_non_zoned_device $SCRATCH_DEV
2) Or add a "_require_nocow_data_writes" helper to check we can write
in place and skip the test if not, as you suggest, as it's more
generic in case there are other filesystems or configurations where
data writes are always COWed.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] generic: test overwriting file with mmap on a full filesystem
2025-07-22 10:27 ` Filipe Manana
@ 2025-07-23 5:48 ` Christoph Hellwig
0 siblings, 0 replies; 14+ messages in thread
From: Christoph Hellwig @ 2025-07-23 5:48 UTC (permalink / raw)
To: Filipe Manana
Cc: Christoph Hellwig, fstests, linux-btrfs, Filipe Manana, linux-xfs,
johannes.thumshirn, naohiro.aota
On Tue, Jul 22, 2025 at 11:27:35AM +0100, Filipe Manana wrote:
> > Can you please rework the patch to see that setting the nocow flag
> > works first and only try with that or something like that?
>
> Reworking it is late as it's already in for-next, but we can add a
> patch to skip it on zoned xfs:
It though I explained it before, but let me try again.
This is not about zoned xfs, zoned xfs is just the canary in the coal
mine.
The test fundamentally assumes file systems can overwrite without
space allocations. And then noticed that this isn't true with a weird
btrfs hack.
It needs to be reworked to only run when that is known to be true.
>
> 1) The quickest way would be to add to the test:
> _require_non_zoned_device $SCRATCH_DEV
That test is not relevant here. While zoned device require out of place
updates, they are also common for many other cases.
> 2) Or add a "_require_nocow_data_writes" helper to check we can write
> in place and skip the test if not, as you suggest, as it's more
> generic in case there are other filesystems or configurations where
> data writes are always COWed.
That's the only thing that works. Only run on file systems that are
known to do in-place updates, or in the odd btrfs case can be forced to
even if they don't normally do it.
To be honest the hardcoded btrfs hack should have been a big red flag,
those almost always means the test is fishy.
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2025-07-23 5:48 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-09 8:53 [PATCH] generic: test overwriting file with mmap on a full filesystem fdmanana
2025-07-10 7:29 ` Zorro Lang
2025-07-10 7:45 ` Qu Wenruo
2025-07-10 11:47 ` Filipe Manana
2025-07-10 16:07 ` Zorro Lang
2025-07-10 17:02 ` Filipe Manana
2025-07-10 17:03 ` [PATCH v2] " fdmanana
2025-07-10 18:24 ` Zorro Lang
2025-07-10 22:00 ` Qu Wenruo
2025-07-22 6:55 ` Christoph Hellwig
2025-07-22 7:50 ` Johannes Thumshirn
2025-07-22 8:16 ` hch
2025-07-22 10:27 ` Filipe Manana
2025-07-23 5:48 ` Christoph Hellwig
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).