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 _begin_fstest auto quick clone
16 # Import common functions.
20 # real QA test starts here
22 _require_scratch_reflink
25 echo "Format and mount"
26 _scratch_mkfs > $seqres.full 2>&1
27 _scratch_mount >> $seqres.full 2>&1
31 filesize=$((blksz * nr))
32 testdir=$SCRATCH_MNT/test-$seq
33 dummy_file=$testdir/dummy
35 high_file=$testdir/high
44 # Create two test files, make $low_file the file with the lower inode
45 # number, and make $high_file the file with the higher inode number.
50 if [ "$(inum $testdir/file1)" -lt "$(inum $testdir/file2)" ]; then
51 mv $testdir/file1 $low_file
52 mv $testdir/file2 $high_file
54 mv $testdir/file2 $low_file
55 mv $testdir/file1 $high_file
58 _pwrite_byte 0x60 0 $filesize $low_file >> $seqres.full
59 _pwrite_byte 0x61 0 $filesize $high_file >> $seqres.full
62 # Check md5sum of both files, but keep results sorted by inode order
64 md5sum $low_file | _filter_scratch
65 md5sum $high_file | _filter_scratch
68 # Test reflinking data from the first file to the second file
72 local off=$((filesize / 2))
73 local sz=$((filesize / 2))
76 _reflink_range $src $off $dest $off $sz >> $seqres.full
81 # Make a file shared with a dummy file
84 test -z "$which" && which=1
85 local dummy=$dummy_file.$which
91 # Make two files share (different ranges) with a dummy file
92 mutual_dummy_share() {
94 _cp_reflink $1 $dummy_file
95 _reflink_range $2 0 $dummy_file $blksz $blksz >> $seqres.full
98 # Announce ourselves, remembering which scenario we've tried
100 echo "$scenario: $@" | tee -a $seqres.full
101 scenario=$((scenario + 1))
104 # Scenario 1: low to high, neither file shares
105 ann "low to high, neither share"
107 test_files $low_file $high_file
109 # Scenario 2: high to low, neither file shares
110 ann "high to low, neither share"
112 test_files $high_file $low_file
114 # Scenario 3: low to high, only source file shares
115 ann "low to high, only source shares"
117 dummy_share $low_file
118 test_files $low_file $high_file
120 # Scenario 4: high to low, only source file shares
121 ann "high to low, only source shares"
123 dummy_share $high_file
124 test_files $high_file $low_file
126 # Scenario 5: low to high, only dest file shares
127 ann "low to high, only dest shares"
129 dummy_share $high_file
130 test_files $low_file $high_file
132 # Scenario 6: high to low, only dest file shares
133 ann "high to low, only dest shares"
135 dummy_share $low_file
136 test_files $high_file $low_file
138 # Scenario 7: low to high, both files share with each other
139 ann "low to high, both files share with each other"
141 _reflink_range $low_file 0 $high_file 0 $blksz >> $seqres.full
142 test_files $low_file $high_file
144 # Scenario 8: high to low, both files share with each other
145 ann "high to low, both files share with each other"
147 _reflink_range $low_file 0 $high_file 0 $blksz >> $seqres.full
148 test_files $high_file $low_file
150 # Scenario 9: low to high, both files share but not with each other
151 ann "low to high, both files share but not with each other"
153 # ocfs2 can only reflink between files sharing a refcount tree, so for
154 # this test (and #10) we skip the dummy file because we'd rather not split
155 # the test code just to mask off the /one/ weird fs like this...
156 if _supports_arbitrary_fileset_reflink; then
157 dummy_share $low_file 1
158 dummy_share $high_file 2
160 test_files $low_file $high_file
162 # Scenario 10: high to low, both files share but not with each other
163 ann "high to low, both files share but not with each other"
165 if _supports_arbitrary_fileset_reflink; then
166 dummy_share $low_file 1
167 dummy_share $high_file 2
169 test_files $high_file $low_file
171 # Scenario 11: low to high, both files share mutually
172 ann "low to high, both files share mutually"
174 mutual_dummy_share $low_file $high_file
175 test_files $low_file $high_file
177 # Scenario 12: high to low, both files share mutually
178 ann "high to low, both files share mutually"
180 mutual_dummy_share $low_file $high_file
181 test_files $high_file $low_file