Linux XFS filesystem development
 help / color / mirror / Atom feed
* [PATCH 0/5] fs: drain in-flight DIO before buffered writes
@ 2026-10-25 12:41 Jiale Yao
  2026-10-25 12:41 ` [PATCH 3/5] xfs: " Jiale Yao
  2026-10-25 12:41 ` [PATCH 4/5] xfs: drain in-flight DIO before zoned " Jiale Yao
  0 siblings, 2 replies; 4+ messages in thread
From: Jiale Yao @ 2026-10-25 12:41 UTC (permalink / raw)
  To: Jaegeuk Kim, Chao Yu, Carlos Maiolino, Damien Le Moal,
	Naohiro Aota, Johannes Thumshirn, Matthew Wilcox (Oracle),
	Jan Kara, Andrew Morton, Al Viro, Eric Biggers, Dave Chinner,
	Darrick J. Wong, linux-f2fs-devel, linux-kernel, linux-xfs,
	linux-fsdevel, linux-mm

An asynchronous direct write can remain in flight after its submitting
thread releases the filesystem's I/O submission lock. If a buffered write
dirties page cache before that direct write completes, post-I/O page-cache
invalidation can find dirty pages, report possible data corruption, and
record -EIO in the mapping error sequence.

Drain in-flight DIO before buffered writes in the generic filemap path,
F2FS, XFS, and zonefs. The filemap change also protects UDF and other
users of __generic_file_write_iter(). Keep IOCB_NOWAIT requests
nonblocking by returning -EAGAIN when a drain would be required.

The patches are separated by common code or filesystem and remain
independently buildable in series order.

Jiale Yao (5):
  filemap: drain in-flight DIO before buffered writes
  f2fs: drain in-flight DIO before buffered writes
  xfs: drain in-flight DIO before buffered writes
  xfs: drain in-flight DIO before zoned buffered writes
  zonefs: drain in-flight DIO before buffered writes

 fs/f2fs/file.c    | 13 +++++++++++--
 fs/xfs/xfs_file.c | 22 ++++++++++++++++++++++
 fs/zonefs/file.c  |  8 ++++++++
 mm/filemap.c      |  9 +++++++++
 4 files changed, 50 insertions(+), 2 deletions(-)

-- 
2.34.1


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

* [PATCH 3/5] xfs: drain in-flight DIO before buffered writes
  2026-10-25 12:41 [PATCH 0/5] fs: drain in-flight DIO before buffered writes Jiale Yao
@ 2026-10-25 12:41 ` Jiale Yao
  2026-10-26  0:52   ` Dave Chinner
  2026-10-25 12:41 ` [PATCH 4/5] xfs: drain in-flight DIO before zoned " Jiale Yao
  1 sibling, 1 reply; 4+ messages in thread
From: Jiale Yao @ 2026-10-25 12:41 UTC (permalink / raw)
  To: Carlos Maiolino, Darrick J. Wong, Dave Chinner, linux-xfs,
	linux-kernel
  Cc: stable

XFS_IOLOCK_EXCL prevents new direct I/O submissions, but asynchronous
direct writes submitted while the lock was shared can remain active after
their submitting threads release the lock. A buffered write can then dirty
page cache before direct I/O completion performs post-write invalidation.

Wait for active DIO after acquiring XFS_IOLOCK_EXCL and before buffered
write checks can modify page cache. Return -EAGAIN instead of waiting for
an IOCB_NOWAIT request.

Fixes: acdda3aae146 ("xfs: use iomap_dio_rw")
Cc: stable@vger.kernel.org
Signed-off-by: Jiale Yao <yaojiale02@163.com>
---
 fs/xfs/xfs_file.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 7d0c8a197575..aa7cf51b5843 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -1018,6 +1018,20 @@ xfs_file_dax_write(
 	return ret;
 }
 
+STATIC int
+xfs_file_buffered_write_dio_wait(
+	struct kiocb		*iocb)
+{
+	struct inode		*inode = file_inode(iocb->ki_filp);
+
+	if (!atomic_read(&inode->i_dio_count))
+		return 0;
+	if (iocb->ki_flags & IOCB_NOWAIT)
+		return -EAGAIN;
+	inode_dio_wait(inode);
+	return 0;
+}
+
 STATIC ssize_t
 xfs_file_buffered_write(
 	struct kiocb		*iocb,
@@ -1035,6 +1049,10 @@ xfs_file_buffered_write(
 	if (ret)
 		return ret;
 
+	ret = xfs_file_buffered_write_dio_wait(iocb);
+	if (ret)
+		goto out;
+
 	ret = xfs_file_write_checks(iocb, from, &iolock, NULL);
 	if (ret)
 		goto out;
-- 
2.34.1


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

* [PATCH 4/5] xfs: drain in-flight DIO before zoned buffered writes
  2026-10-25 12:41 [PATCH 0/5] fs: drain in-flight DIO before buffered writes Jiale Yao
  2026-10-25 12:41 ` [PATCH 3/5] xfs: " Jiale Yao
@ 2026-10-25 12:41 ` Jiale Yao
  1 sibling, 0 replies; 4+ messages in thread
From: Jiale Yao @ 2026-10-25 12:41 UTC (permalink / raw)
  To: Carlos Maiolino, Darrick J. Wong, linux-xfs, linux-kernel; +Cc: stable

Buffered writes to zoned realtime files hold XFS_IOLOCK_EXCL, but direct
I/O submitted earlier while holding the lock shared can still be active.
The buffered write can dirty page cache before the asynchronous direct
write completes its post-I/O invalidation, causing an invalidation failure
and a mapping error.

Use the buffered-write DIO drain after acquiring XFS_IOLOCK_EXCL and
before the zoned write checks can touch page cache. Preserve NOWAIT
semantics by returning -EAGAIN when a wait would be needed.

Fixes: 2e2383405824 ("xfs: implement direct writes to zoned RT devices")
Cc: stable@vger.kernel.org
Signed-off-by: Jiale Yao <yaojiale02@163.com>
---
 fs/xfs/xfs_file.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index aa7cf51b5843..96a11af8e71a 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -1121,6 +1121,10 @@ xfs_file_buffered_write_zoned(
 	if (ret)
 		goto out_unreserve;
 
+	ret = xfs_file_buffered_write_dio_wait(iocb);
+	if (ret)
+		goto out_unlock;
+
 	ret = xfs_file_write_checks(iocb, from, &iolock, &ac);
 	if (ret)
 		goto out_unlock;
-- 
2.34.1


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

* Re: [PATCH 3/5] xfs: drain in-flight DIO before buffered writes
  2026-10-25 12:41 ` [PATCH 3/5] xfs: " Jiale Yao
@ 2026-10-26  0:52   ` Dave Chinner
  0 siblings, 0 replies; 4+ messages in thread
From: Dave Chinner @ 2026-10-26  0:52 UTC (permalink / raw)
  To: Jiale Yao
  Cc: Carlos Maiolino, Darrick J. Wong, Dave Chinner, linux-xfs,
	linux-kernel, stable

On Sun, Oct 25, 2026 at 08:41:12PM +0800, Jiale Yao wrote:
> XFS_IOLOCK_EXCL prevents new direct I/O submissions, but asynchronous
> direct writes submitted while the lock was shared can remain active after
> their submitting threads release the lock. A buffered write can then dirty
> page cache before direct I/O completion performs post-write invalidation.
> 
> Wait for active DIO after acquiring XFS_IOLOCK_EXCL and before buffered
> write checks can modify page cache. Return -EAGAIN instead of waiting for
> an IOCB_NOWAIT request.
> 
> Fixes: acdda3aae146 ("xfs: use iomap_dio_rw")
> Cc: stable@vger.kernel.org
> Signed-off-by: Jiale Yao <yaojiale02@163.com>
> ---
>  fs/xfs/xfs_file.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)

This doesn't fix the page cache dirtying race condition. Write to
the file with mmap() instead of write() and the same thing happens.
Because ->page-mkwrite() doesn't use the IOLOCK, it can't be
serialised against DIO submission or in flight DIO.

Regardless, overlapping buffered and direct writes to the same file
indicate an application bug that needs fixing because the result of
such IO patterns is not deterministic (even with this "fix").

Sometimes the DIO write will win, sometimes the buffered write will
win. Either way, one of the application writes gets lost and so we
still have data corruption from an application perspective...

IOWs, all this patch does is shut up the warning that tells us that
the application is doing stupid things that could result in data
corruption.

-Dave.
-- 
Dave Chinner
dgc@kernel.org

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

end of thread, other threads:[~2026-10-26  0:52 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-25 12:41 [PATCH 0/5] fs: drain in-flight DIO before buffered writes Jiale Yao
2026-10-25 12:41 ` [PATCH 3/5] xfs: " Jiale Yao
2026-10-26  0:52   ` Dave Chinner
2026-10-25 12:41 ` [PATCH 4/5] xfs: drain in-flight DIO before zoned " Jiale Yao

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