2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (C) 2019 SUSE Linux Products GmbH. All Rights Reserved.
7 # Check that if we write some data to a file, its inode gets evicted (while its
8 # parent directory's inode is not evicted due to being in use), then we rename
9 # the file and fsync it, after a power failure the file data is not lost.
12 seqres=$RESULT_DIR/$seq
13 echo "QA output created by $seq"
15 status=1 # failure is the default!
16 trap "_cleanup; exit \$status" 0 1 2 3 15
25 # get standard environment, filters and checks
30 # real QA test starts here
35 _require_dm_target flakey
39 _scratch_mkfs >>$seqres.full 2>&1
40 _require_metadata_journaling $SCRATCH_DEV
44 # Create our test directory with two files in it.
45 mkdir $SCRATCH_MNT/dir
46 touch $SCRATCH_MNT/dir/foo
47 touch $SCRATCH_MNT/dir/bar
49 # Do a direct IO write into file bar.
50 # To trigger the bug found in btrfs, doing a buffered write would also work as
51 # long as writeback completes before the file's inode is evicted (the inode can
52 # not be evicted while delalloc exists). But since that is hard to trigger from
53 # a user space test, without resulting in a transaction commit as well, just do
54 # a direct IO write since it is much simpler.
55 $XFS_IO_PROG -d -c "pwrite -S 0xd3 0 4K" $SCRATCH_MNT/dir/bar | _filter_xfs_io
57 # Keep the directory in use while we evict all inodes. This is to prevent
58 # eviction of the directory's inode (a necessary condition to trigger the bug
59 # found in btrfs, as evicting the directory inode would result in commiting the
60 # current transaction when the fsync of file foo happens below).
68 # Wait a bit to give time to the background process to chdir to the directory.
71 # Evict all inodes from memory, except the directory's inode because a background
72 # process is using it.
73 echo 2 > /proc/sys/vm/drop_caches
75 # Now fsync our file foo, which ends up persisting information about its parent
76 # directory inode because it is a new inode.
77 $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/dir/foo
79 # Rename our file bar to baz right before we fsync it.
80 mv $SCRATCH_MNT/dir/bar $SCRATCH_MNT/dir/baz
82 # Fsync our file baz, after a power failure we expect to see the data we
83 # previously wrote to it.
84 $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/dir/baz
86 # Kill the background process using our test directory.
90 # Simulate a power failure and then check no data loss happened.
91 _flakey_drop_and_remount
93 echo "File data after power failure:"
94 od -t x1 -A d $SCRATCH_MNT/dir/baz