Commit c07e2b41 authored by Jens Axboe's avatar Jens Axboe

block: factor our bio_check_eod()

End of device check is done twice in __generic_make_request() and it's
fully inlined each time.  Factor out bio_check_eod().
Signed-off-by: default avatarTejun Heo <htejun@gmail.com>
Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent a0cd1285
...@@ -3120,6 +3120,35 @@ static inline int should_fail_request(struct bio *bio) ...@@ -3120,6 +3120,35 @@ static inline int should_fail_request(struct bio *bio)
#endif /* CONFIG_FAIL_MAKE_REQUEST */ #endif /* CONFIG_FAIL_MAKE_REQUEST */
/*
* Check whether this bio extends beyond the end of the device.
*/
static inline int bio_check_eod(struct bio *bio, unsigned int nr_sectors)
{
sector_t maxsector;
if (!nr_sectors)
return 0;
/* Test device or partition size, when known. */
maxsector = bio->bi_bdev->bd_inode->i_size >> 9;
if (maxsector) {
sector_t sector = bio->bi_sector;
if (maxsector < nr_sectors || maxsector - nr_sectors < sector) {
/*
* This may well happen - the kernel calls bread()
* without checking the size of the device, e.g., when
* mounting a device.
*/
handle_bad_sector(bio);
return 1;
}
}
return 0;
}
/** /**
* generic_make_request: hand a buffer to its device driver for I/O * generic_make_request: hand a buffer to its device driver for I/O
* @bio: The bio describing the location in memory and on the device. * @bio: The bio describing the location in memory and on the device.
...@@ -3147,27 +3176,14 @@ static inline int should_fail_request(struct bio *bio) ...@@ -3147,27 +3176,14 @@ static inline int should_fail_request(struct bio *bio)
static inline void __generic_make_request(struct bio *bio) static inline void __generic_make_request(struct bio *bio)
{ {
struct request_queue *q; struct request_queue *q;
sector_t maxsector;
sector_t old_sector; sector_t old_sector;
int ret, nr_sectors = bio_sectors(bio); int ret, nr_sectors = bio_sectors(bio);
dev_t old_dev; dev_t old_dev;
might_sleep(); might_sleep();
/* Test device or partition size, when known. */
maxsector = bio->bi_bdev->bd_inode->i_size >> 9;
if (maxsector) {
sector_t sector = bio->bi_sector;
if (maxsector < nr_sectors || maxsector - nr_sectors < sector) { if (bio_check_eod(bio, nr_sectors))
/* goto end_io;
* This may well happen - the kernel calls bread()
* without checking the size of the device, e.g., when
* mounting a device.
*/
handle_bad_sector(bio);
goto end_io;
}
}
/* /*
* Resolve the mapping until finished. (drivers are * Resolve the mapping until finished. (drivers are
...@@ -3223,21 +3239,8 @@ static inline void __generic_make_request(struct bio *bio) ...@@ -3223,21 +3239,8 @@ static inline void __generic_make_request(struct bio *bio)
old_sector = bio->bi_sector; old_sector = bio->bi_sector;
old_dev = bio->bi_bdev->bd_dev; old_dev = bio->bi_bdev->bd_dev;
maxsector = bio->bi_bdev->bd_inode->i_size >> 9; if (bio_check_eod(bio, nr_sectors))
if (maxsector) { goto end_io;
sector_t sector = bio->bi_sector;
if (maxsector < nr_sectors ||
maxsector - nr_sectors < sector) {
/*
* This may well happen - partitions are not
* checked to make sure they are within the size
* of the whole device.
*/
handle_bad_sector(bio);
goto end_io;
}
}
ret = q->make_request_fn(q, bio); ret = q->make_request_fn(q, bio);
} while (ret); } while (ret);
......
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