2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2022 SUSE Linux Products GmbH. All Rights Reserved.
7 # Test that after a full fsync of a file with preallocated extents beyond the
8 # file's size, if a power failure happens, the preallocated extents still exist
9 # after we mount the filesystem.
12 _begin_fstest auto quick log prealloc
25 # real QA test starts here
29 _require_dm_target flakey
30 _require_xfs_io_command "falloc" "-k"
31 _require_xfs_io_command "fiemap"
36 _scratch_mkfs >>$seqres.full 2>&1
37 _require_metadata_journaling $SCRATCH_DEV
41 # Create our test file with many extents.
42 # On btrfs this results in having multiple leaves of metadata full of file
43 # extent items, a condition necessary to trigger the original bug.
45 # We use direct IO here because:
47 # 1) It's faster then doing fsync after each buffered write;
49 # 2) For btrfs, the first fsync would clear the inode's full sync runtime flag,
50 # and we want the fsync below to trigger the full fsync code path of btrfs.
51 $XFS_IO_PROG -f -d -c "pwrite -b 4K 0 16M" $SCRATCH_MNT/foo | _filter_xfs_io
53 # Now add two preallocated extents to our file without extending the file's size.
54 # One right at i_size, and another further beyond, leaving a gap between the two
56 $XFS_IO_PROG -c "falloc -k 16M 1M" $SCRATCH_MNT/foo
57 $XFS_IO_PROG -c "falloc -k 20M 1M" $SCRATCH_MNT/foo
59 # Make sure everything is durably persisted.
60 # On btrfs this commits the current transaction and it makes all the created
61 # extents to have a generation lower than the generation of the transaction used
62 # by the next write and fsync.
65 # Now overwrite only the first extent.
66 # On btrfs, due to COW (both data and metadata), that results in modifying only
67 # the first leaf of metadata for our inode (we replace a file extent item and
68 # update the inode item). Then fsync it. On btrfs this fsync will use the slow
69 # code path because it's the first fsync since the inode was created/loaded.
70 $XFS_IO_PROG -c "pwrite 0 4K" -c "fsync" $SCRATCH_MNT/foo | _filter_xfs_io
72 # Simulate a power failure and then mount again the filesystem to replay the log
74 _flakey_drop_and_remount
76 # After the power failure we expect that the preallocated extents, beyond the
77 # inode's i_size, still exist.
78 echo "List of extents after power failure:"
79 $XFS_IO_PROG -c "fiemap -v" $SCRATCH_MNT/foo | _filter_fiemap