Currently, an unaligned dio read at eof on ext4 returns EINVAL from do_blockdev_direct_IO. However this unaligned dio read at eof could be due to previous short read and we should return zero. Fix this by checking for this condition in ext4_direct_IO_read() and returning zero, if true. Signed-off-by: Ashish Samant <ashish.samant@xxxxxxxxxx> --- fs/ext4/inode.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 534a913..8b3dbc0 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3806,7 +3806,7 @@ static ssize_t ext4_direct_IO_read(struct kiocb *iocb, struct iov_iter *iter) struct address_space *mapping = iocb->ki_filp->f_mapping; struct inode *inode = mapping->host; size_t count = iov_iter_count(iter); - ssize_t ret; + ssize_t ret = 0; /* * Shared inode_lock is enough for us - it protects against concurrent @@ -3814,6 +3814,8 @@ static ssize_t ext4_direct_IO_read(struct kiocb *iocb, struct iov_iter *iter) * we are protected against page writeback as well. */ inode_lock_shared(inode); + if (iocb->ki_pos >= i_size_read(inode)) + goto out_unlock; ret = filemap_write_and_wait_range(mapping, iocb->ki_pos, iocb->ki_pos + count - 1); if (ret) -- 1.9.1