2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2014 Red Hat, Inc. All Rights Reserved.
7 # This test implements a data corruption scenario on XFS filesystems with
8 # sub-page sized blocks and unwritten extents. Inode lock contention during
9 # writeback of pages to unwritten extents leads to failure to convert those
10 # extents on I/O completion. This causes data corruption as unwritten extents
11 # are always read back as zeroes.
14 seqres=$RESULT_DIR/$seq
15 echo "QA output created by $seq"
19 status=1 # failure is the default!
20 trap "_cleanup; exit \$status" 0 1 2 3 15
25 kill -9 $syncpid > /dev/null 2>&1
30 # get standard environment, filters and checks
34 # real QA test starts here
44 # Modify as appropriate.
47 _require_xfs_io_command "falloc"
48 _require_xfs_io_command "fiemap"
50 _scratch_mkfs >/dev/null 2>&1
53 # run background sync thread
57 for iters in $(seq 1 100)
59 rm -f $SCRATCH_MNT/file
61 # create a delalloc block in each page of the first 64k of the file
62 for pgoff in $(seq 0 0x1000 0xf000); do
63 offset=$((pgoff + 0xc00))
65 -c "pwrite $offset 0x1" \
66 $SCRATCH_MNT/file >> $seqres.full 2>&1
69 # preallocate the first 64k and overwite, writing past 64k to contend
73 -c "falloc 0 0x10000" \
74 -c "pwrite 0 $file_len" \
76 $SCRATCH_MNT/file >> $seqres.full 2>&1
78 # Check for unwritten extents. We should have none before EOF since we
79 # wrote over the entire preallocated region and ran fsync.
80 eof_sector=$(( file_len / 512 ))
81 $XFS_IO_PROG -c 'fiemap -v' $SCRATCH_MNT/file | \
84 awk "{if (\$2 < $eof_sector) {print \$0}}" | \
85 grep -q unwritten && _fail "Unwritten extents found!"
88 echo $iters iterations
93 # clear page cache and dump the file
95 hexdump $SCRATCH_MNT/file