btrfs: add test for cases when a dio write has to fallback to a buffered write
authorFilipe Manana <>
Tue, 16 Mar 2021 12:22:15 +0000 (12:22 +0000)
committerEryu Guan <>
Wed, 17 Mar 2021 17:40:01 +0000 (01:40 +0800)
Test cases where a direct IO write, with O_DSYNC, can not be done and has
to fallback to a buffered write.

This is motivated by the fact we don't have existing tests for these cases
and in fact we had a regression for one case in the 5.10 kernel. This was
the case when doing a direct IO write, with O_DSYNC, against a file offset
that is not aligned to the filesystem's block size, which resulted in
triggering an assertion failure when btrfs is built with assertions enabled
(CONFIG_BTRFS_ASSERT=y). One openSUSE Tumbleweed user hit this frequently
when using Docker and DB2.

The kernel commit in 5.10 that introduced the regression was commit
0eb79294dbe328 ("btrfs: dio iomap DSYNC workaround")). In kernel 5.11 the
regression fixed, by pure chance, by commit ecfdc08b8cc65d ("btrfs: remove
dio iomap DSYNC workaround"). Since the commit that fixed the bug in 5.11
was dependent on a large patchset, a special and simple fix was added to
the stable kernel 5.10.18 by commit a6703c71153438 ("btrfs: fix crash after
non-aligned direct IO write with O_DSYNC").

Signed-off-by: Filipe Manana <>
Reviewed-by: Eryu Guan <>
Signed-off-by: Eryu Guan <>
tests/btrfs/234 [new file with mode: 0755]
tests/btrfs/234.out [new file with mode: 0644]

diff --git a/tests/btrfs/234 b/tests/btrfs/234
new file mode 100755 (executable)
index 0000000..df64e54
--- /dev/null
@@ -0,0 +1,64 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2021 SUSE Linux Products GmbH. All Rights Reserved.
+# FS QA Test No. btrfs/234
+# Test cases where a direct IO write, with O_DSYNC, can not be done and has to
+# fallback to a buffered write.
+seq=`basename $0`
+echo "QA output created by $seq"
+status=1       # failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+       cd /
+       rm -f $tmp.*
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/attr
+# real QA test starts here
+_supported_fs btrfs
+_require_chattr c
+rm -f $seqres.full
+_scratch_mkfs >>$seqres.full 2>&1
+# Create a test file with compression enabled (chattr +c).
+touch $SCRATCH_MNT/foo
+# Now do a buffered write to create compressed extents.
+$XFS_IO_PROG -s -c "pwrite -S 0xab -b 1M 0 1M" $SCRATCH_MNT/foo | _filter_xfs_io
+# Now do the direct IO write with O_DSYNC into a file range that contains
+# compressed extents. It should fallback to buffered IO and succeed.
+$XFS_IO_PROG -d -s -c "pwrite -S 0xcd 512K 512K" $SCRATCH_MNT/foo | _filter_xfs_io
+# Now try doing a direct IO write, with O_DSYNC, for a range that starts with
+# non-aligned offset. It should also fallback to buffered IO and succeed.
+$XFS_IO_PROG -f -d -s -c "pwrite -S 0xef 1111 512K" $SCRATCH_MNT/bar | _filter_xfs_io
+# Unmount, mount again, and verify we have the expected data.
+echo "File foo data:"
+od -A d -t x1 $SCRATCH_MNT/foo
+echo "File bar data:"
+od -A d -t x1 $SCRATCH_MNT/bar
diff --git a/tests/btrfs/234.out b/tests/btrfs/234.out
new file mode 100644 (file)
index 0000000..4504a19
--- /dev/null
@@ -0,0 +1,21 @@
+QA output created by 234
+wrote 1048576/1048576 bytes at offset 0
+XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 524288/524288 bytes at offset 524288
+XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 524288/524288 bytes at offset 1111
+XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+File foo data:
+0000000 ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab
+0524288 cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd
+File bar data:
+0000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+0001104 00 00 00 00 00 00 00 ef ef ef ef ef ef ef ef ef
+0001120 ef ef ef ef ef ef ef ef ef ef ef ef ef ef ef ef
+0525392 ef ef ef ef ef ef ef
index 5214dbd..6d0c70c 100644 (file)
 231 auto quick clone log replay
 232 auto quick qgroup limit
 233 auto quick subvolume
+234 auto quick compress rw