On Thu 19-11-15 21:25:34, Jan Kara wrote: > Assume a filesystem with 4KB blocks. When a file has size 1000 bytes and > we issue direct IO read at offset 1024, blockdev_direct_IO() reads the > tail of the last block and the logic for handling short DIO reads in > dio_complete() results in a return value -24 (1000 - 1024) which > obviously confuses userspace. > > Fix the problem by bailing out early once we sample i_size and can > reliably check that direct IO read starts beyond i_size. > > Reported-by: Avi Kivity <avi@xxxxxxxxxxxx> > Fixes: 9fe55eea7e4b444bafc42fa0000cc2d1d2847275 > CC: stable@xxxxxxxxxxxxxxx > CC: Steven Whitehouse <swhiteho@xxxxxxxxxx> > Signed-off-by: Jan Kara <jack@xxxxxxx> > --- > fs/direct-io.c | 10 +++++++++- > 1 file changed, 9 insertions(+), 1 deletion(-) > > Avi, this patch fixes the issue for me. Jens, can you pick up this fix please? Thanks! Honza > diff --git a/fs/direct-io.c b/fs/direct-io.c > index 18e7554cf94c..08094c9d8172 100644 > --- a/fs/direct-io.c > +++ b/fs/direct-io.c > @@ -1163,6 +1163,15 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, > } > } > > + /* Once we sampled i_size check for reads beyond EOF */ > + dio->i_size = i_size_read(inode); > + if (iov_iter_rw(iter) == READ && offset >= dio->i_size) { > + if (dio->flags & DIO_LOCKING) > + mutex_unlock(&inode->i_mutex); > + kmem_cache_free(dio_cache, dio); > + goto out; > + } > + > /* > * For file extending writes updating i_size before data writeouts > * complete can expose uninitialized blocks in dumb filesystems. > @@ -1216,7 +1225,6 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, > sdio.next_block_for_io = -1; > > dio->iocb = iocb; > - dio->i_size = i_size_read(inode); > > spin_lock_init(&dio->bio_lock); > dio->refcount = 1; > -- > 2.1.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html