4 # Test log tree replay when qgroups are enabled and orphan roots (deleted
7 #-----------------------------------------------------------------------
9 # Copyright (C) 2016 SUSE Linux Products GmbH. All Rights Reserved.
10 # Author: Filipe Manana <fdmanana@suse.com>
12 # This program is free software; you can redistribute it and/or
13 # modify it under the terms of the GNU General Public License as
14 # published by the Free Software Foundation.
16 # This program is distributed in the hope that it would be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 # GNU General Public License for more details.
21 # You should have received a copy of the GNU General Public License
22 # along with this program; if not, write the Free Software Foundation,
23 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #-----------------------------------------------------------------------
28 seqres=$RESULT_DIR/$seq
29 echo "QA output created by $seq"
31 status=1 # failure is the default!
32 trap "_cleanup; exit \$status" 0 1 2 3 15
41 # get standard environment, filters and checks
46 # real QA test starts here
50 _require_dm_target flakey
54 _scratch_mkfs >>$seqres.full 2>&1
55 _require_metadata_journaling $SCRATCH_DEV
59 _run_btrfs_util_prog quota enable $SCRATCH_MNT
61 # Create 2 directories with one file in one of them.
62 # We use these just to trigger a transaction commit later, moving the file from
63 # directory a to directory b and doing an fsync against directory a.
66 touch $SCRATCH_MNT/a/f
69 # Create our test file with 2 4K extents.
70 $XFS_IO_PROG -f -s -c "pwrite -S 0xaa 0 8K" $SCRATCH_MNT/foobar | _filter_xfs_io
72 # Create a snapshot and delete it. This doesn't really delete the snapshot
73 # immediately, just makes it inaccessible and invisible to user space, the
74 # snapshot is deleted later by a dedicated kernel thread (cleaner kthread)
75 # which is woke up at the next transaction commit.
76 # A root orphan item is inserted into the tree of tree roots, so that if a
77 # power failure happens before the dedicated kernel thread does the snapshot
78 # deletion, the next time the filesystem is mounted it resumes the snapshot
80 _run_btrfs_util_prog subvolume snapshot $SCRATCH_MNT $SCRATCH_MNT/snap
81 _run_btrfs_util_prog subvolume delete $SCRATCH_MNT/snap
83 # Now overwrite half of the extents we wrote before. Because we made a snapshpot
84 # before, which isn't really deleted yet (since no transaction commit happened
85 # after we did the snapshot delete request), the non overwritten extents get
86 # referenced twice, once by the default subvolume and once by the snapshot.
87 $XFS_IO_PROG -c "pwrite -S 0xbb 4K 8K" $SCRATCH_MNT/foobar | _filter_xfs_io
89 # Now move file f from directory a to directory b and fsync directory a.
90 # The fsync on the directory a triggers a transaction commit (because a file
91 # was moved from it to another directory) and the file fsync leaves a log tree
92 # with file extent items to replay.
93 mv $SCRATCH_MNT/a/f $SCRATCH_MNT/a/b
94 $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/a
95 $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foobar
97 echo "File digest before power failure:"
98 md5sum $SCRATCH_MNT/foobar | _filter_scratch
100 # Now simulate a power failure and mount the filesystem to replay the log tree.
101 # After the log tree was replayed, we used to hit a BUG_ON() when processing
102 # the root orphan item for the deleted snapshot. This is because when processing
103 # an orphan root the code expected to be the first code inserting the root into
104 # the fs_info->fs_root_radix radix tree, while in reallity it was the second
105 # caller attempting to do it - the first caller was the transaction commit that
106 # took place after replaying the log tree, when updating the qgroup counters.
107 _flakey_drop_and_remount
109 echo "File digest before after failure:"
110 # Must match what he got before the power failure.
111 md5sum $SCRATCH_MNT/foobar | _filter_scratch