Skip to content

Commit ff99a2b

Browse files
author
Brian Foster
committed
ext4: fail unaligned direct IO write with EINVAL
JIRA: https://issues.redhat.com/browse/RHEL-121230 commit 9638457 Author: Jan Kara <jack@suse.cz> Date: Mon Sep 1 13:27:40 2025 +0200 ext4: fail unaligned direct IO write with EINVAL Commit bc264fe ("iomap: support incremental iomap_iter advances") changed the error handling logic in iomap_iter(). Previously any error from iomap_dio_bio_iter() got propagated to userspace, after this commit if ->iomap_end returns error, it gets propagated to userspace instead of an error from iomap_dio_bio_iter(). This results in unaligned writes to ext4 to silently fallback to buffered IO instead of erroring out. Now returning ENOTBLK for DIO writes from ext4_iomap_end() seems unnecessary these days. It is enough to return ENOTBLK from ext4_iomap_begin() when we don't support DIO write for that particular file offset (due to hole). Fixes: bc264fe ("iomap: support incremental iomap_iter advances") Cc: stable@kernel.org Signed-off-by: Jan Kara <jack@suse.cz> Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com> Message-ID: <20250901112739.32484-2-jack@suse.cz> Signed-off-by: Theodore Ts'o <tytso@mit.edu> Signed-off-by: Brian Foster <bfoster@redhat.com>
1 parent 6cc30e0 commit ff99a2b

File tree

1 file changed

+0
-35
lines changed

1 file changed

+0
-35
lines changed

fs/ext4/inode.c

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3468,47 +3468,12 @@ static int ext4_iomap_overwrite_begin(struct inode *inode, loff_t offset,
34683468
return ret;
34693469
}
34703470

3471-
static inline bool ext4_want_directio_fallback(unsigned flags, ssize_t written)
3472-
{
3473-
/* must be a directio to fall back to buffered */
3474-
if ((flags & (IOMAP_WRITE | IOMAP_DIRECT)) !=
3475-
(IOMAP_WRITE | IOMAP_DIRECT))
3476-
return false;
3477-
3478-
/* atomic writes are all-or-nothing */
3479-
if (flags & IOMAP_ATOMIC)
3480-
return false;
3481-
3482-
/* can only try again if we wrote nothing */
3483-
return written == 0;
3484-
}
3485-
3486-
static int ext4_iomap_end(struct inode *inode, loff_t offset, loff_t length,
3487-
ssize_t written, unsigned flags, struct iomap *iomap)
3488-
{
3489-
/*
3490-
* Check to see whether an error occurred while writing out the data to
3491-
* the allocated blocks. If so, return the magic error code for
3492-
* non-atomic write so that we fallback to buffered I/O and attempt to
3493-
* complete the remainder of the I/O.
3494-
* For non-atomic writes, any blocks that may have been
3495-
* allocated in preparation for the direct I/O will be reused during
3496-
* buffered I/O. For atomic write, we never fallback to buffered-io.
3497-
*/
3498-
if (ext4_want_directio_fallback(flags, written))
3499-
return -ENOTBLK;
3500-
3501-
return 0;
3502-
}
3503-
35043471
const struct iomap_ops ext4_iomap_ops = {
35053472
.iomap_begin = ext4_iomap_begin,
3506-
.iomap_end = ext4_iomap_end,
35073473
};
35083474

35093475
const struct iomap_ops ext4_iomap_overwrite_ops = {
35103476
.iomap_begin = ext4_iomap_overwrite_begin,
3511-
.iomap_end = ext4_iomap_end,
35123477
};
35133478

35143479
static int ext4_iomap_begin_report(struct inode *inode, loff_t offset,

0 commit comments

Comments
 (0)