15b050dbd1240695964259d2778c8d2918f78d55
[xfstests-dev.git] / tests / btrfs / 087
1 #! /bin/bash
2 # FS QA Test No. btrfs/087
3 #
4 # Test a very complex scenario for a btrfs incremental send operation where a
5 # large directory hierarchy had many subtrees moved between parent directories,
6 # preserving the names of some directories and inverting the parent-child
7 # relationship between some directories (a child in the parent snapshot became
8 # a parent, in the send snapshot, of the directory that is its parent in the
9 # parent snapshot).
10 #
11 # This test made the incremental send fail with -ENOMEM because it entered an
12 # infinite loop when building path strings that are used as operands of the
13 # rename operations issued in the send stream.
14 # This issue was fixed by the following linux kernel btrfs patch:
15 #
16 #   Btrfs: incremental send, don't delay directory renames unnecessarily
17 #
18 #-----------------------------------------------------------------------
19 # Copyright (C) 2015 SUSE Linux Products GmbH. All Rights Reserved.
20 # Author: Filipe Manana <fdmanana@suse.com>
21 #
22 # This program is free software; you can redistribute it and/or
23 # modify it under the terms of the GNU General Public License as
24 # published by the Free Software Foundation.
25 #
26 # This program is distributed in the hope that it would be useful,
27 # but WITHOUT ANY WARRANTY; without even the implied warranty of
28 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29 # GNU General Public License for more details.
30 #
31 # You should have received a copy of the GNU General Public License
32 # along with this program; if not, write the Free Software Foundation,
33 # Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
34 #-----------------------------------------------------------------------
35 #
36
37 seq=`basename $0`
38 seqres=$RESULT_DIR/$seq
39 echo "QA output created by $seq"
40
41 tmp=/tmp/$$
42 status=1        # failure is the default!
43 trap "_cleanup; exit \$status" 0 1 2 3 15
44
45 _cleanup()
46 {
47         rm -fr $send_files_dir
48         rm -f $tmp.*
49 }
50
51 # get standard environment, filters and checks
52 . ./common/rc
53 . ./common/filter
54
55 # real QA test starts here
56 _supported_fs btrfs
57 _supported_os Linux
58 _require_scratch
59 _require_fssum
60
61 send_files_dir=$TEST_DIR/btrfs-test-$seq
62
63 rm -f $seqres.full
64 rm -fr $send_files_dir
65 mkdir $send_files_dir
66
67 _scratch_mkfs >>$seqres.full 2>&1
68 _scratch_mount
69
70 mkdir $SCRATCH_MNT/data
71 mkdir $SCRATCH_MNT/data/n1
72 mkdir $SCRATCH_MNT/data/n1/n2
73 mkdir $SCRATCH_MNT/data/n4
74 mkdir $SCRATCH_MNT/data/n1/n2/p1
75 mkdir $SCRATCH_MNT/data/n1/n2/p1/p2
76 mkdir $SCRATCH_MNT/data/t6
77 mkdir $SCRATCH_MNT/data/t7
78 mkdir -p $SCRATCH_MNT/data/t5/t7
79 mkdir $SCRATCH_MNT/data/t2
80 mkdir $SCRATCH_MNT/data/t4
81 mkdir -p $SCRATCH_MNT/data/t1/t3
82 mkdir $SCRATCH_MNT/data/p1
83 mv $SCRATCH_MNT/data/t1 $SCRATCH_MNT/data/p1
84 mkdir -p $SCRATCH_MNT/data/p1/p2
85 mv $SCRATCH_MNT/data/t4 $SCRATCH_MNT/data/p1/p2/t1
86 mv $SCRATCH_MNT/data/t5 $SCRATCH_MNT/data/n4/t5
87 mv $SCRATCH_MNT/data/n1/n2/p1/p2 $SCRATCH_MNT/data/n4/t5/p2
88 mv $SCRATCH_MNT/data/t7 $SCRATCH_MNT/data/n4/t5/p2/t7
89 mv $SCRATCH_MNT/data/t2 $SCRATCH_MNT/data/n4/t1
90 mv $SCRATCH_MNT/data/p1 $SCRATCH_MNT/data/n4/t5/p2/p1
91 mv $SCRATCH_MNT/data/n1/n2 $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2
92 mv $SCRATCH_MNT/data/n4/t5/p2/p1/p2/t1 $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/t1
93 mv $SCRATCH_MNT/data/n4/t5/t7 $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/t1/t7
94 mv $SCRATCH_MNT/data/n4/t5/p2/p1/t1/t3 $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/t1/t3
95 mv $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/p1 \
96         $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/t1/t7/p1
97 mv $SCRATCH_MNT/data/t6 $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/t1/t3/t5
98 mv $SCRATCH_MNT/data/n4/t5/p2/p1/t1 $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/t1/t3/t1
99 mv $SCRATCH_MNT/data/n1 $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/t1/t7/p1/n1
100
101 # Filesystem looks like:
102 #
103 # .                                                             (ino 256)
104 # |--- data/                                                    (ino 257)
105 #        |--- n4/                                               (ino 260)
106 #             |--- t1/                                          (ino 267)
107 #             |--- t5/                                          (ino 265)
108 #                  |--- p2/                                     (ino 262)
109 #                       |--- p1/                                (ino 271)
110 #                       |    |--- p2/                           (ino 272)
111 #                       |         |--- n2/                      (ino 259)
112 #                       |              |--- t1/                 (ino 268)
113 #                       |                   |--- t3/            (ino 270)
114 #                       |                   |    |--- t1/       (ino 269)
115 #                       |                   |    |--- t5/       (ino 263)
116 #                       |                   |
117 #                       |                   |--- t7/            (ino 266)
118 #                       |                        |--- p1/       (ino 261)
119 #                       |                             |--- n1   (ino 258)
120 #                       |
121 #                       |--- t7/                                (ino 264)
122 #
123 _run_btrfs_util_prog subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/mysnap1
124
125 # The following sequence of directory renames resulted in an infinite path build
126 # loop when attempting to build the path for inode 266. This is because the
127 # inode's new parent, inode 261, was part of a circular dependency of delayed
128 # rename operations. This circular dependency should jave never been built (it
129 # happened due to a bug), and was the following:
130 #
131 #   ino 272 <- ino 261 <- ino 259 <- ino 268 <- ino 267 <- ino 261
132 #
133 # Where the notation "X <- Y" means that rename of inode X is delayed to happen
134 # after the rename of inode Y.
135
136 mv $SCRATCH_MNT/data/n4/t1 $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/t1/t7/p1/t1
137 mv $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/t1 $SCRATCH_MNT/data/n4/
138 mv $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2 $SCRATCH_MNT/data/n4/t1/n2
139 mv $SCRATCH_MNT/data/n4/t1/t7/p1 $SCRATCH_MNT/data/n4/t1/n2/p1
140 mv $SCRATCH_MNT/data/n4/t1/t3/t1 $SCRATCH_MNT/data/n4/t1/n2/t1
141 mv $SCRATCH_MNT/data/n4/t1/t3 $SCRATCH_MNT/data/n4/t1/n2/t1/t3
142 mv $SCRATCH_MNT/data/n4/t5/p2/p1/p2 $SCRATCH_MNT/data/n4/t1/n2/p1/p2
143 mv $SCRATCH_MNT/data/n4/t1/t7 $SCRATCH_MNT/data/n4/t1/n2/p1/t7
144 mv $SCRATCH_MNT/data/n4/t5/p2/p1 $SCRATCH_MNT/data/n4/t1/n2/p1/p2/p1
145 mv $SCRATCH_MNT/data/n4/t1/n2/t1/t3/t5 $SCRATCH_MNT/data/n4/t1/n2/p1/p2/t5
146 mv $SCRATCH_MNT/data/n4/t5 $SCRATCH_MNT/data/n4/t1/n2/p1/p2/p1/t5
147 mv $SCRATCH_MNT/data/n4/t1/n2/p1/p2/p1/t5/p2 \
148         $SCRATCH_MNT/data/n4/t1/n2/p1/p2/p1/p2
149 mv $SCRATCH_MNT/data/n4/t1/n2/p1/p2/p1/p2/t7 $SCRATCH_MNT/data/n4/t1/t7
150
151 # Filesystem now looks like:
152 #
153 # .                                                   (ino 256)
154 # |--- data                                           (ino 257)
155 #        |--- n4/                                     (ino 260)
156 #             |--- t1/                                (ino 268)
157 #                  |--- n2/                           (ino 259)
158 #                  |    |--- p1/                      (ino 261)
159 #                  |    |    |--- n1/                 (ino 258)
160 #                  |    |    |--- p2/                 (ino 272)
161 #                  |    |    |    |--- p1/            (ino 271)
162 #                  |    |    |    |    |--- p2/       (ino 262)
163 #                  |    |    |    |    |--- t5/       (ino 265)
164 #                  |    |    |    |
165 #                  |    |    |    |--- t5/            (ino 263)
166 #                  |    |    |
167 #                  |    |    |--- t1/                 (ino 267)
168 #                  |    |    |--- t7/                 (ino 266)
169 #                  |    |
170 #                  |    |--- t1/                      (ino 269)
171 #                  |         |--- t3/                 (ino 270)
172 #                  |
173 #                  |--- t7/                           (ino 264)
174 #
175 _run_btrfs_util_prog subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/mysnap2
176
177 run_check $FSSUM_PROG -A -f -w $send_files_dir/1.fssum $SCRATCH_MNT/mysnap1
178 run_check $FSSUM_PROG -A -f -w $send_files_dir/2.fssum \
179         -x $SCRATCH_MNT/mysnap2/mysnap1 $SCRATCH_MNT/mysnap2
180
181 _run_btrfs_util_prog send -f $send_files_dir/1.snap $SCRATCH_MNT/mysnap1
182 _run_btrfs_util_prog send -p $SCRATCH_MNT/mysnap1 -f $send_files_dir/2.snap \
183         $SCRATCH_MNT/mysnap2
184
185 # Now recreate the filesystem by receiving both send streams and verify we get
186 # the same content that the original filesystem had.
187 _scratch_unmount
188 _scratch_mkfs >>$seqres.full 2>&1
189 _scratch_mount
190
191 _run_btrfs_util_prog receive -f $send_files_dir/1.snap $SCRATCH_MNT
192 run_check $FSSUM_PROG -r $send_files_dir/1.fssum $SCRATCH_MNT/mysnap1
193 _run_btrfs_util_prog receive -f $send_files_dir/2.snap $SCRATCH_MNT
194 run_check $FSSUM_PROG -r $send_files_dir/2.fssum $SCRATCH_MNT/mysnap2
195
196 echo "Silence is golden"
197 status=0
198 exit