d1e873ac00be417f6ad762764d90cdf8a27ab6d5
[xfstests-dev.git] / tests / btrfs / 127
1 #! /bin/bash
2 # FS QA Test No. btrfs/127
3 #
4 # Test that an incremental send operation works after doing radical changes
5 # in the directory hierarchy that involve switching the inode that directory
6 # entries point to.
7 #
8 #-----------------------------------------------------------------------
9 # Copyright (C) 2016 SUSE Linux Products GmbH. All Rights Reserved.
10 # Author: Filipe Manana <fdmanana@suse.com>
11 #
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.
15 #
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.
20 #
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 #-----------------------------------------------------------------------
25 #
26
27 seq=`basename $0`
28 seqres=$RESULT_DIR/$seq
29 echo "QA output created by $seq"
30
31 tmp=/tmp/$$
32 status=1        # failure is the default!
33 trap "_cleanup; exit \$status" 0 1 2 3 15
34
35 _cleanup()
36 {
37         cd /
38         rm -fr $send_files_dir
39         rm -f $tmp.*
40 }
41
42 # get standard environment, filters and checks
43 . ./common/rc
44 . ./common/filter
45
46 # real QA test starts here
47 _supported_fs btrfs
48 _supported_os Linux
49 _require_test
50 _require_scratch
51 _require_fssum
52
53 send_files_dir=$TEST_DIR/btrfs-test-$seq
54
55 rm -f $seqres.full
56 rm -fr $send_files_dir
57 mkdir $send_files_dir
58
59 _scratch_mkfs >>$seqres.full 2>&1
60 _scratch_mount
61
62 # case 1
63 mkdir -p $SCRATCH_MNT/case_1/d/p1
64 mkdir $SCRATCH_MNT/case_1/p1
65
66 # case 2
67 mkdir -p $SCRATCH_MNT/case_2/a
68 mkdir $SCRATCH_MNT/case_2/d
69 mkdir $SCRATCH_MNT/case_2/e
70 mkdir $SCRATCH_MNT/case_2/f
71 mkdir $SCRATCH_MNT/case_2/ance
72 mkdir $SCRATCH_MNT/case_2/d/ance
73 mkdir $SCRATCH_MNT/case_2/a/c
74 mv $SCRATCH_MNT/case_2/e $SCRATCH_MNT/case_2/d/ance
75 mv $SCRATCH_MNT/case_2/f $SCRATCH_MNT/case_2/d/ance
76 mv $SCRATCH_MNT/case_2/ance $SCRATCH_MNT/case_2/d/ance
77
78 # case 3
79 mkdir -p $SCRATCH_MNT/case_3/d
80 mkdir $SCRATCH_MNT/case_3/a
81 mkdir $SCRATCH_MNT/case_3/waiting_dir
82 mkdir -p $SCRATCH_MNT/case_3/pre/ance
83 mkdir $SCRATCH_MNT/case_3/d/ance
84 mkdir $SCRATCH_MNT/case_3/a/c
85 mv $SCRATCH_MNT/case_3/waiting_dir $SCRATCH_MNT/case_3/d/ance
86
87 # case 4
88 mkdir -p $SCRATCH_MNT/case_4/tmp
89 mkdir $SCRATCH_MNT/case_4/below_ance
90 mkdir -p $SCRATCH_MNT/case_4/pre/wait_dir
91 mkdir $SCRATCH_MNT/case_4/desc
92 mkdir $SCRATCH_MNT/case_4/ance
93 mv $SCRATCH_MNT/case_4/below_ance $SCRATCH_MNT/case_4/ance
94 mkdir $SCRATCH_MNT/case_4/other_dir
95
96 # Filesystem looks like:
97 #
98 # .                                                                  (ino 256)
99 # |--- case_1/                                                       (ino 257)
100 # |       |---- d/                                                   (ino 258)
101 # |       |     |--- p1/                                             (ino 259)
102 # |       |
103 # |       |---- p1/                                                  (ino 260)
104 # |
105 # |--- case_2/                                                       (ino 261)
106 # |       |---- a/                                                   (ino 262)
107 # |       |     |---- c/                                             (ino 268)
108 # |       |
109 # |       |---- d/                                                   (ino 263)
110 # |             |---- ance/                                          (ino 267)
111 # |                     |---- e/                                     (ino 264)
112 # |                     |---- f/                                     (ino 265)
113 # |                     |---- ance/                                  (ino 266)
114 # |
115 # |--- case_3/                                                       (ino 269)
116 # |       |---- a/                                                   (ino 271)
117 # |       |     |---- c/                                             (ino 276)
118 # |       |
119 # |       |---- d/                                                   (ino 270)
120 # |       |     |---- ance/                                          (ino 275)
121 # |       |             |---- waiting_dir/                           (ino 272)
122 # |       |
123 # |       |---- pre/                                                 (ino 273)
124 # |              |---- ance/                                         (ino 274)
125 # |
126 # |--- case_4/                                                       (ino 277)
127 #         |---- tmp/                                                 (ino 278)
128 #         |---- pre/                                                 (ino 280)
129 #         |      |---- wait_dir/                                     (ino 281)
130 #         |
131 #         |---- desc/                                                (ino 282)
132 #         |---- ance/                                                (ino 283)
133 #         |       |---- below_ance/                                  (ino 279)
134 #         |
135 #         |---- other_dir/                                           (ino 284)
136 #
137 _run_btrfs_util_prog subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/mysnap1
138
139 # case 1
140 #
141 # The directory named "d" (inode 257) has in both snapshots an entry with the
142 # name "p1" but it refers to different inodes in both snapshots (inode 258 in
143 # the parent snapshot and inode 259 in the send snapshot). When attempting to
144 # move inode 258, the operation is delayed because its new parent, inode 259,
145 # was not yet moved/renamed (as the stream is currently processing inode 258).
146 # Later on when processing inode 259, btrfs' send also ended up delaying the
147 # move/rename operation for this inode, so that it would happen after inode 258
148 # was processed, creating a circular dependency that resulted in the send stream
149 # terminating without issuing a rename operations for the inodes 258 and 259.
150 #
151 mv $SCRATCH_MNT/case_1/d/p1 $SCRATCH_MNT/case_1/p1
152 mv $SCRATCH_MNT/case_1/p1 $SCRATCH_MNT/case_1/d
153
154 # case 2
155 #
156 # When the inode 265 is processed, the path for inode 267 is computed, which at
157 # that time corresponds to "case_2/d/ance", and it was stored in the name cache
158 # (to avoid recomputing it again later when needed).
159 # Later on when processing inode 266, btrfs' send end up orphanizing (renaming
160 # to a name matching the pattern o<ino>-<gen>-<seq>) inode 267 because it has
161 # the same name as inode 266 and at that time it's a child of the new parent
162 # directory (inode 263) for inode 266. After the orphanization and while still
163 # processing inode 266, a rename operation for inode 266 was generated. However
164 # the source path for that rename operation was incorrect because it ended up
165 # using the old, pre-orphanization, name of inode 267.
166 #
167 mv $SCRATCH_MNT/case_2/a/c $SCRATCH_MNT/case_2
168 mv $SCRATCH_MNT/case_2/d/ance $SCRATCH_MNT/case_2/c
169 mv $SCRATCH_MNT/case_2/c/ance/ance $SCRATCH_MNT/case_2/d
170 mv $SCRATCH_MNT/case_2/c/ance/f $SCRATCH_MNT/case_2
171 mv $SCRATCH_MNT/case_2/c/ance/e $SCRATCH_MNT/case_2/f
172
173 # case 3
174 #
175 # This is similar to cases 1 and 2, but adding more complexity just to exercise
176 # btrfs' incremental send correctness.
177 #
178 mv $SCRATCH_MNT/case_3/d/ance $SCRATCH_MNT/case_3/a
179 mv $SCRATCH_MNT/case_3/a/c $SCRATCH_MNT/case_3
180 mv $SCRATCH_MNT/case_3/a/ance/waiting_dir $SCRATCH_MNT/case_3/c
181 mv $SCRATCH_MNT/case_3/pre/ance $SCRATCH_MNT/case_3/d
182 mv $SCRATCH_MNT/case_3/pre $SCRATCH_MNT/case_3/c/waiting_dir
183
184 # case 4
185 #
186 # When attempting to rename inode 283, the incremental send stream included an
187 # invalid destination path for the rename command. This was due to a missing
188 # path loop detection in the send code that made the rename of inode 283 happen
189 # without waiting for the rename of inode 284 to happen first (since it's an
190 # ancestor in the send snapshot that is beyond the current progress and it was
191 # also renamed/moved).
192 #
193 mv $SCRATCH_MNT/case_4/other_dir $SCRATCH_MNT/case_4/tmp
194 mv $SCRATCH_MNT/case_4/ance/below_ance $SCRATCH_MNT/case_4/tmp/other_dir
195 mv $SCRATCH_MNT/case_4/pre/wait_dir $SCRATCH_MNT/case_4/tmp/other_dir
196 mv $SCRATCH_MNT/case_4/pre $SCRATCH_MNT/case_4/tmp/other_dir/below_ance
197 mv $SCRATCH_MNT/case_4/desc $SCRATCH_MNT/case_4/tmp/other_dir/wait_dir
198 mv $SCRATCH_MNT/case_4/ance $SCRATCH_MNT/case_4/tmp/other_dir/wait_dir/desc
199
200 # Filesystem now looks like:
201 #
202 # .                                                                  (ino 256)
203 # |--- case_1/                                                       (ino 257)
204 # |        |--- d/                                                   (ino 258)
205 # |             |--- p1/                                             (ino 260)
206 # |                   |--- p1/                                       (ino 259)
207 # |
208 # |--- case_2/                                                       (ino 261)
209 # |       |---- a/                                                   (ino 262)
210 # |       |---- c/                                                   (ino 268)
211 # |       |     |---- ance/                                          (ino 267)
212 # |       |
213 # |       |---- d/                                                   (ino 263)
214 # |       |     |---- ance/                                          (ino 266)
215 # |       |
216 # |       |---- f/                                                   (ino 265)
217 # |             |---- e/                                             (ino 264)
218 # |
219 # |--- case_3/                                                       (ino 269)
220 # |       |---- a/                                                   (ino 271)
221 # |       |     |---- ance/                                          (ino 275)
222 # |       |
223 # |       |---- c/                                                   (ino 276)
224 # |       |     |---- waiting_dir/                                   (ino 272)
225 # |       |                   |---- pre/                             (ino 273)
226 # |       |
227 # |       |---- d/                                                   (ino 270)
228 # |             |---- ance/                                          (ino 274)
229 # |
230 # |--- case_4/                                                       (ino 277)
231 #         |---- tmp/                                                 (ino 278)
232 #                |---- other_dir/                                    (ino 284)
233 #                            |---- below_ance/                       (ino 279)
234 #                            |            |---- pre/                 (ino 280)
235 #                            |
236 #                            |---- wait_dir/                         (ino 281)
237 #                                       |---- desc/                  (ino 282)
238 #                                               |---- ance/          (ino 283)
239 #
240 _run_btrfs_util_prog subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/mysnap2
241
242 run_check $FSSUM_PROG -A -f -w $send_files_dir/1.fssum $SCRATCH_MNT/mysnap1
243 run_check $FSSUM_PROG -A -f -w $send_files_dir/2.fssum \
244         -x $SCRATCH_MNT/mysnap2/mysnap1 $SCRATCH_MNT/mysnap2
245
246 _run_btrfs_util_prog send -f $send_files_dir/1.snap $SCRATCH_MNT/mysnap1
247 _run_btrfs_util_prog send -p $SCRATCH_MNT/mysnap1 -f $send_files_dir/2.snap \
248         $SCRATCH_MNT/mysnap2
249
250 # Now recreate the filesystem by receiving both send streams and verify we get
251 # the same content that the original filesystem had.
252 _scratch_unmount
253 _scratch_mkfs >>$seqres.full 2>&1
254 _scratch_mount
255
256 _run_btrfs_util_prog receive -f $send_files_dir/1.snap $SCRATCH_MNT
257 run_check $FSSUM_PROG -r $send_files_dir/1.fssum $SCRATCH_MNT/mysnap1
258 _run_btrfs_util_prog receive -f $send_files_dir/2.snap $SCRATCH_MNT
259 run_check $FSSUM_PROG -r $send_files_dir/2.fssum $SCRATCH_MNT/mysnap2
260
261 echo "Silence is golden"
262 status=0
263 exit