aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/ll_rw_blk.c63
1 files changed, 33 insertions, 30 deletions
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 8904f8b1f417..548f0d826679 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -3120,6 +3120,35 @@ static inline int should_fail_request(struct bio *bio)
3120 3120
3121#endif /* CONFIG_FAIL_MAKE_REQUEST */ 3121#endif /* CONFIG_FAIL_MAKE_REQUEST */
3122 3122
3123/*
3124 * Check whether this bio extends beyond the end of the device.
3125 */
3126static inline int bio_check_eod(struct bio *bio, unsigned int nr_sectors)
3127{
3128 sector_t maxsector;
3129
3130 if (!nr_sectors)
3131 return 0;
3132
3133 /* Test device or partition size, when known. */
3134 maxsector = bio->bi_bdev->bd_inode->i_size >> 9;
3135 if (maxsector) {
3136 sector_t sector = bio->bi_sector;
3137
3138 if (maxsector < nr_sectors || maxsector - nr_sectors < sector) {
3139 /*
3140 * This may well happen - the kernel calls bread()
3141 * without checking the size of the device, e.g., when
3142 * mounting a device.
3143 */
3144 handle_bad_sector(bio);
3145 return 1;
3146 }
3147 }
3148
3149 return 0;
3150}
3151
3123/** 3152/**
3124 * generic_make_request: hand a buffer to its device driver for I/O 3153 * generic_make_request: hand a buffer to its device driver for I/O
3125 * @bio: The bio describing the location in memory and on the device. 3154 * @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)
3147static inline void __generic_make_request(struct bio *bio) 3176static inline void __generic_make_request(struct bio *bio)
3148{ 3177{
3149 struct request_queue *q; 3178 struct request_queue *q;
3150 sector_t maxsector;
3151 sector_t old_sector; 3179 sector_t old_sector;
3152 int ret, nr_sectors = bio_sectors(bio); 3180 int ret, nr_sectors = bio_sectors(bio);
3153 dev_t old_dev; 3181 dev_t old_dev;
3154 3182
3155 might_sleep(); 3183 might_sleep();
3156 /* Test device or partition size, when known. */
3157 maxsector = bio->bi_bdev->bd_inode->i_size >> 9;
3158 if (maxsector) {
3159 sector_t sector = bio->bi_sector;
3160 3184
3161 if (maxsector < nr_sectors || maxsector - nr_sectors < sector) { 3185 if (bio_check_eod(bio, nr_sectors))
3162 /* 3186 goto end_io;
3163 * This may well happen - the kernel calls bread()
3164 * without checking the size of the device, e.g., when
3165 * mounting a device.
3166 */
3167 handle_bad_sector(bio);
3168 goto end_io;
3169 }
3170 }
3171 3187
3172 /* 3188 /*
3173 * Resolve the mapping until finished. (drivers are 3189 * Resolve the mapping until finished. (drivers are
@@ -3223,21 +3239,8 @@ end_io:
3223 old_sector = bio->bi_sector; 3239 old_sector = bio->bi_sector;
3224 old_dev = bio->bi_bdev->bd_dev; 3240 old_dev = bio->bi_bdev->bd_dev;
3225 3241
3226 maxsector = bio->bi_bdev->bd_inode->i_size >> 9; 3242 if (bio_check_eod(bio, nr_sectors))
3227 if (maxsector) { 3243 goto end_io;
3228 sector_t sector = bio->bi_sector;
3229
3230 if (maxsector < nr_sectors ||
3231 maxsector - nr_sectors < sector) {
3232 /*
3233 * This may well happen - partitions are not
3234 * checked to make sure they are within the size
3235 * of the whole device.
3236 */
3237 handle_bad_sector(bio);
3238 goto end_io;
3239 }
3240 }
3241 3244
3242 ret = q->make_request_fn(q, bio); 3245 ret = q->make_request_fn(q, bio);
3243 } while (ret); 3246 } while (ret);