e848a26159b32884eb5da0201f2bfec18bd23131
[xfstests-dev.git] / tests / btrfs / 079
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (C) 2014 Fujitsu All Rights Reserved.
4 #
5 # FS QA Test No. btrfs/079
6 #
7 # Do write along with fiemap ioctl.
8 # Regression test for the kernel comit:
9 # 51f395ad btrfs: Use right extent length when inserting overlap extent map.
10 #
11 # When calling fiemap(without SYNC flag) and btrfs fs is commiting,
12 # it will cause race condition and cause btrfs to generate a wrong extent
13 # whose len is overflow and fail to insert into the extent map tree,
14 # returning -EEXIST.
15 #
16 # Fixed by the following patches (not merged in mainline yet):
17 # btrfs: Fix and enhance merge_extent_mapping() to insert best fitted extent map
18 # btrfs: Fix the wrong condition judgment about subset extent map
19 #
20 seq=`basename $0`
21 seqres=$RESULT_DIR/$seq
22 echo "QA output created by $seq"
23
24 tmp=/tmp/$$
25 status=1        # failure is the default!
26 trap "_cleanup; exit \$status" 0 1 2 3 15
27
28 _cleanup()
29 {
30         kill $dd_pid &> /dev/null
31         kill $fiemap_pid &> /dev/null
32         wait
33         rm -fr $testfile
34         rm -fr $tmp.* $tmp
35 }
36
37 # get standard environment, filters and checks
38 . ./common/rc
39 . ./common/filter
40
41 # real QA test starts here
42 _supported_fs btrfs
43 _supported_os Linux
44 _require_scratch
45 # Since xfs_io's fiemap always use SYNC flag and can't be unset,
46 # we must use filefrag to call fiemap without SYNC flag.
47 _require_command "$FILEFRAG_PROG" filefrag
48 _require_xfs_io_command "falloc"
49
50 filesize=$((10 * 1024 * 1024 * 1024)) #10G size
51 buffersize=$((1024 * 1024)) # 1M bs for dd
52 count=$(($filesize / $buffersize))
53 testfile=$SCRATCH_MNT/testfile
54
55 rm -f $seqres.full
56
57 _scratch_mkfs >>$seqres.full 2>&1
58 _scratch_mount
59 _require_fs_space $SCRATCH_MNT $(($filesize / 1024))
60 $XFS_IO_PROG -f -c "falloc 0 $filesize" $testfile
61
62 dd_work() {
63         out=$1
64         dd if=/dev/zero of=$out bs=$buffersize count=$count \
65            conv=notrunc &> /dev/null
66 }
67
68 # There is a bug for e2fsprogs, at least in version 1.42.9, filefrag will
69 # leak the return value, so we can't judge return value only,
70 # but also to filter the output
71 _filter_error() {
72         # when filefrag fails FIEMAP ioctl, it will fall back to FIBMAP,
73         # which is not supported by btrfs and will report "FIBMAP: strerr()"
74         # However old e2fsprogs will use wrong errno EINVAL other than ENOTTY
75         # so only grep for "FIBMAP" for max compatibility.
76         grep "FIBMAP"
77 }
78
79 fiemap_work() {
80         filename=$1
81         while true; do
82                 $FILEFRAG_PROG $filename 2> $tmp.output 1> /dev/null
83                 ret=$?
84                 err=`cat $tmp.output | _filter_error`
85                 if [ $ret -ne 0 -o -n "$err" ]; then
86                         kill $dd_pid
87                         return 1
88                 fi
89         done
90 }
91
92 dd_work $testfile &
93 dd_pid=$!
94 fiemap_work $testfile &
95 fiemap_pid=$!
96 wait $dd_pid
97 ddret=$?
98 kill $fiemap_pid &> /dev/null
99 wait $fiemap_pid
100
101 if [ $ddret -ne 0 ]; then
102         echo "Extent merge bug detected"
103         status=1
104         exit
105 else
106         echo "Silence is golden"
107         status=0
108         exit
109 fi