From: Filipe Manana <fdmanana@xxxxxxxx> Test that if we fsync a file that has no more hard links, power fail and then mount the filesystem, after the journal/log is replayed, the file doesn't exists anymore. This exercises a bug recently found and fixed by the following patch for the linux kernel: btrfs: fix fsync of files with no hard links not persisting deletion Signed-off-by: Filipe Manana <fdmanana@xxxxxxxx> --- tests/generic/764 | 78 +++++++++++++++++++++++++++++++++++++++++++ tests/generic/764.out | 2 ++ 2 files changed, 80 insertions(+) create mode 100755 tests/generic/764 create mode 100644 tests/generic/764.out diff --git a/tests/generic/764 b/tests/generic/764 new file mode 100755 index 00000000..57d21095 --- /dev/null +++ b/tests/generic/764 @@ -0,0 +1,78 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2025 SUSE Linux Products GmbH. All Rights Reserved. +# +# FS QA Test 764 +# +# Test that if we fsync a file that has no more hard links, power fail and then +# mount the filesystem, after the journal/log is replayed, the file doesn't +# exists anymore. +# +. ./common/preamble +_begin_fstest auto quick log + +_cleanup() +{ + if [ ! -z $XFS_IO_PID ]; then + kill $XFS_IO_PID > /dev/null 2>&1 + wait $XFS_IO_PID > /dev/null 2>&1 + fi + _cleanup_flakey + cd / + rm -r -f $tmp.* +} + +. ./common/dmflakey + +[ "$FSTYP" = "btrfs" ] && _fixed_by_kernel_commit xxxxxxxxxxxx \ + "btrfs: fix fsync of files with no hard links not persisting deletion" + +_require_scratch +_require_dm_target flakey +_require_mknod + +_scratch_mkfs >>$seqres.full 2>&1 || _fail "mkfs failed" +_require_metadata_journaling $SCRATCH_DEV +_init_flakey +_mount_flakey + +touch $SCRATCH_MNT/foo + +# Commit the current transaction and persist the file. +_scratch_sync + +# A fifo to communicate with a background xfs_io process that will fsync the +# file after we deleted its hard link while it's open by xfs_io. +mkfifo $SCRATCH_MNT/fifo + +tail -f $SCRATCH_MNT/fifo | $XFS_IO_PROG $SCRATCH_MNT/foo >>$seqres.full & +XFS_IO_PID=$! + +# Give some time for the xfs_io process to open a file descriptor for the file. +sleep 1 + +# Now while the file is open by the xfs_io process, delete its only hard link. +rm -f $SCRATCH_MNT/foo + +# Now that it has no more hard links, make the xfs_io process fsync it. +echo "fsync" > $SCRATCH_MNT/fifo + +# Terminate the xfs_io process so that we can unmount. +echo "quit" > $SCRATCH_MNT/fifo +wait $XFS_IO_PID +unset XFS_IO_PID + +# Simulate a power failure and then mount again the filesystem to replay the +# journal/log. +_flakey_drop_and_remount + +# We don't expect the file to exist anymore, since it was fsynced when it had no +# more hard links. +[ -f $SCRATCH_MNT/foo ] && echo "file foo still exists" + +_unmount_flakey + +# success, all done +echo "Silence is golden" +status=0 +exit diff --git a/tests/generic/764.out b/tests/generic/764.out new file mode 100644 index 00000000..bb58e5b8 --- /dev/null +++ b/tests/generic/764.out @@ -0,0 +1,2 @@ +QA output created by 764 +Silence is golden -- 2.45.2