2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (C) 2015 SUSE Linux Products GmbH. All Rights Reserved.
5 # FS QA Test No. btrfs/092
7 # Test btrfs incremental send after renaming and moving directories around in a
8 # way that ends up making a directory have different dentries with the same name
9 # but pointing to different inodes in the parent and send snapshots, and also
10 # inverting the ancestor-descendent relationship between one of those inodes and
13 # Cases like this made an incremental send enter an infinite lopp when building
14 # path strings, leading to -ENOMEM errors when the path string reached a length
16 # This issue was fixed by the following linux kernel btrfs patch:
18 # Btrfs: incremental send, check if orphanized dir inode needs delayed rename
21 seqres=$RESULT_DIR/$seq
22 echo "QA output created by $seq"
25 status=1 # failure is the default!
26 trap "_cleanup; exit \$status" 0 1 2 3 15
30 rm -fr $send_files_dir
34 # get standard environment, filters and checks
38 # real QA test starts here
44 send_files_dir=$TEST_DIR/btrfs-test-$seq
47 rm -fr $send_files_dir
50 _scratch_mkfs >>$seqres.full 2>&1
53 mkdir -p $SCRATCH_MNT/data/n1/n2
54 mkdir $SCRATCH_MNT/data/n4
55 mkdir -p $SCRATCH_MNT/data/t6/t7
56 mkdir $SCRATCH_MNT/data/t5
57 mkdir $SCRATCH_MNT/data/t7
58 mkdir $SCRATCH_MNT/data/n4/t2
59 mkdir $SCRATCH_MNT/data/t4
60 mkdir $SCRATCH_MNT/data/t3
61 mv $SCRATCH_MNT/data/t7 $SCRATCH_MNT/data/n4/t2
62 mv $SCRATCH_MNT/data/t4 $SCRATCH_MNT/data/n4/t2/t7
63 mv $SCRATCH_MNT/data/t5 $SCRATCH_MNT/data/n4/t2/t7/t4
64 mv $SCRATCH_MNT/data/t6 $SCRATCH_MNT/data/n4/t2/t7/t4/t5
65 mv $SCRATCH_MNT/data/n1/n2 $SCRATCH_MNT/data/n4/t2/t7/t4/t5/t6
66 mv $SCRATCH_MNT/data/n1 $SCRATCH_MNT/data/n4/t2/t7/t4/t5/t6
67 mv $SCRATCH_MNT/data/n4/t2/t7/t4/t5/t6/t7 $SCRATCH_MNT/data/n4/t2/t7/t4/t5/t6/n2
68 mv $SCRATCH_MNT/data/t3 $SCRATCH_MNT/data/n4/t2/t7/t4/t5/t6/n2/t7
70 # Filesystem looks like:
85 _run_btrfs_util_prog subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/mysnap1
87 # The sequence of directory rename operations below made the btrfs incremental
88 # send implementation enter an infinite loop when building path strings. The
89 # reason for this was the following:
91 # * While processing inode 262 it ended up orphanizing inode 264 (rename it to
92 # "/o264-6-0"). This is because the parent inode 265 has a dentry with name
93 # t7 in the parent snapshot that refers to inode 264, which is ahead of the
94 # current send progress (inode 262) and our inode 262 has the name t7 in
95 # the directory inode 265 in the send snapshot - so in order to rename inode
96 # 262 to its new name/location, it orphanizes (renames) 264 before 264 is
99 # * When it processes inode 264 it was not checking if it needed to delay its
100 # rename operation. This was incorrect because in the parent snapshot inode
101 # 267 is a descendent of inode 264 and inode 267 is an ancestor of inode 264
102 # in the send snapshot, which means the rename of inode 264 must happen after
103 # inode 267 is renamed in order to avoid the infinite loops when building
104 # path strings that involved inodes 264 and 267;
106 # * As a consequence as soon as the send progress moved to inode 265, the
107 # following loop when building a path string for inode 264 happened:
109 # start inode 264, send progress of 265 for example
110 # parent of 264 -> 267
111 # parent of 267 -> 262
112 # parent of 262 -> 259
113 # parent of 259 -> 261
114 # parent of 261 -> 263
115 # parent of 263 -> 266
116 # parent of 266 -> 264
117 # |--> back to first iteration while current path string length
118 # is <= PATH_MAX, and fail with -ENOMEM otherwise
120 mv $SCRATCH_MNT/data/n4/t2/t7/t4/t5/t6/n1 $SCRATCH_MNT/data/n4
121 mv $SCRATCH_MNT/data/n4/t2 $SCRATCH_MNT/data/n4/n1
122 mv $SCRATCH_MNT/data/n4/n1/t2/t7/t4/t5/t6/n2 $SCRATCH_MNT/data/n4/n1/t2
123 mv $SCRATCH_MNT/data/n4/n1/t2/n2/t7/t3 $SCRATCH_MNT/data/n4/n1/t2
124 mv $SCRATCH_MNT/data/n4/n1/t2/t7/t4/t5/t6 $SCRATCH_MNT/data/n4/n1/t2
125 mv $SCRATCH_MNT/data/n4/n1/t2/t7/t4 $SCRATCH_MNT/data/n4/n1/t2/t6
126 mv $SCRATCH_MNT/data/n4/n1/t2/t7 $SCRATCH_MNT/data/n4/n1/t2/t3
127 mv $SCRATCH_MNT/data/n4/n1/t2/n2/t7 $SCRATCH_MNT/data/n4/n1/t2
129 # Filesystem now looks like:
132 # |-- data/ (ino 257)
141 # | |-- t4/ (ino 266)
142 # | |-- t5/ (ino 263)
146 _run_btrfs_util_prog subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/mysnap2
148 run_check $FSSUM_PROG -A -f -w $send_files_dir/1.fssum $SCRATCH_MNT/mysnap1
149 run_check $FSSUM_PROG -A -f -w $send_files_dir/2.fssum \
150 -x $SCRATCH_MNT/mysnap2/mysnap1 $SCRATCH_MNT/mysnap2
152 _run_btrfs_util_prog send -f $send_files_dir/1.snap $SCRATCH_MNT/mysnap1
153 _run_btrfs_util_prog send -p $SCRATCH_MNT/mysnap1 -f $send_files_dir/2.snap \
156 # Now recreate the filesystem by receiving both send streams and verify we get
157 # the same content that the original filesystem had.
159 _scratch_mkfs >>$seqres.full 2>&1
162 _run_btrfs_util_prog receive -f $send_files_dir/1.snap $SCRATCH_MNT
163 run_check $FSSUM_PROG -r $send_files_dir/1.fssum $SCRATCH_MNT/mysnap1
164 _run_btrfs_util_prog receive -f $send_files_dir/2.snap $SCRATCH_MNT
165 run_check $FSSUM_PROG -r $send_files_dir/2.fssum $SCRATCH_MNT/mysnap2
167 echo "Silence is golden"