# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2022 SUSE Linux Products GmbH. All Rights Reserved.
#
-# FS QA Test 261
+# FS QA Test 677
#
# Test that after a full fsync of a file with preallocated extents beyond the
# file's size, if a power failure happens, the preallocated extents still exist
# real QA test starts here
-_supported_fs btrfs
+_supported_fs generic
_require_scratch
_require_dm_target flakey
_require_xfs_io_command "falloc" "-k"
_init_flakey
_mount_flakey
-# Create our test file with many file extent items, so that they span several
-# leaves of metadata, even if the node/page size is 64K. We use direct IO and
-# not fsync/O_SYNC because it's both faster and it avoids clearing the full sync
-# flag from the inode - we want the fsync below to trigger the slow full sync
-# code path.
+# Create our test file with many extents.
+# On btrfs this results in having multiple leaves of metadata full of file
+# extent items, a condition necessary to trigger the original bug.
+#
+# We use direct IO here because:
+#
+# 1) It's faster then doing fsync after each buffered write;
+#
+# 2) For btrfs, the first fsync would clear the inode's full sync runtime flag,
+# and we want the fsync below to trigger the full fsync code path of btrfs.
$XFS_IO_PROG -f -d -c "pwrite -b 4K 0 16M" $SCRATCH_MNT/foo | _filter_xfs_io
# Now add two preallocated extents to our file without extending the file's size.
$XFS_IO_PROG -c "falloc -k 16M 1M" $SCRATCH_MNT/foo
$XFS_IO_PROG -c "falloc -k 20M 1M" $SCRATCH_MNT/foo
-# Make sure everything is durably persisted and the transaction is committed.
-# This makes all created extents to have a generation lower than the generation
-# of the transaction used by the next write and fsync.
+# Make sure everything is durably persisted.
+# On btrfs this commits the current transaction and it makes all the created
+# extents to have a generation lower than the generation of the transaction used
+# by the next write and fsync.
sync
-# Now overwrite only the first extent, which will result in modifying only the
-# first leaf of metadata for our inode. Then fsync it. This fsync will use the
-# slow code path (inode full sync bit is set) because it's the first fsync since
-# the inode was created/loaded.
+# Now overwrite only the first extent.
+# On btrfs, due to COW (both data and metadata), that results in modifying only
+# the first leaf of metadata for our inode (we replace a file extent item and
+# update the inode item). Then fsync it. On btrfs this fsync will use the slow
+# code path because it's the first fsync since the inode was created/loaded.
$XFS_IO_PROG -c "pwrite 0 4K" -c "fsync" $SCRATCH_MNT/foo | _filter_xfs_io
# Simulate a power failure and then mount again the filesystem to replay the log