2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2014 Filipe Manana. All Rights Reserved.
5 # FS QA Test No. btrfs/045
7 # Regression test for a btrfs incremental send issue where the kernel failed
8 # to build paths strings. This resulted either in sending a wrong path string
9 # to the send stream or entering an infinite loop when building it.
10 # This happened in the following scenarios:
12 # 1) A directory was made a child of another directory which has a lower inode
13 # number and has a pending move/rename operation or there's some non-direct
14 # ancestor directory with a higher inode number that was renamed/moved too.
15 # This made the incremental send code go into an infinite loop when building
18 # 2) A directory was made a child of another directory which has a higher inode
19 # number, but the new parent wasn't moved nor renamed. Instead some other
20 # ancestor higher in the hierarchy, with an higher inode number too, was
21 # moved/renamed too. This made the incremental send code go into an infinite
22 # loop when building a path string;
24 # 3) An orphan directory is created and at least one of its non-immediate
25 # descendent directories have a pending move/rename operation. This made
26 # an incremental send issue to the send stream an invalid path string that
27 # didn't account for the orphan ancestor directory.
29 # These issues are fixed by the following linux kernel btrfs patches:
31 # Btrfs: fix incremental send's decision to delay a dir move/rename
32 # Btrfs: part 2, fix incremental send's decision to delay a dir move/rename
33 # Btrfs: send, fix more issues related to directory renames
34 # Btrfs: send, account for orphan directories when building path strings
37 seqres=$RESULT_DIR/$seq
38 echo "QA output created by $seq"
41 status=1 # failure is the default!
42 trap "_cleanup; exit \$status" 0 1 2 3 15
49 # get standard environment, filters and checks
53 # real QA test starts here
60 _scratch_mkfs >/dev/null 2>&1
63 # case 1), mentioned above
64 mkdir -p $SCRATCH_MNT/a/b
65 mkdir $SCRATCH_MNT/a/c
66 mkdir $SCRATCH_MNT/a/b/d
67 touch $SCRATCH_MNT/a/file1
68 touch $SCRATCH_MNT/a/b/file2
69 mv $SCRATCH_MNT/a/file1 $SCRATCH_MNT/a/b/d/file3
70 ln $SCRATCH_MNT/a/b/d/file3 $SCRATCH_MNT/a/b/file4
71 mkdir $SCRATCH_MNT/a/b/f
72 mv $SCRATCH_MNT/a/b $SCRATCH_MNT/a/c/b2
73 touch $SCRATCH_MNT/a/c/b2/d/file5
75 # case 2), mentioned above
76 mkdir -p $SCRATCH_MNT/a/x1/x2
77 mkdir $SCRATCH_MNT/a/Z
78 mkdir -p $SCRATCH_MNT/a/x1/x2/x3/x4/x5
80 # case 2) again, but a more complex scenario
81 mkdir -p $SCRATCH_MNT/_a/_b/_c/_d
82 mkdir $SCRATCH_MNT/_a/_b/_c/_d/_e
83 mkdir $SCRATCH_MNT/_a/_b/_c/_d/_f
84 mv $SCRATCH_MNT/_a/_b/_c/_d/_e $SCRATCH_MNT/_a/_b/_c/_d/_f/_E2
85 mkdir $SCRATCH_MNT/_a/_b/_c/_g
86 mv $SCRATCH_MNT/_a/_b/_c/_d $SCRATCH_MNT/_a/_b/_D2
88 # case 3), mentioned above
89 mkdir -p $SCRATCH_MNT/za/zb/zc/zd
90 mkdir $SCRATCH_MNT/za/zb/ze
91 mv $SCRATCH_MNT/za/zb/zc $SCRATCH_MNT/za/zb/ze/zCC
92 mkdir $SCRATCH_MNT/za/zb/ze/zCC/zd/zf
93 mkdir $SCRATCH_MNT/za/zg
95 # case 1), more complex scenario
96 mkdir -p $SCRATCH_MNT/y_a/y_b
97 mkdir -p $SCRATCH_MNT/y_a/y_c/y_d
98 mkdir $SCRATCH_MNT/y_a/y_b/y_e
99 mkdir $SCRATCH_MNT/y_a/y_c/y_d/y_f
100 mv $SCRATCH_MNT/y_a/y_b $SCRATCH_MNT/y_a/y_c/y_d/y_2b
101 mkdir $SCRATCH_MNT/y_a/y_x
102 mkdir $SCRATCH_MNT/y_a/y_y
104 # case 1), variation of previous scenario with a subtree is moved into
105 # a directory created after creating the parent snapshot
106 mkdir -p $SCRATCH_MNT/w_a/w_b
107 mkdir -p $SCRATCH_MNT/w_a/w_c/w_d
108 mkdir $SCRATCH_MNT/w_a/w_b/w_e
109 mkdir $SCRATCH_MNT/w_a/w_c/w_d/w_f
110 mv $SCRATCH_MNT/w_a/w_b $SCRATCH_MNT/w_a/w_c/w_d/w_2b
112 mkdir -p $SCRATCH_MNT/xa/xb
113 mkdir $SCRATCH_MNT/xa/xc
114 mv $SCRATCH_MNT/xa/xb $SCRATCH_MNT/xa/xc/xb2
115 mkdir $SCRATCH_MNT/xa/xe
117 mkdir -p $SCRATCH_MNT/%a/%b
118 mkdir $SCRATCH_MNT/%a/%c
119 mkdir $SCRATCH_MNT/%a/%b/%d
120 mkdir $SCRATCH_MNT/%a/%c/%e
122 # Filesystem looks like:
127 # | | |-- b2/ (ino 258)
128 # | | |-- d/ (ino 260)
129 # | | | |-- file3 (ino 261)
130 # | | | |-- file5 (ino 264)
132 # | | |-- file2 (ino 262)
133 # | | |-- file4 (ino 261)
134 # | | |-- f/ (ino 263)
136 # | |-- x1/ (ino 265)
137 # | | |-- x2/ (ino 266)
138 # | | |-- x3/ (ino 268)
139 # | | |-- x4/ (ino 269)
140 # | | |-- x5/ (ino 270)
145 # | |-- _b/ (ino 272)
146 # | |-- _c/ (ino 273)
147 # | | |-- _g/ (ino 277)
149 # | |-- _D2/ (ino 274)
150 # | |-- _f/ (ino 276)
151 # | |-- _E2/ (ino 275)
154 # | |-- zb/ (ino 279)
155 # | | |-- ze/ (ino 282)
156 # | | |-- zCC/ (ino 280)
157 # | | |-- zd/ (ino 281)
158 # | | |-- zf/ (ino 283)
160 # | |-- zg/ (ino 284)
163 # | |-- y_c/ (ino 287)
164 # | | |-- y_d/ (ino 288)
165 # | | |-- y_2b/ (ino 286)
166 # | | | |-- y_e/ (ino 289)
168 # | | |-- y_f/ (ino 290)
170 # | |-- y_x/ (ino 291)
171 # | |-- y_y/ (ino 292)
174 # | |-- w_c/ (ino 295)
175 # | |-- w_d/ (ino 296)
176 # | |-- w_2b/ (ino 294)
177 # | | |-- w_e/ (ino 297)
179 # | |-- w_f/ (ino 298)
182 # | |-- xc/ (ino 301)
183 # | | |-- xb2/ (ino 300)
185 # | |-- xe/ (ino 302)
189 # | |-- %d/ (ino 306)
194 _run_btrfs_util_prog subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/mysnap1
196 # case 1), mentioned above
197 ln $SCRATCH_MNT/a/c/b2/file4 $SCRATCH_MNT/a/c/b2/f/file6
198 mv $SCRATCH_MNT/a/c/b2/d/file5 $SCRATCH_MNT/a/c/file7
199 touch $SCRATCH_MNT/a/c/b2/d/file8
200 touch $SCRATCH_MNT/a/c/b2/file9
201 ln $SCRATCH_MNT/a/c/b2/file9 $SCRATCH_MNT/a/c/b2/file10
202 mv $SCRATCH_MNT/a/c/b2/f $SCRATCH_MNT/a/f2
203 mv $SCRATCH_MNT/a/c $SCRATCH_MNT/a/c2
204 mv $SCRATCH_MNT/a/c2/b2 $SCRATCH_MNT/a/f2/b3
205 mv $SCRATCH_MNT/a/c2 $SCRATCH_MNT/a/f2/b3/c3
206 touch $SCRATCH_MNT/a/f2/b3/c3/file11
207 mv $SCRATCH_MNT/a $SCRATCH_MNT/a2
209 # case 2), mentioned above
210 mv $SCRATCH_MNT/a2/x1/x2/x3 $SCRATCH_MNT/a2/Z/X33
211 mv $SCRATCH_MNT/a2/x1/x2 $SCRATCH_MNT/a2/Z/X33/x4/x5/X22
213 # case 2) again, but a more complex scenario
214 mkdir $SCRATCH_MNT/_a/_o
215 mv $SCRATCH_MNT/_a/_b/_c/_g $SCRATCH_MNT/_a/_b/_D2/_f/_G2
216 mv $SCRATCH_MNT/_a/_b/_D2 $SCRATCH_MNT/_a/_b/_dd
217 mv $SCRATCH_MNT/_a/_b/_c $SCRATCH_MNT/_a/_C2
218 mv $SCRATCH_MNT/_a/_b/_dd/_f $SCRATCH_MNT/_a/_o/_FF
219 mv $SCRATCH_MNT/_a/_b $SCRATCH_MNT/_a/_o/_FF/_E2/_BB
221 # case 3), mentioned above
222 mkdir $SCRATCH_MNT/za/zg/zh
223 mv $SCRATCH_MNT/za/zb/ze $SCRATCH_MNT/za/zg/zh/zEE
224 mv $SCRATCH_MNT/za/zg/zh/zEE/zCC/zd $SCRATCH_MNT/za/zg/zh/zEE/zDD
225 mv $SCRATCH_MNT/za/zg/zh/zEE/zDD/zf $SCRATCH_MNT/za/zg/zh/zEE/zDD/zFF
227 # case 1), more complex scenario
228 mv $SCRATCH_MNT/y_a/y_x $SCRATCH_MNT/y_a/y_y
229 mv $SCRATCH_MNT/y_a/y_c/y_d/y_2b/y_e $SCRATCH_MNT/y_a/y_c/y_d/y_2b/y_2e
230 mv $SCRATCH_MNT/y_a/y_c/y_d $SCRATCH_MNT/y_a/y_y/y_x/y_2d
231 mv $SCRATCH_MNT/y_a/y_c $SCRATCH_MNT/y_a/y_y/y_x/y_2d/y_2b/y_2c
233 # case 1), variation of previous scenario with a subtree is moved into
234 # a directory created after creating the parent snapshot
235 mv $SCRATCH_MNT/w_a/w_c/w_d/w_2b/w_e $SCRATCH_MNT/w_a/w_c/w_d/w_2b/w_2e
236 mkdir $SCRATCH_MNT/w_a/w_h
237 mv $SCRATCH_MNT/w_a/w_c/w_d $SCRATCH_MNT/w_a/w_h/w_2d
238 mv $SCRATCH_MNT/w_a/w_c $SCRATCH_MNT/w_a/w_h/w_2d/w_2b/w_2c
240 mv $SCRATCH_MNT/xa/xc/xb2 $SCRATCH_MNT/xa/xe/xb3
241 mkdir $SCRATCH_MNT/xa/xe/xb3/xf
242 mkdir $SCRATCH_MNT/xa/xh
243 mv $SCRATCH_MNT/xa/xc $SCRATCH_MNT/xa/xe/xb3/xf/xc2
244 mv $SCRATCH_MNT/xa/xe $SCRATCH_MNT/xa/xh/xe2
246 echo "hello" > $SCRATCH_MNT/%a/foo
247 mkdir $SCRATCH_MNT/%a/%b/%d/%f
248 mkdir $SCRATCH_MNT/%a/%b/%g
249 mv $SCRATCH_MNT/%a/%c/%e $SCRATCH_MNT/%a/%b/%g/%e2
250 mv $SCRATCH_MNT/%a/%c $SCRATCH_MNT/%a/%b/%d/%f/%c2
251 mv $SCRATCH_MNT/%a/%b/%d/%f $SCRATCH_MNT/%a/%b/%g/%e2/%f2
252 mv $SCRATCH_MNT/%a/foo $SCRATCH_MNT/%a/%b/%g/%e2/%f2
254 # Filesystem now looks like:
258 # | |-- f2/ (ino 263)
259 # | | |-- file6 (ino 261)
260 # | | |-- b3/ (ino 258)
261 # | | |-- d/ (ino 260)
262 # | | | |-- file3 (ino 261)
263 # | | | |-- file8 (ino 308)
265 # | | |-- file2 (ino 262)
266 # | | |-- file4 (ino 261)
267 # | | |-- file9 (ino 309)
268 # | | |-- file10 (ino 309)
270 # | | |-- c3/ (ino 259)
271 # | | |-- file7 (ino 264)
272 # | | |-- file11 (ino 310)
274 # | |-- x1/ (ino 265)
276 # | |-- X33/ (ino 268)
277 # | |-- x4/ (ino 269)
278 # | |-- x5/ (ino 270)
279 # | |-- X22/ (ino 266)
282 # | |-- _o/ (ino 311)
283 # | | |-- _FF/ (ino 276)
284 # | | |-- _E2/ (ino 275)
285 # | | | |-- _BB/ (ino 272)
286 # | | | |-- dd/ (ino 274)
288 # | | |-- G2/ (ino 277)
289 # | |-- C2/ (ino 273)
292 # | |-- zb/ (ino 279)
293 # | |-- zg/ (ino 284)
294 # | |-- zh/ (ino 312)
295 # | |-- zEE/ (ino 282)
296 # | |-- zCC/ (ino 280)
297 # | |-- zDD/ (ino 281)
298 # | |-- zFF/ (ino 283)
301 # | |-- y_y/ (ino 292)
302 # | |-- y_x/ (ino 291)
303 # | |-- y_2d/ (ino 288)
304 # | |-- y_2b/ (ino 286)
305 # | | |-- y_2c/ (ino 287)
306 # | | |-- y_2e/ (ino 289)
307 # | |-- y_f/ (ino 290)
310 # | |-- w_h/ (ino 313)
311 # | |-- w_2d/ (ino 296)
312 # | |-- w_2b/ (ino 294)
313 # | | |-- w_2c/ (ino 295)
314 # | | |-- w_2e/ (ino 297)
315 # | |-- w_f/ (ino 298)
318 # | |-- xh/ (ino 315)
319 # | |-- xe2 (ino 302)
320 # | |-- xb3/ (ino 300)
321 # | |-- xf/ (ino 314)
322 # | |-- xc2/ (ino 301)
333 _run_btrfs_util_prog subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/mysnap2
335 run_check $FSSUM_PROG -A -f -w $tmp/1.fssum $SCRATCH_MNT/mysnap1
336 run_check $FSSUM_PROG -A -f -w $tmp/2.fssum -x $SCRATCH_MNT/mysnap2/mysnap1 \
339 _run_btrfs_util_prog send -f $tmp/1.snap $SCRATCH_MNT/mysnap1
341 _run_btrfs_util_prog send -p $SCRATCH_MNT/mysnap1 -f $tmp/2.snap \
347 _scratch_mkfs >/dev/null 2>&1
350 _run_btrfs_util_prog receive -f $tmp/1.snap $SCRATCH_MNT
351 run_check $FSSUM_PROG -r $tmp/1.fssum $SCRATCH_MNT/mysnap1
353 _run_btrfs_util_prog receive -f $tmp/2.snap $SCRATCH_MNT
354 run_check $FSSUM_PROG -r $tmp/2.fssum $SCRATCH_MNT/mysnap2