btrfs: test incremental send after removing a directory and all its files
[xfstests-dev.git] / tests / btrfs / 227
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (C) 2020 SUSE Linux Products GmbH. All Rights Reserved.
4 #
5 # FS QA Test No. btrfs/227
6 #
7 # Test that an incremental send operation succeeds, and produces the correct
8 # results, after removing a directory and all its files, unmounting the
9 # filesystem, mounting the filesystem again and creating a new file (or
10 # directory).
11 #
12 seq=`basename $0`
13 seqres=$RESULT_DIR/$seq
14 echo "QA output created by $seq"
15
16 tmp=/tmp/$$
17 status=1        # failure is the default!
18 trap "_cleanup; exit \$status" 0 1 2 3 15
19
20 _cleanup()
21 {
22         cd /
23         rm -fr $send_files_dir
24         rm -f $tmp.*
25 }
26
27 # get standard environment, filters and checks
28 . ./common/rc
29 . ./common/filter
30
31 # real QA test starts here
32 _supported_fs btrfs
33 _require_test
34 _require_scratch
35 _require_fssum
36
37 send_files_dir=$TEST_DIR/btrfs-test-$seq
38
39 rm -f $seqres.full
40 rm -fr $send_files_dir
41 mkdir $send_files_dir
42
43 _scratch_mkfs >>$seqres.full 2>&1
44 _scratch_mount
45
46 mkdir $SCRATCH_MNT/dir
47 touch $SCRATCH_MNT/dir/file1
48 touch $SCRATCH_MNT/dir/file2
49 touch $SCRATCH_MNT/dir/file3
50
51 # Filesystem looks like:
52 #
53 # .                                     (ino 256)
54 # |----- dir/                           (ino 257)
55 #         |----- file1                  (ino 258)
56 #         |----- file2                  (ino 259)
57 #         |----- file3                  (ino 260)
58 #
59
60 # Now create the base snapshot, which is going to be the parent snapshot for
61 # a later incremental send.
62 $BTRFS_UTIL_PROG subvolume snapshot -r $SCRATCH_MNT \
63         $SCRATCH_MNT/mysnap1 > /dev/null
64
65 $BTRFS_UTIL_PROG send -f $send_files_dir/1.snap \
66         $SCRATCH_MNT/mysnap1 2>&1 1>/dev/null | _filter_scratch
67
68 # Now remove our directory and all its files.
69 rm -fr $SCRATCH_MNT/dir
70
71 # Unmount the filesystem and mount it again. This is to ensure that the next
72 # inode that is created ends up with the same inode number that our directory
73 # "dir" had, 257, which is the first free "objectid" available after mounting
74 # again the filesystem.
75 _scratch_cycle_mount
76
77 # Now create a new file (it could be a directory as well).
78 touch $SCRATCH_MNT/newfile
79
80 # Filesystem now looks like:
81 #
82 # .                                     (ino 256)
83 # |----- newfile                        (ino 257)
84 #
85
86 $BTRFS_UTIL_PROG subvolume snapshot -r $SCRATCH_MNT \
87                  $SCRATCH_MNT/mysnap2 > /dev/null
88 $BTRFS_UTIL_PROG send -p $SCRATCH_MNT/mysnap1 -f $send_files_dir/2.snap \
89                  $SCRATCH_MNT/mysnap2 2>&1 1>/dev/null | _filter_scratch
90
91 $FSSUM_PROG -A -f -w $send_files_dir/1.fssum $SCRATCH_MNT/mysnap1
92 $FSSUM_PROG -A -f -w $send_files_dir/2.fssum \
93         -x $SCRATCH_MNT/mysnap2/mysnap1 $SCRATCH_MNT/mysnap2
94
95 # Now recreate the filesystem by receiving both send streams and verify we get
96 # the same content that the original filesystem had.
97 _scratch_unmount
98 _scratch_mkfs >>$seqres.full 2>&1
99 _scratch_mount
100
101 $BTRFS_UTIL_PROG receive -f $send_files_dir/1.snap $SCRATCH_MNT > /dev/null
102
103 # The receive operation below used to fail with the following error:
104 #
105 #    ERROR: chown o257-9-0 failed: No such file or directory
106 #
107 # This is because when the kernel was processing old inode 257 (the directory),
108 # it had to delay its removal because its children inodes, "file1", "file2" and
109 # "file3", have higher inode numbers and will be processed (and unlinked) later.
110 # Then when it processed the new inode 257 (named "newfile"), it got confused
111 # and though that this inode was the one with a delayed removal and therefore
112 # generate an orphan name for it ("o257-9-0") instead of its current name of
113 # "newfile", causing the receiver to fail since there is no file with that
114 # orphan name.
115 #
116 $BTRFS_UTIL_PROG receive -f $send_files_dir/2.snap $SCRATCH_MNT > /dev/null
117
118 $FSSUM_PROG -r $send_files_dir/1.fssum $SCRATCH_MNT/mysnap1
119 $FSSUM_PROG -r $send_files_dir/2.fssum $SCRATCH_MNT/mysnap2
120
121 status=0
122 exit