summaryrefslogtreecommitdiff
path: root/tests/generic/032
blob: c006a591709c8c01b8f1d3c5c2262c04bd75b269 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2014 Red Hat, Inc.  All Rights Reserved.
#
# FS QA Test No. 032
#
# This test implements a data corruption scenario on XFS filesystems with
# sub-page sized blocks and unwritten extents. Inode lock contention during
# writeback of pages to unwritten extents leads to failure to convert those
# extents on I/O completion. This causes data corruption as unwritten extents
# are always read back as zeroes.
#
. ./common/preamble
_begin_fstest auto quick rw fiemap prealloc

# Override the default cleanup function.
_cleanup()
{
	cd /
	kill -9 $syncpid > /dev/null 2>&1
	wait
	rm -f $tmp.*
}

# Import common functions.
. ./common/punch

# real QA test starts here

_syncloop()
{
	while [ true ]; do
		sync
	done
}

# Modify as appropriate.
_supported_fs generic
_require_scratch
_require_xfs_io_command "falloc"
_require_xfs_io_command "fiemap"

_scratch_mkfs >/dev/null 2>&1
_scratch_mount

# run background sync thread
_syncloop &
syncpid=$!

for iters in $(seq 1 100)
do
	rm -f $SCRATCH_MNT/file

	# create a delalloc block in each page of the first 64k of the file
	for pgoff in $(seq 0 0x1000 0xf000); do
		offset=$((pgoff + 0xc00))
		$XFS_IO_PROG -f \
			-c "pwrite $offset 0x1" \
			$SCRATCH_MNT/file >> $seqres.full 2>&1
	done

	# preallocate the first 64k and overwite, writing past 64k to contend
	# with writeback
	file_len=0x100000
	$XFS_IO_PROG \
		-c "falloc 0 0x10000"	\
		-c "pwrite 0 $file_len"	\
		-c "fsync"		\
		$SCRATCH_MNT/file >> $seqres.full 2>&1

	# Check for unwritten extents. We should have none before EOF since we
	# wrote over the entire preallocated region and ran fsync.
	eof_sector=$(( file_len / 512 ))
	$XFS_IO_PROG -c 'fiemap -v' $SCRATCH_MNT/file | \
		_filter_fiemap | \
		tr '[.]:' '    ' | \
		awk "{if (\$2 < $eof_sector) {print \$0}}" | \
		grep -q unwritten && _fail "Unwritten extents found!"
done

echo $iters iterations

kill $syncpid
wait

# clear page cache and dump the file
_scratch_cycle_mount
_hexdump $SCRATCH_MNT/file

status=0
exit