From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Subject: Re: [PATCH] direct-io: Fix negative return from dio read beyond eof To: Jan Kara , axboe@kernel.dk References: <1447964734-16010-1-git-send-email-jack@suse.cz> Cc: linux-fsdevel@vger.kernel.org, Jeff Moyer , stable@vger.kernel.org, Steven Whitehouse From: Avi Kivity Message-ID: <56A89E16.3060706@scylladb.com> Date: Wed, 27 Jan 2016 12:38:14 +0200 MIME-Version: 1.0 In-Reply-To: <1447964734-16010-1-git-send-email-jack@suse.cz> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Sender: stable-owner@vger.kernel.org List-ID: On 11/19/2015 10:25 PM, 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 > Fixes: 9fe55eea7e4b444bafc42fa0000cc2d1d2847275 > CC: stable@vger.kernel.org While this patch made it into upstream, it did not appear in 4.3.4. Did it slip through the proverbial cracks? Can it be queued for 4.3.5? > CC: Steven Whitehouse > Signed-off-by: Jan Kara > --- > fs/direct-io.c | 10 +++++++++- > 1 file changed, 9 insertions(+), 1 deletion(-) > > Avi, this patch fixes the issue for me. > > 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;