xfs/{263,106}: erase max warnings printout
[xfstests-dev.git] / tests / btrfs / 080
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (C) 2014 SUSE Linux Products GmbH. All Rights Reserved.
4 #
5 # FSQA Test No. 080
6 #
7 # Regression test for a btrfs issue where if right after the snapshot creation
8 # ioctl started, a file write followed by a file truncate happened, with both
9 # operations increasing the file's size, the created snapshot would capture an
10 # inconsistent state of the file system tree. That state reflected the file
11 # truncation but it didn't reflect the write operation, and left a gap between
12 # two file extent items (and that gap corresponded to the total or a partial
13 # area of the write operation's range).
14 #
15 # This issue was fixed by the following linux kernel patch:
16 #
17 #     Btrfs: fix snapshot inconsistency after a file write followed by truncate
18 #
19 seq=`basename $0`
20 seqres=$RESULT_DIR/$seq
21 echo "QA output created by $seq"
22 tmp=/tmp/$$
23 status=1        # failure is the default!
24 trap "_cleanup; exit \$status" 0 1 2 3 15
25
26 _cleanup()
27 {
28         for p in ${cpu_stress_pids[*]}; do
29                 kill $p &> /dev/null
30         done
31         rm -f $tmp.*
32 }
33
34 # get standard environment, filters and checks
35 . ./common/rc
36 . ./common/filter
37
38 # real QA test starts here
39 _supported_fs btrfs
40 _supported_os Linux
41 _require_scratch_nocheck
42
43 rm -f $seqres.full
44
45 create_snapshot()
46 {
47         local ts=`date +'%H_%M_%S_%N'`
48
49         _run_btrfs_util_prog subvolume snapshot -r \
50                 $SCRATCH_MNT $SCRATCH_MNT/"${ts}_snap"
51 }
52
53 create_file()
54 {
55         local name=$1
56
57         run_check $XFS_IO_PROG -f \
58                 -c "pwrite -S 0xaa -b 32K 0 32K" \
59                 -c "fsync" \
60                 -c "pwrite -S 0xbb -b 32770 16K 32770" \
61                 -c "truncate 90123" \
62                 $SCRATCH_MNT/$name
63 }
64
65 workout()
66 {
67         local name=$1
68
69         create_file $name &
70         fpid=$!
71         create_snapshot &
72         spid=$!
73         wait $fpid
74         create_ret=$?
75         wait $spid
76         snap_ret=$?
77         if [ $create_ret != 0 -o $snap_ret != 0 ]; then
78                 _fail "Failure creating file or snapshot, check $seqres.full for details"
79         fi
80 }
81
82 # If the installed btrfs mkfs supports the no-holes feature, make sure the
83 # created fs doesn't get that feature enabled. With it enabled, the below fsck
84 # call wouldn't fail. This feature hasn't been enabled by default since it was
85 # introduced, but be safe and explicitly disable it.
86 _scratch_mkfs -O list-all 2>&1 | grep -q '\bno\-holes\b'
87 if [ $? -eq 0 ]; then
88         mkfs_options="-O ^no-holes"
89 fi
90 _scratch_mkfs "$mkfs_options" >>$seqres.full 2>&1
91
92 _scratch_mount
93
94 # Run some background load in order to make the issue easier to trigger.
95 # Specially needed when testing with non-debug kernels and there isn't
96 # any other significant load on the test machine other than this test.
97 num_cpus=`$here/src/feature -o`
98 num_procs=$(($num_cpus * 20))
99 for ((i = 0; i < $num_procs; i++)); do
100         while true; do
101                 true
102         done &
103         cpu_stress_pids[$i]=$!
104 done
105
106 for ((i = 1; i <= 100; i++)); do
107         workout "foobar_$i"
108 done
109
110 for ((i = 0; i < $num_procs; i++)); do
111         kill ${cpu_stress_pids[$i]} &> /dev/null
112         unset cpu_stress_pids[$i]
113 done
114
115 for f in $(find $SCRATCH_MNT -type f -name 'foobar_*'); do
116         digest=`md5sum $f | cut -d ' ' -f 1`
117         case $digest in
118         "d41d8cd98f00b204e9800998ecf8427e")
119                 # ok, empty file
120                 ;;
121         "c28418534a020122aca59fd3ff9581b5")
122                 # ok, only first write captured
123                 ;;
124         "cd0032da89254cdc498fda396e6a9b54")
125                 # ok, only 2 first writes captured
126                 ;;
127         "a1963f914baf4d2579d643425f4e54bc")
128                 # ok, the 2 writes and the truncate were captured
129                 ;;
130         *)
131                 # not ok, truncate captured but not one or both writes
132                 _fail "Unexpected digest for file $f"
133         esac
134 done
135
136 # Check the filesystem for inconsistencies.
137 # Before the btrfs kernel fix mentioned above, we would very often get fsck
138 # error messages like: "root 306 inode 338 errors 100, file extent discount".
139 #
140 # This was because if right after the snapshot creation ioctl started, a file
141 # write followed by a file truncate, with both operations increasing the file's
142 # size, we would get a snapshot that reflected a state where the file truncation
143 # was visible but the previous file write was not visible, breaking expected
144 # total ordering of operations and causing a gap between 2 file extents, where a
145 # file extent item representing the range [32K .. ALIGN(16K + 32770, 4096)] was
146 # missing in the snapshot's btree.
147 _check_scratch_fs
148
149 echo "Silence is golden"
150 status=0
151 exit