mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/2] btrfs: drain in-flight direct IO before direct writes dirty the page cache
@ 2026-11-06 15:21 Breno Leitao
  2026-11-06 15:21 ` [PATCH v2 1/2] btrfs: drain in-flight direct IO before buffered write fallback Breno Leitao
  2026-11-06 15:21 ` [PATCH v2 2/2] btrfs: drain in-flight direct IO before zeroing an unaligned EOF block Breno Leitao
  0 siblings, 2 replies; 3+ messages in thread
From: Breno Leitao @ 2026-11-06 15:21 UTC (permalink / raw)
  To: David Sterba, Chris Mason
  Cc: Qu Wenruo, Filipe Manana, Boris Burkov, Atish Patra, linux-btrfs,
	linux-kernel, linux-arm-kernel, Breno Leitao, kernel-team,
	stable, Qu Wenruo

Atish reported that arm64 hosts with 64K pages and 4K btrfs blocks,
which keep VM disk images as NOCOW files opened with O_DIRECT, log

  Page cache invalidation failure on direct I/O.  Possible data corruption due to collision with buffered I/O!

and the next fsync() on the image fails with -EIO. Every write the VM
issues is O_DIRECT, the buffered writes come from btrfs itself.

Both patches close the same race: a direct write dirties a folio while
another task's direct write to a different block of that folio is in
flight, and the completion of the latter fails to invalidate it.

Patch 1 waits before the buffered fallback for unaligned writes. Patch 2
waits before btrfs_write_check() zeroes the block at an unaligned EOF,
which btrfs_direct_write() does before it decides to fall back.

Tested on a 64K page arm64 kernel, on a NOCOW file of a 4K block btrfs.
Async 4K O_DIRECT writes race 512 byte O_DIRECT writes inside EOF
(fallback), and O_DIRECT writes past an unaligned EOF, of 4K (eof-dio)
and of 512 bytes, which fall back (eof-fb). fdatasync() EIOs in 20
seconds per test:

              base   patch 1   patch 1+2
  fallback       6         0           0
  eof-dio       24        20           0
  eof-fb        34        14           0

60 second runs got 56 and 38 EIOs in the eof tests with patch 1, and
none in any test with both patches, in two runs. The reproducer for
patch 1 is at [1].

[1] https://github.com/leitao/btrfs-dio-fallback

Signed-off-by: Breno Leitao <leitao@debian.org>
---
Changes in v2:
- New patch 2: drain in-flight direct IO before btrfs_write_check()
  zeroes the block at an unaligned EOF (Qu, from a Sashiko review).
- Patch 1: no code change. Picked up Boris' Reviewed-by, and added a
  stable Cc.
- Both patches: the Fixes: tags now name 95ea0486b20e, which first
  allowed writes with more than one block per folio, 4K blocks on 64K
  pages.
- Link to v1: https://lore.kernel.org/all/auxv7Tg0xSq5yHmb@gmail.com/

---
Breno Leitao (2):
      btrfs: drain in-flight direct IO before buffered write fallback
      btrfs: drain in-flight direct IO before zeroing an unaligned EOF block

 fs/btrfs/file.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
---
base-commit: ddfe51b0a0f5dc9e415cc2c8ad8db17532dd426b
base-tree: git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
change-id: 20261106-btrfs_page_cache-2ab11049c913

Best regards,
--  
Breno Leitao <leitao@debian.org>


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-11-06 15:26 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-06 15:21 [PATCH v2 0/2] btrfs: drain in-flight direct IO before direct writes dirty the page cache Breno Leitao
2026-11-06 15:21 ` [PATCH v2 1/2] btrfs: drain in-flight direct IO before buffered write fallback Breno Leitao
2026-11-06 15:21 ` [PATCH v2 2/2] btrfs: drain in-flight direct IO before zeroing an unaligned EOF block Breno Leitao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®