From: Filipe Manana <fdmanana@xxxxxxxx> 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@xxxxxxxx> --- common/rc | 59 +++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/211 | 1 + 2 files changed, 60 insertions(+) diff --git a/common/rc b/common/rc index 96578d15..52aade10 100644 --- a/common/rc +++ b/common/rc @@ -5873,6 +5873,65 @@ _require_program() { _have_program "$1" || _notrun "$tag required" } +# 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" + + # 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 "$test_file" + fi + + $XFS_IO_PROG -f -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 "inplace writes not supported" + fi +} + ################################################################################ # make sure this script returns success /bin/true diff --git a/tests/generic/211 b/tests/generic/211 index e87d1e01..ed426db2 100755 --- a/tests/generic/211 +++ b/tests/generic/211 @@ -27,6 +27,7 @@ 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 -- 2.47.2