2 # FS QA Test No. btrfs/127
4 # Test that an incremental send operation works after doing radical changes
5 # in the directory hierarchy that involve switching the inode that directory
8 #-----------------------------------------------------------------------
9 # Copyright (C) 2016 SUSE Linux Products GmbH. All Rights Reserved.
10 # Author: Filipe Manana <fdmanana@suse.com>
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.
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.
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 #-----------------------------------------------------------------------
28 seqres=$RESULT_DIR/$seq
29 echo "QA output created by $seq"
32 status=1 # failure is the default!
33 trap "_cleanup; exit \$status" 0 1 2 3 15
38 rm -fr $send_files_dir
42 # get standard environment, filters and checks
46 # real QA test starts here
53 send_files_dir=$TEST_DIR/btrfs-test-$seq
56 rm -fr $send_files_dir
59 _scratch_mkfs >>$seqres.full 2>&1
63 mkdir -p $SCRATCH_MNT/case_1/d/p1
64 mkdir $SCRATCH_MNT/case_1/p1
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
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
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
96 # Filesystem looks like:
99 # |--- case_1/ (ino 257)
100 # | |---- d/ (ino 258)
101 # | | |--- p1/ (ino 259)
103 # | |---- p1/ (ino 260)
105 # |--- case_2/ (ino 261)
106 # | |---- a/ (ino 262)
107 # | | |---- c/ (ino 268)
109 # | |---- d/ (ino 263)
110 # | |---- ance/ (ino 267)
111 # | |---- e/ (ino 264)
112 # | |---- f/ (ino 265)
113 # | |---- ance/ (ino 266)
115 # |--- case_3/ (ino 269)
116 # | |---- a/ (ino 271)
117 # | | |---- c/ (ino 276)
119 # | |---- d/ (ino 270)
120 # | | |---- ance/ (ino 275)
121 # | | |---- waiting_dir/ (ino 272)
123 # | |---- pre/ (ino 273)
124 # | |---- ance/ (ino 274)
126 # |--- case_4/ (ino 277)
127 # |---- tmp/ (ino 278)
128 # |---- pre/ (ino 280)
129 # | |---- wait_dir/ (ino 281)
131 # |---- desc/ (ino 282)
132 # |---- ance/ (ino 283)
133 # | |---- below_ance/ (ino 279)
135 # |---- other_dir/ (ino 284)
137 _run_btrfs_util_prog subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/mysnap1
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.
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
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.
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
175 # This is similar to cases 1 and 2, but adding more complexity just to exercise
176 # btrfs' incremental send correctness.
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
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).
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
200 # Filesystem now looks like:
203 # |--- case_1/ (ino 257)
204 # | |--- d/ (ino 258)
205 # | |--- p1/ (ino 260)
206 # | |--- p1/ (ino 259)
208 # |--- case_2/ (ino 261)
209 # | |---- a/ (ino 262)
210 # | |---- c/ (ino 268)
211 # | | |---- ance/ (ino 267)
213 # | |---- d/ (ino 263)
214 # | | |---- ance/ (ino 266)
216 # | |---- f/ (ino 265)
217 # | |---- e/ (ino 264)
219 # |--- case_3/ (ino 269)
220 # | |---- a/ (ino 271)
221 # | | |---- ance/ (ino 275)
223 # | |---- c/ (ino 276)
224 # | | |---- waiting_dir/ (ino 272)
225 # | | |---- pre/ (ino 273)
227 # | |---- d/ (ino 270)
228 # | |---- ance/ (ino 274)
230 # |--- case_4/ (ino 277)
231 # |---- tmp/ (ino 278)
232 # |---- other_dir/ (ino 284)
233 # |---- below_ance/ (ino 279)
234 # | |---- pre/ (ino 280)
236 # |---- wait_dir/ (ino 281)
237 # |---- desc/ (ino 282)
238 # |---- ance/ (ino 283)
240 _run_btrfs_util_prog subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/mysnap2
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
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 \
250 # Now recreate the filesystem by receiving both send streams and verify we get
251 # the same content that the original filesystem had.
253 _scratch_mkfs >>$seqres.full 2>&1
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
261 echo "Silence is golden"