summaryrefslogtreecommitdiff
path: root/tests/btrfs/079
blob: e848a26159b32884eb5da0201f2bfec18bd23131 (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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2014 Fujitsu All Rights Reserved.
#
# FS QA Test No. btrfs/079
#
# Do write along with fiemap ioctl.
# Regression test for the kernel comit:
# 51f395ad btrfs: Use right extent length when inserting overlap extent map.
#
# When calling fiemap(without SYNC flag) and btrfs fs is commiting,
# it will cause race condition and cause btrfs to generate a wrong extent
# whose len is overflow and fail to insert into the extent map tree,
# returning -EEXIST.
#
# Fixed by the following patches (not merged in mainline yet):
# btrfs: Fix and enhance merge_extent_mapping() to insert best fitted extent map
# btrfs: Fix the wrong condition judgment about subset extent map
#
seq=`basename $0`
seqres=$RESULT_DIR/$seq
echo "QA output created by $seq"

tmp=/tmp/$$
status=1	# failure is the default!
trap "_cleanup; exit \$status" 0 1 2 3 15

_cleanup()
{
	kill $dd_pid &> /dev/null
	kill $fiemap_pid &> /dev/null
	wait
	rm -fr $testfile
	rm -fr $tmp.* $tmp
}

# get standard environment, filters and checks
. ./common/rc
. ./common/filter

# real QA test starts here
_supported_fs btrfs
_supported_os Linux
_require_scratch
# Since xfs_io's fiemap always use SYNC flag and can't be unset,
# we must use filefrag to call fiemap without SYNC flag.
_require_command "$FILEFRAG_PROG" filefrag
_require_xfs_io_command "falloc"

filesize=$((10 * 1024 * 1024 * 1024)) #10G size
buffersize=$((1024 * 1024)) # 1M bs for dd
count=$(($filesize / $buffersize))
testfile=$SCRATCH_MNT/testfile

rm -f $seqres.full

_scratch_mkfs >>$seqres.full 2>&1
_scratch_mount
_require_fs_space $SCRATCH_MNT $(($filesize / 1024))
$XFS_IO_PROG -f -c "falloc 0 $filesize" $testfile

dd_work() {
	out=$1
	dd if=/dev/zero of=$out bs=$buffersize count=$count \
	   conv=notrunc &> /dev/null
}

# There is a bug for e2fsprogs, at least in version 1.42.9, filefrag will
# leak the return value, so we can't judge return value only,
# but also to filter the output
_filter_error() {
	# when filefrag fails FIEMAP ioctl, it will fall back to FIBMAP,
	# which is not supported by btrfs and will report "FIBMAP: strerr()"
	# However old e2fsprogs will use wrong errno EINVAL other than ENOTTY
	# so only grep for "FIBMAP" for max compatibility.
	grep "FIBMAP"
}

fiemap_work() {
	filename=$1
	while true; do
		$FILEFRAG_PROG $filename 2> $tmp.output 1> /dev/null
		ret=$?
		err=`cat $tmp.output | _filter_error`
		if [ $ret -ne 0 -o -n "$err" ]; then
			kill $dd_pid
			return 1
		fi
	done
}

dd_work $testfile &
dd_pid=$!
fiemap_work $testfile &
fiemap_pid=$!
wait $dd_pid
ddret=$?
kill $fiemap_pid &> /dev/null
wait $fiemap_pid

if [ $ddret -ne 0 ]; then
	echo "Extent merge bug detected"
	status=1
	exit
else
	echo "Silence is golden"
	status=0
	exit
fi