Message ID | 1518470282-7948-1-git-send-email-ashish.samant@oracle.com |
---|---|
State | New, archived |
Headers | show |
Series | ext4: Fix return value for direct io reads at or beyond eof | expand |
Hi, Does this patch look ok? Gentle reminder for review. Thanks, Ashish On 02/12/2018 01:18 PM, Ashish Samant wrote: > 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@oracle.com> > --- > 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)
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)
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@oracle.com> --- fs/ext4/inode.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)