generic: test for non-zero used blocks while writing into a file

Test that if we keep overwriting an entire file, either with buffered
writes or direct IO writes, the number of used blocks reported by stat(2)
is never zero while the writes and writeback are in progress.

This is motivated by a bug in btrfs and currently fails on btrfs only. It
is fixed a patchset for btrfs that has the following patches:

  btrfs: fix missing delalloc new bit for new delalloc ranges
  btrfs: refactor btrfs_drop_extents() to make it easier to extend
  btrfs: fix race when defragging that leads to unnecessary IO
  btrfs: update the number of bytes used by an inode atomically

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Eryu Guan <guaneryu@gmail.com>
This commit is contained in:
Filipe Manana
2020-11-09 12:01:06 +00:00
committed by Eryu Guan
parent 609bb35622
commit 7a327ad2f4
3 changed files with 88 additions and 0 deletions
+84
View File
@@ -0,0 +1,84 @@
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2020 SUSE Linux Products GmbH. All Rights Reserved.
#
# FS QA Test No. 615
#
# Test that if we keep overwriting an entire file, either with buffered writes
# or direct IO writes, the number of used blocks reported by stat(2) is never
# zero while writeback is in progress.
#
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()
{
cd /
rm -f $tmp.*
}
# get standard environment, filters and checks
. ./common/rc
. ./common/filter
# real QA test starts here
_supported_fs generic
_require_scratch
_require_odirect
rm -f $seqres.full
stat_loop()
{
trap "wait; exit" SIGTERM
local filepath=$1
local blocks
while :; do
blocks=$(stat -c %b $filepath)
if [ $blocks -eq 0 ]; then
echo "error: stat(2) reported zero blocks"
break
fi
done
}
_scratch_mkfs >>$seqres.full 2>&1
_scratch_mount
$XFS_IO_PROG -f -s -c "pwrite -b 64K 0 64K" $SCRATCH_MNT/foo > /dev/null
stat_loop $SCRATCH_MNT/foo &
loop_pid=$!
echo "Testing buffered writes"
# Now keep overwriting the entire file, triggering writeback after each write,
# while another process is calling stat(2) on the file. We expect the number of
# used blocks reported by stat(2) to be always greater than 0.
for ((i = 0; i < 2000; i++)); do
if ! kill -s 0 $loop_pid &> /dev/null; then
break
fi
$XFS_IO_PROG -s -c "pwrite -b 64K 0 64K" $SCRATCH_MNT/foo > /dev/null
done
echo "Testing direct IO writes"
# Now similar to what we did before but for direct IO writes.
for ((i = 0; i < 2000; i++)); do
if ! kill -s 0 $loop_pid &> /dev/null; then
break
fi
$XFS_IO_PROG -d -c "pwrite -b 64K 0 64K" $SCRATCH_MNT/foo > /dev/null
done
kill $loop_pid &> /dev/null
wait
status=0
exit
+3
View File
@@ -0,0 +1,3 @@
QA output created by 615
Testing buffered writes
Testing direct IO writes
+1
View File
@@ -617,3 +617,4 @@
612 auto quick clone
613 auto quick encrypt
614 auto quick rw
615 auto rw