2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (C) 2016 SUSE Linux Products GmbH. All Rights Reserved.
7 # Test log tree replay when qgroups are enabled and orphan roots (deleted
11 _begin_fstest auto quick snapshot metadata qgroup log
13 # Override the default cleanup function.
21 # Import common functions.
25 # real QA test starts here
28 _require_dm_target flakey
30 _scratch_mkfs >>$seqres.full 2>&1
31 _require_metadata_journaling $SCRATCH_DEV
35 _run_btrfs_util_prog quota enable $SCRATCH_MNT
37 # Create 2 directories with one file in one of them.
38 # We use these just to trigger a transaction commit later, moving the file from
39 # directory a to directory b and doing an fsync against directory a.
42 touch $SCRATCH_MNT/a/f
45 # Create our test file with 2 4K extents.
46 $XFS_IO_PROG -f -s -c "pwrite -S 0xaa 0 8K" $SCRATCH_MNT/foobar | _filter_xfs_io
48 # Create a snapshot and delete it. This doesn't really delete the snapshot
49 # immediately, just makes it inaccessible and invisible to user space, the
50 # snapshot is deleted later by a dedicated kernel thread (cleaner kthread)
51 # which is woke up at the next transaction commit.
52 # A root orphan item is inserted into the tree of tree roots, so that if a
53 # power failure happens before the dedicated kernel thread does the snapshot
54 # deletion, the next time the filesystem is mounted it resumes the snapshot
56 _run_btrfs_util_prog subvolume snapshot $SCRATCH_MNT $SCRATCH_MNT/snap
57 _run_btrfs_util_prog subvolume delete $SCRATCH_MNT/snap
59 # Now overwrite half of the extents we wrote before. Because we made a snapshpot
60 # before, which isn't really deleted yet (since no transaction commit happened
61 # after we did the snapshot delete request), the non overwritten extents get
62 # referenced twice, once by the default subvolume and once by the snapshot.
63 $XFS_IO_PROG -c "pwrite -S 0xbb 4K 8K" $SCRATCH_MNT/foobar | _filter_xfs_io
65 # Now move file f from directory a to directory b and fsync directory a.
66 # The fsync on the directory a triggers a transaction commit (because a file
67 # was moved from it to another directory) and the file fsync leaves a log tree
68 # with file extent items to replay.
69 mv $SCRATCH_MNT/a/f $SCRATCH_MNT/a/b
70 $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/a
71 $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foobar
73 echo "File digest before power failure:"
74 md5sum $SCRATCH_MNT/foobar | _filter_scratch
76 # Now simulate a power failure and mount the filesystem to replay the log tree.
77 # After the log tree was replayed, we used to hit a BUG_ON() when processing
78 # the root orphan item for the deleted snapshot. This is because when processing
79 # an orphan root the code expected to be the first code inserting the root into
80 # the fs_info->fs_root_radix radix tree, while in reallity it was the second
81 # caller attempting to do it - the first caller was the transaction commit that
82 # took place after replaying the log tree, when updating the qgroup counters.
83 _flakey_drop_and_remount
85 echo "File digest before after failure:"
86 # Must match what he got before the power failure.
87 md5sum $SCRATCH_MNT/foobar | _filter_scratch