2 # SPDX-License-Identifier: GPL-2.0+
3 # Copyright (c) 2019, Oracle and/or its affiliates. All Rights Reserved.
7 # Ensure that we can reflink from a file with a higher inode number to a lower
8 # inode number and vice versa. Mix it up by doing this test with inodes that
9 # already share blocks and inodes that don't share blocks. This tests both
10 # double-inode locking order correctness as well as stressing things like ocfs2
11 # which have per-inode sharing groups and therefore have to check that we don't
12 # try to link data between disjoint sharing groups.
14 seqres=$RESULT_DIR/$seq
15 echo "QA output created by $seq"
19 status=1 # failure is the default!
20 trap "_cleanup; exit \$status" 0 1 2 3 15
28 # get standard environment, filters and checks
33 # real QA test starts here
35 _require_scratch_reflink
40 echo "Format and mount"
41 _scratch_mkfs > $seqres.full 2>&1
42 _scratch_mount >> $seqres.full 2>&1
46 filesize=$((blksz * nr))
47 testdir=$SCRATCH_MNT/test-$seq
48 dummy_file=$testdir/dummy
50 high_file=$testdir/high
59 # Create two test files, make $low_file the file with the lower inode
60 # number, and make $high_file the file with the higher inode number.
62 _pwrite_byte 0x60 0 $filesize $testdir/file1 >> $seqres.full
63 _pwrite_byte 0x61 0 $filesize $testdir/file2 >> $seqres.full
64 if [ "$(inum $testdir/file1)" -lt "$(inum $testdir/file2)" ]; then
65 mv $testdir/file1 $low_file
66 mv $testdir/file2 $high_file
68 mv $testdir/file2 $low_file
69 mv $testdir/file1 $high_file
73 # Check md5sum of both files, but keep results sorted by inode order
75 md5sum $low_file | _filter_scratch
76 md5sum $high_file | _filter_scratch
79 # Test reflinking data from the first file to the second file
83 local off=$((filesize / 2))
84 local sz=$((filesize / 2))
87 _reflink_range $src $off $dest $off $sz >> $seqres.full
92 # Make a file shared with a dummy file
95 test -z "$which" && which=1
96 local dummy=$dummy_file.$which
102 # Make two files share (different ranges) with a dummy file
103 mutual_dummy_share() {
105 _cp_reflink $1 $dummy_file
106 _reflink_range $2 0 $dummy_file $blksz $blksz >> $seqres.full
109 # Announce ourselves, remembering which scenario we've tried
111 echo "$scenario: $@" | tee -a $seqres.full
112 scenario=$((scenario + 1))
115 # Scenario 1: low to high, neither file shares
116 ann "low to high, neither share"
118 test_files $low_file $high_file
120 # Scenario 2: high to low, neither file shares
121 ann "high to low, neither share"
123 test_files $high_file $low_file
125 # Scenario 3: low to high, only source file shares
126 ann "low to high, only source shares"
128 dummy_share $low_file
129 test_files $low_file $high_file
131 # Scenario 4: high to low, only source file shares
132 ann "high to low, only source shares"
134 dummy_share $high_file
135 test_files $high_file $low_file
137 # Scenario 5: low to high, only dest file shares
138 ann "low to high, only dest shares"
140 dummy_share $high_file
141 test_files $low_file $high_file
143 # Scenario 6: high to low, only dest file shares
144 ann "high to low, only dest shares"
146 dummy_share $low_file
147 test_files $high_file $low_file
149 # Scenario 7: low to high, both files share with each other
150 ann "low to high, both files share with each other"
152 _reflink_range $low_file 0 $high_file 0 $blksz >> $seqres.full
153 test_files $low_file $high_file
155 # Scenario 8: high to low, both files share with each other
156 ann "high to low, both files share with each other"
158 _reflink_range $low_file 0 $high_file 0 $blksz >> $seqres.full
159 test_files $high_file $low_file
161 # Scenario 9: low to high, both files share but not with each other
162 ann "low to high, both files share but not with each other"
164 # ocfs2 can only reflink between files sharing a refcount tree, so for
165 # this test (and #10) we skip the dummy file because we'd rather not split
166 # the test code just to mask off the /one/ weird fs like this...
167 if _supports_arbitrary_fileset_reflink; then
168 dummy_share $low_file 1
169 dummy_share $high_file 2
171 test_files $low_file $high_file
173 # Scenario 10: high to low, both files share but not with each other
174 ann "high to low, both files share but not with each other"
176 if _supports_arbitrary_fileset_reflink; then
177 dummy_share $low_file 1
178 dummy_share $high_file 2
180 test_files $high_file $low_file
182 # Scenario 11: low to high, both files share mutually
183 ann "low to high, both files share mutually"
185 mutual_dummy_share $low_file $high_file
186 test_files $low_file $high_file
188 # Scenario 12: high to low, both files share mutually
189 ann "high to low, both files share mutually"
191 mutual_dummy_share $low_file $high_file
192 test_files $high_file $low_file