diff options
| -rw-r--r-- | block/ll_rw_blk.c | 63 |
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 | */ | ||
| 3126 | static 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) | |||
| 3147 | static inline void __generic_make_request(struct bio *bio) | 3176 | static 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); |
