]> git.apps.os.sepia.ceph.com Git - xfstests-dev.git/commitdiff
generic/211: verify if the filesystem being tested supports in place writes
authorFilipe Manana <fdmanana@suse.com>
Thu, 24 Jul 2025 12:05:59 +0000 (13:05 +0100)
committerZorro Lang <zlang@kernel.org>
Thu, 31 Jul 2025 08:55:23 +0000 (16:55 +0800)
The test currently assumes the filesystem can do in place writes (no
Copy-On-Write, no allocation of new extents) when overwriting a file.
While that is the case for most filesystems in most configurations, there
are exceptions such as zoned xfs where overwriting results in allocating
new extents for the new data.

So make the test check that in place writes are supported and skip the
test if they are not supported.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Zorro Lang <zlang@kernel.org>
common/rc
tests/generic/211

index 96578d152dafb9827c0650abcbe5bd1f5df15c15..b9292a784e429b8b6164b10db5b841045c4f5e53 100644 (file)
--- a/common/rc
+++ b/common/rc
@@ -5873,6 +5873,77 @@ _require_program() {
        _have_program "$1" || _notrun "$tag required"
 }
 
+_force_inplace_writes()
+{
+       local file=$1
+
+       if [ -z "$file" ]; then
+               _fail "Usage: _force_inplace_writes <file path>"
+       fi
+
+       case "$FSTYP" in
+       "btrfs")
+               # Set the file to NOCOW mode on btrfs, which must be done while
+               # the file is empty, otherwise it fails with -EINVAL.
+               _require_chattr C
+               $CHATTR_PROG +C "$file"
+               ;;
+       esac
+}
+
+# Test that a filesystem can do writes to a file in place (without allocating
+# new extents, without Copy-On-Write semantics).
+_require_inplace_writes()
+{
+       _require_xfs_io_command "fiemap"
+
+       local target=$1
+       local test_file="${target}/test_inplace_writes"
+       local fiemap_before
+       local fiemap_after
+
+       if [ -z "$target" ]; then
+               _fail "Usage: _require_inplace_writes <filesystem path>"
+       fi
+
+       rm -f "$test_file"
+       touch "$test_file"
+       _force_inplace_writes "$test_file"
+
+       $XFS_IO_PROG -c "pwrite 0 128K" -c "fsync" "$test_file" &> /dev/null
+       if [ $? -ne 0 ]; then
+               rm -f "$test_file"
+               _fail "_require_inplace_writes failed to write to test file"
+       fi
+
+       # Grab fiemap output before overwriting.
+       fiemap_before=$($XFS_IO_PROG -c "fiemap" "$test_file")
+       if [ $? -ne 0 ]; then
+               rm -f "$test_file"
+               _fail "_require_inplace_writes first fiemap call failed"
+       fi
+
+       $XFS_IO_PROG -c "pwrite 0 128K" -c "fsync" "$test_file" &> /dev/null
+       if [ $? -ne 0 ]; then
+               rm -f "$test_file"
+               _fail "_require_inplace_writes failed to overwrite test file"
+       fi
+
+       fiemap_after=$($XFS_IO_PROG -c "fiemap" "$test_file")
+       if [ $? -ne 0 ]; then
+               rm -f "$test_file"
+               _fail "_require_inplace_writes second fiemap call failed"
+       fi
+
+       rm -f "$test_file"
+
+       # If the filesystem supports inplace writes, then the extent mapping is
+       # the same before and after overwriting.
+       if [ "${fiemap_after}" != "${fiemap_before}" ]; then
+               _notrun "in-place writes not supported"
+       fi
+}
+
 ################################################################################
 # make sure this script returns success
 /bin/true
index e87d1e013e30346b0b586b84faa540d784efe8d7..6eda160856b2c60ee3b2443007eba68a45db0f31 100755 (executable)
@@ -27,15 +27,10 @@ fs_size=$(_small_fs_size_mb 512)
 _try_scratch_mkfs_sized $((fs_size * 1024 * 1024)) >>$seqres.full 2>&1 || \
        _fail "mkfs failed"
 _scratch_mount
+_require_inplace_writes $SCRATCH_MNT
 
 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
+_force_inplace_writes $SCRATCH_MNT/foobar
 
 # 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