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.
48 _require_xfs_io_command "falloc"
49 _require_xfs_io_command "fiemap"
51 _scratch_mkfs >/dev/null 2>&1
54 # run background sync thread
58 for iters in $(seq 1 100)
60 rm -f $SCRATCH_MNT/file
62 # create a delalloc block in each page of the first 64k of the file
63 for pgoff in $(seq 0 0x1000 0xf000); do
64 offset=$((pgoff + 0xc00))
66 -c "pwrite $offset 0x1" \
67 $SCRATCH_MNT/file >> $seqres.full 2>&1
70 # preallocate the first 64k and overwite, writing past 64k to contend
74 -c "falloc 0 0x10000" \
75 -c "pwrite 0 $file_len" \
77 $SCRATCH_MNT/file >> $seqres.full 2>&1
79 # Check for unwritten extents. We should have none before EOF since we
80 # wrote over the entire preallocated region and ran fsync.
81 eof_sector=$(( file_len / 512 ))
82 $XFS_IO_PROG -c 'fiemap -v' $SCRATCH_MNT/file | \
85 awk "{if (\$2 < $eof_sector) {print \$0}}" | \
86 grep -q unwritten && _fail "Unwritten extents found!"
89 echo $iters iterations
94 # clear page cache and dump the file
96 hexdump $SCRATCH_MNT/file