Skip to content

Commit 74cedf9

Browse files
jankaraaxboe
authored andcommitted
direct-io: Fix negative return from dio read beyond eof
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 <[email protected]> Fixes: 9fe55ee CC: [email protected] CC: Steven Whitehouse <[email protected]> Signed-off-by: Jan Kara <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent bf4e6b4 commit 74cedf9

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

fs/direct-io.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1169,6 +1169,15 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
11691169
}
11701170
}
11711171

1172+
/* Once we sampled i_size check for reads beyond EOF */
1173+
dio->i_size = i_size_read(inode);
1174+
if (iov_iter_rw(iter) == READ && offset >= dio->i_size) {
1175+
if (dio->flags & DIO_LOCKING)
1176+
mutex_unlock(&inode->i_mutex);
1177+
kmem_cache_free(dio_cache, dio);
1178+
goto out;
1179+
}
1180+
11721181
/*
11731182
* For file extending writes updating i_size before data writeouts
11741183
* complete can expose uninitialized blocks in dumb filesystems.
@@ -1222,7 +1231,6 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
12221231
sdio.next_block_for_io = -1;
12231232

12241233
dio->iocb = iocb;
1225-
dio->i_size = i_size_read(inode);
12261234

12271235
spin_lock_init(&dio->bio_lock);
12281236
dio->refcount = 1;

0 commit comments

Comments
 (0)