b8ee3e160b88b3332a03236a148c27662cb71a80
[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 _need_to_be_root
61
62 send_files_dir=$TEST_DIR/btrfs-test-$seq
63
64 rm -f $seqres.full
65 rm -fr $send_files_dir
66 mkdir $send_files_dir
67
68 _scratch_mkfs >>$seqres.full 2>&1
69 _scratch_mount
70
71 mkdir $SCRATCH_MNT/data
72 mkdir $SCRATCH_MNT/data/n1
73 mkdir $SCRATCH_MNT/data/n1/n2
74 mkdir $SCRATCH_MNT/data/n4
75 mkdir $SCRATCH_MNT/data/n1/n2/p1
76 mkdir $SCRATCH_MNT/data/n1/n2/p1/p2
77 mkdir $SCRATCH_MNT/data/t6
78 mkdir $SCRATCH_MNT/data/t7
79 mkdir -p $SCRATCH_MNT/data/t5/t7
80 mkdir $SCRATCH_MNT/data/t2
81 mkdir $SCRATCH_MNT/data/t4
82 mkdir -p $SCRATCH_MNT/data/t1/t3
83 mkdir $SCRATCH_MNT/data/p1
84 mv $SCRATCH_MNT/data/t1 $SCRATCH_MNT/data/p1
85 mkdir -p $SCRATCH_MNT/data/p1/p2
86 mv $SCRATCH_MNT/data/t4 $SCRATCH_MNT/data/p1/p2/t1
87 mv $SCRATCH_MNT/data/t5 $SCRATCH_MNT/data/n4/t5
88 mv $SCRATCH_MNT/data/n1/n2/p1/p2 $SCRATCH_MNT/data/n4/t5/p2
89 mv $SCRATCH_MNT/data/t7 $SCRATCH_MNT/data/n4/t5/p2/t7
90 mv $SCRATCH_MNT/data/t2 $SCRATCH_MNT/data/n4/t1
91 mv $SCRATCH_MNT/data/p1 $SCRATCH_MNT/data/n4/t5/p2/p1
92 mv $SCRATCH_MNT/data/n1/n2 $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2
93 mv $SCRATCH_MNT/data/n4/t5/p2/p1/p2/t1 $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/t1
94 mv $SCRATCH_MNT/data/n4/t5/t7 $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/t1/t7
95 mv $SCRATCH_MNT/data/n4/t5/p2/p1/t1/t3 $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/t1/t3
96 mv $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/p1 \
97         $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/t1/t7/p1
98 mv $SCRATCH_MNT/data/t6 $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/t1/t3/t5
99 mv $SCRATCH_MNT/data/n4/t5/p2/p1/t1 $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/t1/t3/t1
100 mv $SCRATCH_MNT/data/n1 $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/t1/t7/p1/n1
101
102 # Filesystem looks like:
103 #
104 # .                                                             (ino 256)
105 # |--- data/                                                    (ino 257)
106 #        |--- n4/                                               (ino 260)
107 #             |--- t1/                                          (ino 267)
108 #             |--- t5/                                          (ino 265)
109 #                  |--- p2/                                     (ino 262)
110 #                       |--- p1/                                (ino 271)
111 #                       |    |--- p2/                           (ino 272)
112 #                       |         |--- n2/                      (ino 259)
113 #                       |              |--- t1/                 (ino 268)
114 #                       |                   |--- t3/            (ino 270)
115 #                       |                   |    |--- t1/       (ino 269)
116 #                       |                   |    |--- t5/       (ino 263)
117 #                       |                   |
118 #                       |                   |--- t7/            (ino 266)
119 #                       |                        |--- p1/       (ino 261)
120 #                       |                             |--- n1   (ino 258)
121 #                       |
122 #                       |--- t7/                                (ino 264)
123 #
124 _run_btrfs_util_prog subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/mysnap1
125
126 # The following sequence of directory renames resulted in an infinite path build
127 # loop when attempting to build the path for inode 266. This is because the
128 # inode's new parent, inode 261, was part of a circular dependency of delayed
129 # rename operations. This circular dependency should jave never been built (it
130 # happened due to a bug), and was the following:
131 #
132 #   ino 272 <- ino 261 <- ino 259 <- ino 268 <- ino 267 <- ino 261
133 #
134 # Where the notation "X <- Y" means that rename of inode X is delayed to happen
135 # after the rename of inode Y.
136
137 mv $SCRATCH_MNT/data/n4/t1 $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/t1/t7/p1/t1
138 mv $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2/t1 $SCRATCH_MNT/data/n4/
139 mv $SCRATCH_MNT/data/n4/t5/p2/p1/p2/n2 $SCRATCH_MNT/data/n4/t1/n2
140 mv $SCRATCH_MNT/data/n4/t1/t7/p1 $SCRATCH_MNT/data/n4/t1/n2/p1
141 mv $SCRATCH_MNT/data/n4/t1/t3/t1 $SCRATCH_MNT/data/n4/t1/n2/t1
142 mv $SCRATCH_MNT/data/n4/t1/t3 $SCRATCH_MNT/data/n4/t1/n2/t1/t3
143 mv $SCRATCH_MNT/data/n4/t5/p2/p1/p2 $SCRATCH_MNT/data/n4/t1/n2/p1/p2
144 mv $SCRATCH_MNT/data/n4/t1/t7 $SCRATCH_MNT/data/n4/t1/n2/p1/t7
145 mv $SCRATCH_MNT/data/n4/t5/p2/p1 $SCRATCH_MNT/data/n4/t1/n2/p1/p2/p1
146 mv $SCRATCH_MNT/data/n4/t1/n2/t1/t3/t5 $SCRATCH_MNT/data/n4/t1/n2/p1/p2/t5
147 mv $SCRATCH_MNT/data/n4/t5 $SCRATCH_MNT/data/n4/t1/n2/p1/p2/p1/t5
148 mv $SCRATCH_MNT/data/n4/t1/n2/p1/p2/p1/t5/p2 \
149         $SCRATCH_MNT/data/n4/t1/n2/p1/p2/p1/p2
150 mv $SCRATCH_MNT/data/n4/t1/n2/p1/p2/p1/p2/t7 $SCRATCH_MNT/data/n4/t1/t7
151
152 # Filesystem now looks like:
153 #
154 # .                                                   (ino 256)
155 # |--- data                                           (ino 257)
156 #        |--- n4/                                     (ino 260)
157 #             |--- t1/                                (ino 268)
158 #                  |--- n2/                           (ino 259)
159 #                  |    |--- p1/                      (ino 261)
160 #                  |    |    |--- n1/                 (ino 258)
161 #                  |    |    |--- p2/                 (ino 272)
162 #                  |    |    |    |--- p1/            (ino 271)
163 #                  |    |    |    |    |--- p2/       (ino 262)
164 #                  |    |    |    |    |--- t5/       (ino 265)
165 #                  |    |    |    |
166 #                  |    |    |    |--- t5/            (ino 263)
167 #                  |    |    |
168 #                  |    |    |--- t1/                 (ino 267)
169 #                  |    |    |--- t7/                 (ino 266)
170 #                  |    |
171 #                  |    |--- t1/                      (ino 269)
172 #                  |         |--- t3/                 (ino 270)
173 #                  |
174 #                  |--- t7/                           (ino 264)
175 #
176 _run_btrfs_util_prog subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/mysnap2
177
178 run_check $FSSUM_PROG -A -f -w $send_files_dir/1.fssum $SCRATCH_MNT/mysnap1
179 run_check $FSSUM_PROG -A -f -w $send_files_dir/2.fssum \
180         -x $SCRATCH_MNT/mysnap2/mysnap1 $SCRATCH_MNT/mysnap2
181
182 _run_btrfs_util_prog send $SCRATCH_MNT/mysnap1 -f $send_files_dir/1.snap
183 _run_btrfs_util_prog send -p $SCRATCH_MNT/mysnap1 $SCRATCH_MNT/mysnap2 \
184         -f $send_files_dir/2.snap
185
186 # Now recreate the filesystem by receiving both send streams and verify we get
187 # the same content that the original filesystem had.
188 _scratch_unmount
189 _scratch_mkfs >>$seqres.full 2>&1
190 _scratch_mount
191
192 _run_btrfs_util_prog receive $SCRATCH_MNT -f $send_files_dir/1.snap
193 run_check $FSSUM_PROG -r $send_files_dir/1.fssum $SCRATCH_MNT/mysnap1
194 _run_btrfs_util_prog receive $SCRATCH_MNT -f $send_files_dir/2.snap
195 run_check $FSSUM_PROG -r $send_files_dir/2.fssum $SCRATCH_MNT/mysnap2
196
197 echo "Silence is golden"
198 status=0
199 exit