mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-15 14:32:06 +00:00
ext4: fail unaligned direct IO write with EINVAL
commit963845748fupstream. Commitbc264fea0f("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:bc264fea0f("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: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
d9774bbe39
commit
e9663669a5
@@ -3872,47 +3872,12 @@ static int ext4_iomap_overwrite_begin(struct inode *inode, loff_t offset,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool ext4_want_directio_fallback(unsigned flags, ssize_t written)
|
||||
{
|
||||
/* must be a directio to fall back to buffered */
|
||||
if ((flags & (IOMAP_WRITE | IOMAP_DIRECT)) !=
|
||||
(IOMAP_WRITE | IOMAP_DIRECT))
|
||||
return false;
|
||||
|
||||
/* atomic writes are all-or-nothing */
|
||||
if (flags & IOMAP_ATOMIC)
|
||||
return false;
|
||||
|
||||
/* can only try again if we wrote nothing */
|
||||
return written == 0;
|
||||
}
|
||||
|
||||
static int ext4_iomap_end(struct inode *inode, loff_t offset, loff_t length,
|
||||
ssize_t written, unsigned flags, struct iomap *iomap)
|
||||
{
|
||||
/*
|
||||
* Check to see whether an error occurred while writing out the data to
|
||||
* the allocated blocks. If so, return the magic error code for
|
||||
* non-atomic write so that we fallback to buffered I/O and attempt to
|
||||
* complete the remainder of the I/O.
|
||||
* For non-atomic writes, any blocks that may have been
|
||||
* allocated in preparation for the direct I/O will be reused during
|
||||
* buffered I/O. For atomic write, we never fallback to buffered-io.
|
||||
*/
|
||||
if (ext4_want_directio_fallback(flags, written))
|
||||
return -ENOTBLK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct iomap_ops ext4_iomap_ops = {
|
||||
.iomap_begin = ext4_iomap_begin,
|
||||
.iomap_end = ext4_iomap_end,
|
||||
};
|
||||
|
||||
const struct iomap_ops ext4_iomap_overwrite_ops = {
|
||||
.iomap_begin = ext4_iomap_overwrite_begin,
|
||||
.iomap_end = ext4_iomap_end,
|
||||
};
|
||||
|
||||
static int ext4_iomap_begin_report(struct inode *inode, loff_t offset,
|
||||
|
||||
Reference in New Issue
Block a user