Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

Return short read or 0 at end of a raw device, not EIO

Author: David Jeffery <djeffery@redhat.com>
Changes to the basic direct I/O code have broken the raw driver when reading
to the end of a raw device. Instead of returning a short read for a read that
extends partially beyond the device's end or 0 when at the end of the device,
these reads now return EIO.

The raw driver needs the same end of device handling as was added for normal
block devices. Using blkdev_read_iter, which has the needed size checks,
prevents the EIO conditions at the end of the device.

Signed-off-by: David Jeffery <djeffery@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

authored by

David Jeffery and committed by
Al Viro
b2de525f b0afd8e5

+4 -2
+1 -1
drivers/char/raw.c
··· 285 285 286 286 static const struct file_operations raw_fops = { 287 287 .read = new_sync_read, 288 - .read_iter = generic_file_read_iter, 288 + .read_iter = blkdev_read_iter, 289 289 .write = new_sync_write, 290 290 .write_iter = blkdev_write_iter, 291 291 .fsync = blkdev_fsync,
+2 -1
fs/block_dev.c
··· 1585 1585 } 1586 1586 EXPORT_SYMBOL_GPL(blkdev_write_iter); 1587 1587 1588 - static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to) 1588 + ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to) 1589 1589 { 1590 1590 struct file *file = iocb->ki_filp; 1591 1591 struct inode *bd_inode = file->f_mapping->host; ··· 1599 1599 iov_iter_truncate(to, size); 1600 1600 return generic_file_read_iter(iocb, to); 1601 1601 } 1602 + EXPORT_SYMBOL_GPL(blkdev_read_iter); 1602 1603 1603 1604 /* 1604 1605 * Try to release a page associated with block device when the system
+1
include/linux/fs.h
··· 2469 2469 extern ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos); 2470 2470 2471 2471 /* fs/block_dev.c */ 2472 + extern ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to); 2472 2473 extern ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from); 2473 2474 extern int blkdev_fsync(struct file *filp, loff_t start, loff_t end, 2474 2475 int datasync);