[PATCH 3/5] xfs: drain in-flight DIO before buffered writes

From: Jiale Yao

Date: Sun Oct 25 2026 - 08:41:55 EST


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@xxxxxxxxxxxxxxx
Signed-off-by: Jiale Yao <yaojiale02@xxxxxxx>
---
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