Commit 877bc275 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] blkdev_get_blocks(): handle eof

For reasons which escape me, blockdev_get_blocks() is returning -EIO if the
mapping request straddles the end of the disk.  This causes reads which
straddle end-of-disk to return -EIO.

Fix it up so that it correctly trims the returned result down to match the
size of the device, for both reads and writes.

If a write attempt is fully beyond end-of-device then return -EIO.  We never
get this far anyway, because generic_write_checks() will return -ENOSPC if all
of the write lies outside a blockdev's i_size.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 01a59cd1
......@@ -137,13 +137,26 @@ static int
blkdev_get_blocks(struct inode *inode, sector_t iblock,
unsigned long max_blocks, struct buffer_head *bh, int create)
{
if ((iblock + max_blocks) > max_block(I_BDEV(inode)))
return -EIO;
sector_t end_block = max_block(I_BDEV(inode));
if ((iblock + max_blocks) > end_block) {
max_blocks = end_block - iblock;
if ((long)max_blocks <= 0) {
if (create)
return -EIO; /* write fully beyond EOF */
/*
* It is a read which is fully beyond EOF. We return
* a !buffer_mapped buffer
*/
max_blocks = 0;
}
}
bh->b_bdev = I_BDEV(inode);
bh->b_blocknr = iblock;
bh->b_size = max_blocks << inode->i_blkbits;
set_buffer_mapped(bh);
if (max_blocks)
set_buffer_mapped(bh);
return 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment