2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (C) 2015 SUSE Linux Products GmbH. All Rights Reserved.
7 # Test file A fsync after moving one other unrelated file B between directories
8 # and fsyncing B's old parent directory before fsyncing the file A. Check that
9 # after a crash all the file A data we fsynced is available.
11 # This test is motivated by an issue discovered in btrfs which caused the file
12 # data to be lost (despite fsync returning success to user space). That btrfs
13 # bug was fixed by the following linux kernel patch:
15 # Btrfs: fix data loss in the fast fsync path
18 seqres=$RESULT_DIR/$seq
19 echo "QA output created by $seq"
23 status=1 # failure is the default!
30 trap "_cleanup; exit \$status" 0 1 2 3 15
32 # get standard environment, filters and checks
37 # real QA test starts here
41 _require_dm_target flakey
45 _scratch_mkfs >> $seqres.full 2>&1
46 _require_metadata_journaling $SCRATCH_DEV
50 # Create our main test file 'foo', the one we check for data loss.
51 # By doing an fsync against our file, it makes btrfs clear the 'needs_full_sync'
52 # bit from its flags (btrfs inode specific flags).
53 $XFS_IO_PROG -f -c "pwrite -S 0xaa 0 8K" \
54 -c "fsync" $SCRATCH_MNT/foo | _filter_xfs_io
56 # Now create one other file and 2 directories. We will move this second file
57 # from one directory to the other later because it forces btrfs to commit its
58 # currently open transaction if we fsync the old parent directory. This is
59 # necessary to trigger the data loss bug that affected btrfs.
60 mkdir $SCRATCH_MNT/testdir_1
61 touch $SCRATCH_MNT/testdir_1/bar
62 mkdir $SCRATCH_MNT/testdir_2
64 # Make sure everything is durably persisted.
67 # Write more 8Kb of data to our file.
68 $XFS_IO_PROG -c "pwrite -S 0xbb 8K 8K" $SCRATCH_MNT/foo | _filter_xfs_io
70 # Move our 'bar' file into a new directory.
71 mv $SCRATCH_MNT/testdir_1/bar $SCRATCH_MNT/testdir_2/bar
73 # Fsync our first directory. Because it had a file moved into some other
74 # directory, this made btrfs commit the currently open transaction. This is
75 # a condition necessary to trigger the data loss bug.
76 $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/testdir_1
78 # Now fsync our main test file. If the fsync succeeds, we expect the 8Kb of
79 # data we wrote previously to be persisted and available if a crash happens.
80 # This did not happen with btrfs, because of the transaction commit that
81 # happened when we fsynced the parent directory.
82 $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foo
84 _flakey_drop_and_remount
86 # Now check that all data we wrote before are available.
87 echo "File content after log replay:"
88 od -t x1 $SCRATCH_MNT/foo