b335ac3de9a637180e62a1138e101ad82744df84
[xfstests-dev.git] / tests / btrfs / 205
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (C) 2020 SUSE Linux Products GmbH. All Rights Reserved.
4 #
5 # FSQA Test No. 205
6 #
7 # Test several scenarios of cloning operations where the source range includes
8 # inline extents. They used to not be supported on btrfs because their
9 # implementation was not straightforward, and therefore these operations used
10 # to fail with errno EOPNOTSUPP on older kernels.
11 #
12 # Support for this was added by a patch with the following subject:
13 #
14 #   "Btrfs: implement full reflink support for inline extents"
15 #
16 seq=`basename $0`
17 seqres=$RESULT_DIR/$seq
18 echo "QA output created by $seq"
19 tmp=/tmp/$$
20 status=1        # failure is the default!
21 trap "_cleanup; exit \$status" 0 1 2 3 15
22
23 _cleanup()
24 {
25         cd /
26         rm -f $tmp.*
27 }
28
29 # get standard environment, filters and checks
30 . ./common/rc
31 . ./common/filter
32 . ./common/reflink
33
34 # real QA test starts here
35 _supported_fs btrfs
36 _require_scratch_reflink
37 _require_xfs_io_command "falloc" "-k"
38 _require_command "$CHATTR_PROG" chattr
39 _require_btrfs_fs_feature "no_holes"
40 _require_btrfs_mkfs_feature "no-holes"
41
42 run_tests()
43 {
44     rm -f $SCRATCH_MNT/foo* $SCRATCH_MNT/bar*
45
46     # File foo1 has an inline extent encoding 4K of data followed by a regular
47     # extent. It has a file size of 128K.
48     echo "Creating file foo1"
49     touch $SCRATCH_MNT/foo1
50     $CHATTR_PROG +c $SCRATCH_MNT/foo1 > /dev/null 2>&1
51     $XFS_IO_PROG -c "pwrite -S 0xab 0 4K" \
52                  -c "fsync" \
53                  -c "pwrite -S 0xab 4K 124K" \
54                  $SCRATCH_MNT/foo1 | _filter_xfs_io
55
56     # File bar1 has a single 128K extent, and a file size of 128K.
57     echo "Creating file bar1"
58     $XFS_IO_PROG -f -c "pwrite -S 0xcd 0 128K" $SCRATCH_MNT/bar1 | _filter_xfs_io
59
60     echo "Cloning foo1 into the end of bar1"
61     $XFS_IO_PROG -c "reflink $SCRATCH_MNT/foo1 0 128K 128K" $SCRATCH_MNT/bar1 \
62         | _filter_xfs_io
63
64     echo "File bar1 digest = $(_md5_checksum $SCRATCH_MNT/bar1)"
65
66     # File foo2 has an inline extent with 1000 bytes of data and it's followed
67     # by a regular extent of 60K. It has a file size of 64K.
68     echo "Creating file foo2"
69     $XFS_IO_PROG -f -c "pwrite -S 0xab 0 1000" \
70                  -c "fsync" \
71                  -c "falloc 0 4K" \
72                  -c "pwrite -S 0xab 4K 60K" \
73                  $SCRATCH_MNT/foo2 | _filter_xfs_io
74
75     # File bar2 has a regular extent of 64K and a file size of 64K too.
76     echo "Creating file bar2"
77     $XFS_IO_PROG -f -c "pwrite -S 0xcd 0 64K" $SCRATCH_MNT/bar2 | _filter_xfs_io
78
79     echo "Cloning foo2 into the end of bar2"
80     $XFS_IO_PROG -c "reflink $SCRATCH_MNT/foo2 0 64K 64K" $SCRATCH_MNT/bar2 \
81         | _filter_xfs_io
82
83     echo "File bar2 digest = $(_md5_checksum $SCRATCH_MNT/bar2)"
84
85     # File bar3 has a regular extent of 128K and a file size of 128K too.
86     echo "Creating file bar3"
87     $XFS_IO_PROG -f -c "pwrite -S 0xcd 0 128K" $SCRATCH_MNT/bar3 \
88         | _filter_xfs_io
89
90     echo "Cloning foo2 into the middle of bar3"
91     $XFS_IO_PROG -c "reflink $SCRATCH_MNT/foo2 0 64K 64K" $SCRATCH_MNT/bar3 \
92         | _filter_xfs_io
93
94     echo "File bar3 digest = $(_md5_checksum $SCRATCH_MNT/bar3)"
95
96     # File bar4 has a 64K hole at offset 0 followed by a 64K regular extent, and
97     # a file size of 128K.
98     echo "Creating file bar4"
99     $XFS_IO_PROG -f -c "pwrite -S 0xcd 64K 64K" $SCRATCH_MNT/bar4 | _filter_xfs_io
100
101     echo "Cloning foo1 into bar4"
102     $XFS_IO_PROG -c "reflink $SCRATCH_MNT/foo1 0 0 128K" $SCRATCH_MNT/bar4 \
103         | _filter_xfs_io
104
105     echo "File bar4 digest = $(_md5_checksum $SCRATCH_MNT/bar4)"
106
107     # File bar5 has a 1Mb prealloc extent at file offset 0 and a file size of 0.
108     echo "Creating file bar5"
109     $XFS_IO_PROG -f -c "falloc -k 0 1M" $SCRATCH_MNT/bar5
110
111     echo "Cloning foo1 into bar5"
112     $XFS_IO_PROG -c "reflink $SCRATCH_MNT/foo1 0 0 128K" $SCRATCH_MNT/bar5 \
113         | _filter_xfs_io
114
115     echo "File bar5 digest = $(_md5_checksum $SCRATCH_MNT/bar5)"
116
117     # File bar6 has an inline extent encoding 500 bytes of data followed by a
118     # prealloc extent of 1Mb at file offset 4K. The file size is 500 bytes.
119     echo "Creating file bar6"
120     $XFS_IO_PROG -f -c "pwrite -S 0xef 0 500" \
121                  -c "falloc -k 4K 1M" \
122                  $SCRATCH_MNT/bar6 | _filter_xfs_io
123
124     echo "Cloning foo1 into bar6"
125     $XFS_IO_PROG -c "reflink $SCRATCH_MNT/foo1 0 0 128K" $SCRATCH_MNT/bar6 \
126         | _filter_xfs_io
127
128     echo "File bar6 digest = $(_md5_checksum $SCRATCH_MNT/bar6)"
129
130     # File foo3 a single inline extent of 500 bytes.
131     echo "Creating file foo3"
132     $XFS_IO_PROG -f -c "pwrite -S 0xbf 0 500" $SCRATCH_MNT/foo3 | _filter_xfs_io
133
134     # File bar7 is an empty file, has no extents.
135     touch $SCRATCH_MNT/bar7
136
137     echo "Cloning foo3 into bar7"
138     $XFS_IO_PROG -c "reflink $SCRATCH_MNT/foo3" $SCRATCH_MNT/bar7 | _filter_xfs_io
139
140     echo "File bar7 digest = $(_md5_checksum $SCRATCH_MNT/bar7)"
141
142     # Unmount and mount again the filesystem. We want to verify the reflink
143     # operations were durably persisted.
144     _scratch_cycle_mount
145
146     echo "File digests after mounting again the filesystem:"
147     echo "File bar1 digest = $(_md5_checksum $SCRATCH_MNT/bar1)"
148     echo "File bar2 digest = $(_md5_checksum $SCRATCH_MNT/bar2)"
149     echo "File bar3 digest = $(_md5_checksum $SCRATCH_MNT/bar3)"
150     echo "File bar4 digest = $(_md5_checksum $SCRATCH_MNT/bar4)"
151     echo "File bar5 digest = $(_md5_checksum $SCRATCH_MNT/bar5)"
152     echo "File bar6 digest = $(_md5_checksum $SCRATCH_MNT/bar6)"
153     echo "File bar7 digest = $(_md5_checksum $SCRATCH_MNT/bar7)"
154 }
155
156 _scratch_mkfs "-O ^no-holes" >>$seqres.full 2>&1
157 _scratch_mount
158
159 echo
160 echo "Testing with defaults"
161 echo
162 run_tests
163
164 echo
165 echo "Testing with -o compress"
166 echo
167 _scratch_cycle_mount "compress"
168 run_tests
169
170 echo
171 echo "Testing with -o nodatacow"
172 echo
173 _scratch_cycle_mount "nodatacow"
174 run_tests
175
176 echo
177 echo "Testing with -O no-holes"
178 echo
179 _scratch_unmount
180 _scratch_mkfs "-O no-holes" >>$seqres.full 2>&1
181 _scratch_mount
182 run_tests
183
184 status=0
185 exit