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
36 _require_scratch_reflink
41 echo "Format and mount"
42 _scratch_mkfs > $seqres.full 2>&1
43 _scratch_mount >> $seqres.full 2>&1
47 filesize=$((blksz * nr))
48 testdir=$SCRATCH_MNT/test-$seq
49 dummy_file=$testdir/dummy
51 high_file=$testdir/high
60 # Create two test files, make $low_file the file with the lower inode
61 # number, and make $high_file the file with the higher inode number.
63 _pwrite_byte 0x60 0 $filesize $testdir/file1 >> $seqres.full
64 _pwrite_byte 0x61 0 $filesize $testdir/file2 >> $seqres.full
65 if [ "$(inum $testdir/file1)" -lt "$(inum $testdir/file2)" ]; then
66 mv $testdir/file1 $low_file
67 mv $testdir/file2 $high_file
69 mv $testdir/file2 $low_file
70 mv $testdir/file1 $high_file
74 # Check md5sum of both files, but keep results sorted by inode order
76 md5sum $low_file | _filter_scratch
77 md5sum $high_file | _filter_scratch
80 # Test reflinking data from the first file to the second file
84 local off=$((filesize / 2))
85 local sz=$((filesize / 2))
88 _reflink_range $src $off $dest $off $sz >> $seqres.full
93 # Make a file shared with a dummy file
96 test -z "$which" && which=1
97 local dummy=$dummy_file.$which
100 _cp_reflink $1 $dummy
103 # Make two files share (different ranges) with a dummy file
104 mutual_dummy_share() {
106 _cp_reflink $1 $dummy_file
107 _reflink_range $2 0 $dummy_file $blksz $blksz >> $seqres.full
110 # Announce ourselves, remembering which scenario we've tried
112 echo "$scenario: $@" | tee -a $seqres.full
113 scenario=$((scenario + 1))
116 # Scenario 1: low to high, neither file shares
117 ann "low to high, neither share"
119 test_files $low_file $high_file
121 # Scenario 2: high to low, neither file shares
122 ann "high to low, neither share"
124 test_files $high_file $low_file
126 # Scenario 3: low to high, only source file shares
127 ann "low to high, only source shares"
129 dummy_share $low_file
130 test_files $low_file $high_file
132 # Scenario 4: high to low, only source file shares
133 ann "high to low, only source shares"
135 dummy_share $high_file
136 test_files $high_file $low_file
138 # Scenario 5: low to high, only dest file shares
139 ann "low to high, only dest shares"
141 dummy_share $high_file
142 test_files $low_file $high_file
144 # Scenario 6: high to low, only dest file shares
145 ann "high to low, only dest shares"
147 dummy_share $low_file
148 test_files $high_file $low_file
150 # Scenario 7: low to high, both files share with each other
151 ann "low to high, both files share with each other"
153 _reflink_range $low_file 0 $high_file 0 $blksz >> $seqres.full
154 test_files $low_file $high_file
156 # Scenario 8: high to low, both files share with each other
157 ann "high to low, both files share with each other"
159 _reflink_range $low_file 0 $high_file 0 $blksz >> $seqres.full
160 test_files $high_file $low_file
162 # Scenario 9: low to high, both files share but not with each other
163 ann "low to high, both files share but not with each other"
165 # ocfs2 can only reflink between files sharing a refcount tree, so for
166 # this test (and #10) we skip the dummy file because we'd rather not split
167 # the test code just to mask off the /one/ weird fs like this...
168 if _supports_arbitrary_fileset_reflink; then
169 dummy_share $low_file 1
170 dummy_share $high_file 2
172 test_files $low_file $high_file
174 # Scenario 10: high to low, both files share but not with each other
175 ann "high to low, both files share but not with each other"
177 if _supports_arbitrary_fileset_reflink; then
178 dummy_share $low_file 1
179 dummy_share $high_file 2
181 test_files $high_file $low_file
183 # Scenario 11: low to high, both files share mutually
184 ann "low to high, both files share mutually"
186 mutual_dummy_share $low_file $high_file
187 test_files $low_file $high_file
189 # Scenario 12: high to low, both files share mutually
190 ann "high to low, both files share mutually"
192 mutual_dummy_share $low_file $high_file
193 test_files $high_file $low_file