From cbf04dde8b3c5a7e043e91cefad68b8980ea0d18 Mon Sep 17 00:00:00 2001 From: Hungyu Lin Date: Mon, 2 Nov 2026 06:15:55 +0000 Subject: [PATCH] ext2: preserve completed DIO bytes when buffered fallback fails ext2_dio_write_iter() can complete part of a direct write before falling back to buffered I/O for a hole inside i_size. If generic_perform_write() then fails, its error overwrites the completed direct-I/O byte count. For example, on a full filesystem, an 8 KiB write to a file with an allocated 4 KiB prefix and a 4 KiB hole overwrites the prefix but returns ENOSPC and leaves the file position unchanged. GNU dd with oflag=direct consequently reports zero bytes written. Preserve a positive direct-I/O result and return the buffered error when no bytes were direct-written. This restores the fallback policy of generic_file_write_iter(), which ext2 used before its iomap conversion. Fixes: fb5de4358e1a ("ext2: Move direct-io to use iomap") Cc: stable@vger.kernel.org Signed-off-by: Hungyu Lin Link: https://patch.msgid.link/20261102061555.55183-1-dennylin0707@gmail.com Signed-off-by: Jan Kara --- fs/ext2/file.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 67fe423c3828..8ddc149d4884 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -145,7 +145,8 @@ static ssize_t ext2_dio_write_iter(struct kiocb *iocb, struct iov_iter *from) pos = iocb->ki_pos; status = generic_perform_write(iocb, from); if (unlikely(status < 0)) { - ret = status; + if (!ret) + ret = status; goto out_unlock; }