reflink: ensure that we can handle reflinking a lot of extents
[xfstests-dev.git] / tests / generic / 032
1 #! /bin/bash
2 # FS QA Test No. 032
3 #
4 # This test implements a data corruption scenario on XFS filesystems with
5 # sub-page sized blocks and unwritten extents. Inode lock contention during
6 # writeback of pages to unwritten extents leads to failure to convert those
7 # extents on I/O completion. This causes data corruption as unwritten extents
8 # are always read back as zeroes.
9 #
10 #-----------------------------------------------------------------------
11 # Copyright (c) 2014 Red Hat, Inc.  All Rights Reserved.
12 #
13 # This program is free software; you can redistribute it and/or
14 # modify it under the terms of the GNU General Public License as
15 # published by the Free Software Foundation.
16 #
17 # This program is distributed in the hope that it would be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 # GNU General Public License for more details.
21 #
22 # You should have received a copy of the GNU General Public License
23 # along with this program; if not, write the Free Software Foundation,
24 # Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
25 #-----------------------------------------------------------------------
26 #
27
28 seq=`basename $0`
29 seqres=$RESULT_DIR/$seq
30 echo "QA output created by $seq"
31
32 here=`pwd`
33 tmp=/tmp/$$
34 status=1        # failure is the default!
35 trap "_cleanup; exit \$status" 0 1 2 3 15
36
37 _cleanup()
38 {
39         cd /
40         kill -9 $syncpid > /dev/null 2>&1
41         wait
42         rm -f $tmp.*
43 }
44
45 # get standard environment, filters and checks
46 . ./common/rc
47 . ./common/punch
48
49 # real QA test starts here
50 rm -f $seqres.full
51
52 _syncloop()
53 {
54         while [ true ]; do
55                 sync
56         done
57 }
58
59 # Modify as appropriate.
60 _supported_fs generic
61 _supported_os Linux
62 _require_scratch
63 _require_xfs_io_command "falloc"
64 _require_xfs_io_command "fiemap"
65
66 _scratch_mkfs >/dev/null 2>&1
67 _scratch_mount
68
69 # run background sync thread
70 _syncloop &
71 syncpid=$!
72
73 for iters in $(seq 1 100)
74 do
75         rm -f $SCRATCH_MNT/file
76
77         # create a delalloc block in each page of the first 64k of the file
78         for pgoff in $(seq 0 0x1000 0xf000); do
79                 offset=$((pgoff + 0xc00))
80                 $XFS_IO_PROG -f \
81                         -c "pwrite $offset 0x1" \
82                         $SCRATCH_MNT/file >> $seqres.full 2>&1
83         done
84
85         # preallocate the first 64k and overwite, writing past 64k to contend
86         # with writeback
87         $XFS_IO_PROG \
88                 -c "falloc 0 0x10000"   \
89                 -c "pwrite 0 0x100000"  \
90                 -c "fsync"              \
91                 $SCRATCH_MNT/file >> $seqres.full 2>&1
92
93         # Check for unwritten extents. We should have none since we wrote over
94         # the entire preallocated region and ran fsync.
95         $XFS_IO_PROG -c "fiemap -v" $SCRATCH_MNT/file | \
96                 tee -a $seqres.full | \
97                 _filter_fiemap | grep unwritten
98         [ $? == 0 ] && _fail "Unwritten extents found!"
99 done
100
101 echo $iters iterations
102
103 kill $syncpid
104 wait
105
106 # clear page cache and dump the file
107 _scratch_remount
108 hexdump $SCRATCH_MNT/file
109
110 status=0
111 exit