xfs: Check for extent overflow when trivally adding a new extent
[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 # remove previous $seqres.full before test
35 rm -f $seqres.full
36
37 # real QA test starts here
38 _supported_fs btrfs
39 _require_scratch_reflink
40 _require_xfs_io_command "falloc" "-k"
41 _require_command "$CHATTR_PROG" chattr
42 _require_btrfs_fs_feature "no_holes"
43 _require_btrfs_mkfs_feature "no-holes"
44
45 run_tests()
46 {
47     rm -f $SCRATCH_MNT/foo* $SCRATCH_MNT/bar*
48
49     # File foo1 has an inline extent encoding 4K of data followed by a regular
50     # extent. It has a file size of 128K.
51     echo "Creating file foo1"
52     touch $SCRATCH_MNT/foo1
53     $CHATTR_PROG +c $SCRATCH_MNT/foo1 > /dev/null 2>&1
54     $XFS_IO_PROG -c "pwrite -S 0xab 0 4K" \
55                  -c "fsync" \
56                  -c "pwrite -S 0xab 4K 124K" \
57                  $SCRATCH_MNT/foo1 | _filter_xfs_io
58
59     # File bar1 has a single 128K extent, and a file size of 128K.
60     echo "Creating file bar1"
61     $XFS_IO_PROG -f -c "pwrite -S 0xcd 0 128K" $SCRATCH_MNT/bar1 | _filter_xfs_io
62
63     echo "Cloning foo1 into the end of bar1"
64     $XFS_IO_PROG -c "reflink $SCRATCH_MNT/foo1 0 128K 128K" $SCRATCH_MNT/bar1 \
65         | _filter_xfs_io
66
67     echo "File bar1 digest = $(_md5_checksum $SCRATCH_MNT/bar1)"
68
69     # File foo2 has an inline extent with 1000 bytes of data and it's followed
70     # by a regular extent of 60K. It has a file size of 64K.
71     echo "Creating file foo2"
72     $XFS_IO_PROG -f -c "pwrite -S 0xab 0 1000" \
73                  -c "fsync" \
74                  -c "falloc 0 4K" \
75                  -c "pwrite -S 0xab 4K 60K" \
76                  $SCRATCH_MNT/foo2 | _filter_xfs_io
77
78     # File bar2 has a regular extent of 64K and a file size of 64K too.
79     echo "Creating file bar2"
80     $XFS_IO_PROG -f -c "pwrite -S 0xcd 0 64K" $SCRATCH_MNT/bar2 | _filter_xfs_io
81
82     echo "Cloning foo2 into the end of bar2"
83     $XFS_IO_PROG -c "reflink $SCRATCH_MNT/foo2 0 64K 64K" $SCRATCH_MNT/bar2 \
84         | _filter_xfs_io
85
86     echo "File bar2 digest = $(_md5_checksum $SCRATCH_MNT/bar2)"
87
88     # File bar3 has a regular extent of 128K and a file size of 128K too.
89     echo "Creating file bar3"
90     $XFS_IO_PROG -f -c "pwrite -S 0xcd 0 128K" $SCRATCH_MNT/bar3 \
91         | _filter_xfs_io
92
93     echo "Cloning foo2 into the middle of bar3"
94     $XFS_IO_PROG -c "reflink $SCRATCH_MNT/foo2 0 64K 64K" $SCRATCH_MNT/bar3 \
95         | _filter_xfs_io
96
97     echo "File bar3 digest = $(_md5_checksum $SCRATCH_MNT/bar3)"
98
99     # File bar4 has a 64K hole at offset 0 followed by a 64K regular extent, and
100     # a file size of 128K.
101     echo "Creating file bar4"
102     $XFS_IO_PROG -f -c "pwrite -S 0xcd 64K 64K" $SCRATCH_MNT/bar4 | _filter_xfs_io
103
104     echo "Cloning foo1 into bar4"
105     $XFS_IO_PROG -c "reflink $SCRATCH_MNT/foo1 0 0 128K" $SCRATCH_MNT/bar4 \
106         | _filter_xfs_io
107
108     echo "File bar4 digest = $(_md5_checksum $SCRATCH_MNT/bar4)"
109
110     # File bar5 has a 1Mb prealloc extent at file offset 0 and a file size of 0.
111     echo "Creating file bar5"
112     $XFS_IO_PROG -f -c "falloc -k 0 1M" $SCRATCH_MNT/bar5
113
114     echo "Cloning foo1 into bar5"
115     $XFS_IO_PROG -c "reflink $SCRATCH_MNT/foo1 0 0 128K" $SCRATCH_MNT/bar5 \
116         | _filter_xfs_io
117
118     echo "File bar5 digest = $(_md5_checksum $SCRATCH_MNT/bar5)"
119
120     # File bar6 has an inline extent encoding 500 bytes of data followed by a
121     # prealloc extent of 1Mb at file offset 4K. The file size is 500 bytes.
122     echo "Creating file bar6"
123     $XFS_IO_PROG -f -c "pwrite -S 0xef 0 500" \
124                  -c "falloc -k 4K 1M" \
125                  $SCRATCH_MNT/bar6 | _filter_xfs_io
126
127     echo "Cloning foo1 into bar6"
128     $XFS_IO_PROG -c "reflink $SCRATCH_MNT/foo1 0 0 128K" $SCRATCH_MNT/bar6 \
129         | _filter_xfs_io
130
131     echo "File bar6 digest = $(_md5_checksum $SCRATCH_MNT/bar6)"
132
133     # File foo3 a single inline extent of 500 bytes.
134     echo "Creating file foo3"
135     $XFS_IO_PROG -f -c "pwrite -S 0xbf 0 500" $SCRATCH_MNT/foo3 | _filter_xfs_io
136
137     # File bar7 is an empty file, has no extents.
138     touch $SCRATCH_MNT/bar7
139
140     echo "Cloning foo3 into bar7"
141     $XFS_IO_PROG -c "reflink $SCRATCH_MNT/foo3" $SCRATCH_MNT/bar7 | _filter_xfs_io
142
143     echo "File bar7 digest = $(_md5_checksum $SCRATCH_MNT/bar7)"
144
145     # Unmount and mount again the filesystem. We want to verify the reflink
146     # operations were durably persisted.
147     _scratch_cycle_mount
148
149     echo "File digests after mounting again the filesystem:"
150     echo "File bar1 digest = $(_md5_checksum $SCRATCH_MNT/bar1)"
151     echo "File bar2 digest = $(_md5_checksum $SCRATCH_MNT/bar2)"
152     echo "File bar3 digest = $(_md5_checksum $SCRATCH_MNT/bar3)"
153     echo "File bar4 digest = $(_md5_checksum $SCRATCH_MNT/bar4)"
154     echo "File bar5 digest = $(_md5_checksum $SCRATCH_MNT/bar5)"
155     echo "File bar6 digest = $(_md5_checksum $SCRATCH_MNT/bar6)"
156     echo "File bar7 digest = $(_md5_checksum $SCRATCH_MNT/bar7)"
157 }
158
159 _scratch_mkfs "-O ^no-holes" >>$seqres.full 2>&1
160 _scratch_mount
161
162 echo
163 echo "Testing with defaults"
164 echo
165 run_tests
166
167 echo
168 echo "Testing with -o compress"
169 echo
170 _scratch_cycle_mount "compress"
171 run_tests
172
173 echo
174 echo "Testing with -o nodatacow"
175 echo
176 _scratch_cycle_mount "nodatacow"
177 run_tests
178
179 echo
180 echo "Testing with -O no-holes"
181 echo
182 _scratch_unmount
183 _scratch_mkfs "-O no-holes" >>$seqres.full 2>&1
184 _scratch_mount
185 run_tests
186
187 status=0
188 exit