generic/405: test mkfs against thin provision device
[xfstests-dev.git] / tests / generic / 404
1 #! /bin/bash
2 # FS QA Test 404
3 #
4 # Regression test which targets two nasty ext4 bugs in a logic which
5 # shifts extents:
6 #
7 # 1) 14d981f468a1 ("ext4: Include forgotten start block on fallocate insert range")
8 #
9 # An incorrect right shift (insert range) for the first extent in
10 # a range.
11 #
12 # Test tries to insert many blocks at the same offset to reproduce
13 # the following layout:
14 #
15 #    block #0  block #1
16 #    |ext0 ext1|ext2 ext3 ...|
17 #         ^
18 #      insert of a new block
19 #
20 # Because of an incorrect range first block is never reached,
21 # thus ext1 is untouched, resulting to a hole at a wrong offset:
22 #
23 # What we got:
24 #
25 #    block #0   block #1
26 #    |ext0 ext1|   ext2 ext3 ...|
27 #               ^
28 #               hole at a wrong offset
29 #
30 # What we expect:
31 #
32 #    block #0    block #1
33 #    |ext0   ext1|ext2 ext3 ...|
34 #         ^
35 #         hole at a correct offset
36 #
37 # 2) 2b3864b32403 ("ext4: do not polute the extents cache while shifting extents")
38 #
39 # Extents status tree is filled in with outdated offsets while doing
40 # extents shift, that leads to wrong data blocks.  That is why test
41 # writes unique block content and checks md5sum of a result file after
42 # each block insert.
43 #
44 #-----------------------------------------------------------------------
45 # Copyright (c) 2017 Roman Penyaev.  All Rights Reserved.
46 #
47 # This program is free software; you can redistribute it and/or
48 # modify it under the terms of the GNU General Public License as
49 # published by the Free Software Foundation.
50 #
51 # This program is distributed in the hope that it would be useful,
52 # but WITHOUT ANY WARRANTY; without even the implied warranty of
53 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
54 # GNU General Public License for more details.
55 #
56 # You should have received a copy of the GNU General Public License
57 # along with this program; if not, write the Free Software Foundation,
58 # Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
59 #-----------------------------------------------------------------------
60 #
61
62 seq=`basename $0`
63 seqres=$RESULT_DIR/$seq
64 echo "QA output created by $seq"
65
66 here=`pwd`
67 tmp=/tmp/$$
68 status=1        # failure is the default!
69 trap "_cleanup; exit \$status" 0 1 2 3 15
70
71 testfile=$TEST_DIR/$seq.file
72 pattern=$tmp.pattern
73
74 _cleanup()
75 {
76         cd /
77         rm -f $tmp.*
78         rm -f $testfile
79 }
80
81 # get standard environment, filters and checks
82 . ./common/rc
83 . ./common/filter
84
85 # remove previous $seqres.full before test
86 rm -f $seqres.full
87
88 # real QA test starts here
89
90 # Modify as appropriate.
91 _supported_fs generic
92 _supported_os Linux
93 _require_test
94 _require_xfs_io_command "finsert"
95
96 blksize=`_get_block_size $TEST_DIR`
97
98 # Generate a block with a repeating number represented as 4 bytes decimal.
99 # The test generates unique pattern for each block in order to observe a
100 # wrong order if any.
101 function generate_pattern() {
102         blkind=$1
103         printf "%04d" $blkind | awk  '{ while (c++ < '$(($blksize/4))') \
104                 printf "%s", $0 }' > $pattern
105 }
106
107 $XFS_IO_PROG -f -c "falloc 0 $(($blksize * 2))" $testfile \
108                          >> $seqres.full 2>&1
109
110 # First block, has 0001 as a pattern
111 generate_pattern 1
112 $XFS_IO_PROG -c "pwrite -i $pattern        0 $blksize" $testfile \
113                          >> $seqres.full 2>&1
114
115 # Second block, has 0002 as a pattern
116 generate_pattern 2
117 $XFS_IO_PROG -c "pwrite -i $pattern $blksize $blksize" $testfile \
118                          >> $seqres.full 2>&1
119
120 # Insert 498 blocks after the first block.  We use this quite big
121 # number to increase the reproduction probability.
122 for (( block=3; block<=500; block++ )); do
123         $XFS_IO_PROG -c "finsert $blksize $blksize" $testfile \
124                                  >> $seqres.full 2>&1
125
126         generate_pattern $block
127         $XFS_IO_PROG -c "pwrite -i $pattern $blksize $blksize" $testfile \
128                                  >> $seqres.full 2>&1
129
130         # Avoid offsets in hexdump output, because block size can vary.
131         # Here we check md5 after each insert to be sure that zero blocks
132         # do not appear, targets this commit:
133         #   14d981f468a1 ("ext4: Include forgotten start block on fallocate insert range")
134         # or blocks are in correct order, this commit:
135         #   2b3864b32403 ("ext4: do not polute the extents cache while shifting extents")
136         #
137         md5=`hexdump -e '16/1 "%_p" "\n"' $testfile | md5sum`
138         printf "#%d %s\n" "$block" "$md5"
139 done
140
141 # Eventually output file has 500 blocks in the following order:
142 #   0001 0500 0499 0498 ... 0002
143
144 # success, all done
145 status=0
146 exit