diff options
-rw-r--r-- | drivers/block/pktcdvd.c | 9 | ||||
-rw-r--r-- | drivers/md/linear.c | 10 | ||||
-rw-r--r-- | drivers/md/raid0.c | 10 | ||||
-rw-r--r-- | drivers/md/raid10.c | 15 | ||||
-rw-r--r-- | drivers/md/raid5.c | 10 | ||||
-rw-r--r-- | fs/bio.c | 26 | ||||
-rw-r--r-- | include/linux/blkdev.h | 9 |
7 files changed, 60 insertions, 29 deletions
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 3ba1df93e9e3..589850cff359 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -2633,11 +2633,12 @@ end_io: | |||
2633 | 2633 | ||
2634 | 2634 | ||
2635 | 2635 | ||
2636 | static int pkt_merge_bvec(struct request_queue *q, struct bio *bio, struct bio_vec *bvec) | 2636 | static int pkt_merge_bvec(struct request_queue *q, struct bvec_merge_data *bmd, |
2637 | struct bio_vec *bvec) | ||
2637 | { | 2638 | { |
2638 | struct pktcdvd_device *pd = q->queuedata; | 2639 | struct pktcdvd_device *pd = q->queuedata; |
2639 | sector_t zone = ZONE(bio->bi_sector, pd); | 2640 | sector_t zone = ZONE(bmd->bi_sector, pd); |
2640 | int used = ((bio->bi_sector - zone) << 9) + bio->bi_size; | 2641 | int used = ((bmd->bi_sector - zone) << 9) + bmd->bi_size; |
2641 | int remaining = (pd->settings.size << 9) - used; | 2642 | int remaining = (pd->settings.size << 9) - used; |
2642 | int remaining2; | 2643 | int remaining2; |
2643 | 2644 | ||
@@ -2645,7 +2646,7 @@ static int pkt_merge_bvec(struct request_queue *q, struct bio *bio, struct bio_v | |||
2645 | * A bio <= PAGE_SIZE must be allowed. If it crosses a packet | 2646 | * A bio <= PAGE_SIZE must be allowed. If it crosses a packet |
2646 | * boundary, pkt_make_request() will split the bio. | 2647 | * boundary, pkt_make_request() will split the bio. |
2647 | */ | 2648 | */ |
2648 | remaining2 = PAGE_SIZE - bio->bi_size; | 2649 | remaining2 = PAGE_SIZE - bmd->bi_size; |
2649 | remaining = max(remaining, remaining2); | 2650 | remaining = max(remaining, remaining2); |
2650 | 2651 | ||
2651 | BUG_ON(remaining < 0); | 2652 | BUG_ON(remaining < 0); |
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 10748240cb2f..6a866d7c8ae5 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
@@ -50,17 +50,19 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector) | |||
50 | /** | 50 | /** |
51 | * linear_mergeable_bvec -- tell bio layer if two requests can be merged | 51 | * linear_mergeable_bvec -- tell bio layer if two requests can be merged |
52 | * @q: request queue | 52 | * @q: request queue |
53 | * @bio: the buffer head that's been built up so far | 53 | * @bvm: properties of new bio |
54 | * @biovec: the request that could be merged to it. | 54 | * @biovec: the request that could be merged to it. |
55 | * | 55 | * |
56 | * Return amount of bytes we can take at this offset | 56 | * Return amount of bytes we can take at this offset |
57 | */ | 57 | */ |
58 | static int linear_mergeable_bvec(struct request_queue *q, struct bio *bio, struct bio_vec *biovec) | 58 | static int linear_mergeable_bvec(struct request_queue *q, |
59 | struct bvec_merge_data *bvm, | ||
60 | struct bio_vec *biovec) | ||
59 | { | 61 | { |
60 | mddev_t *mddev = q->queuedata; | 62 | mddev_t *mddev = q->queuedata; |
61 | dev_info_t *dev0; | 63 | dev_info_t *dev0; |
62 | unsigned long maxsectors, bio_sectors = bio->bi_size >> 9; | 64 | unsigned long maxsectors, bio_sectors = bvm->bi_size >> 9; |
63 | sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev); | 65 | sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); |
64 | 66 | ||
65 | dev0 = which_dev(mddev, sector); | 67 | dev0 = which_dev(mddev, sector); |
66 | maxsectors = (dev0->size << 1) - (sector - (dev0->offset<<1)); | 68 | maxsectors = (dev0->size << 1) - (sector - (dev0->offset<<1)); |
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 914c04ddec7c..bcbb82594a19 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c | |||
@@ -241,18 +241,20 @@ static int create_strip_zones (mddev_t *mddev) | |||
241 | /** | 241 | /** |
242 | * raid0_mergeable_bvec -- tell bio layer if a two requests can be merged | 242 | * raid0_mergeable_bvec -- tell bio layer if a two requests can be merged |
243 | * @q: request queue | 243 | * @q: request queue |
244 | * @bio: the buffer head that's been built up so far | 244 | * @bvm: properties of new bio |
245 | * @biovec: the request that could be merged to it. | 245 | * @biovec: the request that could be merged to it. |
246 | * | 246 | * |
247 | * Return amount of bytes we can accept at this offset | 247 | * Return amount of bytes we can accept at this offset |
248 | */ | 248 | */ |
249 | static int raid0_mergeable_bvec(struct request_queue *q, struct bio *bio, struct bio_vec *biovec) | 249 | static int raid0_mergeable_bvec(struct request_queue *q, |
250 | struct bvec_merge_data *bvm, | ||
251 | struct bio_vec *biovec) | ||
250 | { | 252 | { |
251 | mddev_t *mddev = q->queuedata; | 253 | mddev_t *mddev = q->queuedata; |
252 | sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev); | 254 | sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); |
253 | int max; | 255 | int max; |
254 | unsigned int chunk_sectors = mddev->chunk_size >> 9; | 256 | unsigned int chunk_sectors = mddev->chunk_size >> 9; |
255 | unsigned int bio_sectors = bio->bi_size >> 9; | 257 | unsigned int bio_sectors = bvm->bi_size >> 9; |
256 | 258 | ||
257 | max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9; | 259 | max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9; |
258 | if (max < 0) max = 0; /* bio_add cannot handle a negative return */ | 260 | if (max < 0) max = 0; /* bio_add cannot handle a negative return */ |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index a71277b640ab..22bb2b1b886d 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -439,26 +439,27 @@ static sector_t raid10_find_virt(conf_t *conf, sector_t sector, int dev) | |||
439 | /** | 439 | /** |
440 | * raid10_mergeable_bvec -- tell bio layer if a two requests can be merged | 440 | * raid10_mergeable_bvec -- tell bio layer if a two requests can be merged |
441 | * @q: request queue | 441 | * @q: request queue |
442 | * @bio: the buffer head that's been built up so far | 442 | * @bvm: properties of new bio |
443 | * @biovec: the request that could be merged to it. | 443 | * @biovec: the request that could be merged to it. |
444 | * | 444 | * |
445 | * Return amount of bytes we can accept at this offset | 445 | * Return amount of bytes we can accept at this offset |
446 | * If near_copies == raid_disk, there are no striping issues, | 446 | * If near_copies == raid_disk, there are no striping issues, |
447 | * but in that case, the function isn't called at all. | 447 | * but in that case, the function isn't called at all. |
448 | */ | 448 | */ |
449 | static int raid10_mergeable_bvec(struct request_queue *q, struct bio *bio, | 449 | static int raid10_mergeable_bvec(struct request_queue *q, |
450 | struct bio_vec *bio_vec) | 450 | struct bvec_merge_data *bvm, |
451 | struct bio_vec *biovec) | ||
451 | { | 452 | { |
452 | mddev_t *mddev = q->queuedata; | 453 | mddev_t *mddev = q->queuedata; |
453 | sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev); | 454 | sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); |
454 | int max; | 455 | int max; |
455 | unsigned int chunk_sectors = mddev->chunk_size >> 9; | 456 | unsigned int chunk_sectors = mddev->chunk_size >> 9; |
456 | unsigned int bio_sectors = bio->bi_size >> 9; | 457 | unsigned int bio_sectors = bvm->bi_size >> 9; |
457 | 458 | ||
458 | max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9; | 459 | max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9; |
459 | if (max < 0) max = 0; /* bio_add cannot handle a negative return */ | 460 | if (max < 0) max = 0; /* bio_add cannot handle a negative return */ |
460 | if (max <= bio_vec->bv_len && bio_sectors == 0) | 461 | if (max <= biovec->bv_len && bio_sectors == 0) |
461 | return bio_vec->bv_len; | 462 | return biovec->bv_len; |
462 | else | 463 | else |
463 | return max; | 464 | return max; |
464 | } | 465 | } |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 54c8ee28fcc4..9b00675dc64f 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -3319,15 +3319,17 @@ static int raid5_congested(void *data, int bits) | |||
3319 | /* We want read requests to align with chunks where possible, | 3319 | /* We want read requests to align with chunks where possible, |
3320 | * but write requests don't need to. | 3320 | * but write requests don't need to. |
3321 | */ | 3321 | */ |
3322 | static int raid5_mergeable_bvec(struct request_queue *q, struct bio *bio, struct bio_vec *biovec) | 3322 | static int raid5_mergeable_bvec(struct request_queue *q, |
3323 | struct bvec_merge_data *bvm, | ||
3324 | struct bio_vec *biovec) | ||
3323 | { | 3325 | { |
3324 | mddev_t *mddev = q->queuedata; | 3326 | mddev_t *mddev = q->queuedata; |
3325 | sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev); | 3327 | sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); |
3326 | int max; | 3328 | int max; |
3327 | unsigned int chunk_sectors = mddev->chunk_size >> 9; | 3329 | unsigned int chunk_sectors = mddev->chunk_size >> 9; |
3328 | unsigned int bio_sectors = bio->bi_size >> 9; | 3330 | unsigned int bio_sectors = bvm->bi_size >> 9; |
3329 | 3331 | ||
3330 | if (bio_data_dir(bio) == WRITE) | 3332 | if ((bvm->bi_rw & 1) == WRITE) |
3331 | return biovec->bv_len; /* always allow writes to be mergeable */ | 3333 | return biovec->bv_len; /* always allow writes to be mergeable */ |
3332 | 3334 | ||
3333 | max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9; | 3335 | max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9; |
@@ -325,10 +325,19 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page | |||
325 | if (page == prev->bv_page && | 325 | if (page == prev->bv_page && |
326 | offset == prev->bv_offset + prev->bv_len) { | 326 | offset == prev->bv_offset + prev->bv_len) { |
327 | prev->bv_len += len; | 327 | prev->bv_len += len; |
328 | if (q->merge_bvec_fn && | 328 | |
329 | q->merge_bvec_fn(q, bio, prev) < len) { | 329 | if (q->merge_bvec_fn) { |
330 | prev->bv_len -= len; | 330 | struct bvec_merge_data bvm = { |
331 | return 0; | 331 | .bi_bdev = bio->bi_bdev, |
332 | .bi_sector = bio->bi_sector, | ||
333 | .bi_size = bio->bi_size, | ||
334 | .bi_rw = bio->bi_rw, | ||
335 | }; | ||
336 | |||
337 | if (q->merge_bvec_fn(q, &bvm, prev) < len) { | ||
338 | prev->bv_len -= len; | ||
339 | return 0; | ||
340 | } | ||
332 | } | 341 | } |
333 | 342 | ||
334 | goto done; | 343 | goto done; |
@@ -369,11 +378,18 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page | |||
369 | * queue to get further control | 378 | * queue to get further control |
370 | */ | 379 | */ |
371 | if (q->merge_bvec_fn) { | 380 | if (q->merge_bvec_fn) { |
381 | struct bvec_merge_data bvm = { | ||
382 | .bi_bdev = bio->bi_bdev, | ||
383 | .bi_sector = bio->bi_sector, | ||
384 | .bi_size = bio->bi_size, | ||
385 | .bi_rw = bio->bi_rw, | ||
386 | }; | ||
387 | |||
372 | /* | 388 | /* |
373 | * merge_bvec_fn() returns number of bytes it can accept | 389 | * merge_bvec_fn() returns number of bytes it can accept |
374 | * at this offset | 390 | * at this offset |
375 | */ | 391 | */ |
376 | if (q->merge_bvec_fn(q, bio, bvec) < len) { | 392 | if (q->merge_bvec_fn(q, &bvm, bvec) < len) { |
377 | bvec->bv_page = NULL; | 393 | bvec->bv_page = NULL; |
378 | bvec->bv_len = 0; | 394 | bvec->bv_len = 0; |
379 | bvec->bv_offset = 0; | 395 | bvec->bv_offset = 0; |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 7ab8acad5b6e..ff9d0bdf2a16 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -254,7 +254,14 @@ typedef int (prep_rq_fn) (struct request_queue *, struct request *); | |||
254 | typedef void (unplug_fn) (struct request_queue *); | 254 | typedef void (unplug_fn) (struct request_queue *); |
255 | 255 | ||
256 | struct bio_vec; | 256 | struct bio_vec; |
257 | typedef int (merge_bvec_fn) (struct request_queue *, struct bio *, struct bio_vec *); | 257 | struct bvec_merge_data { |
258 | struct block_device *bi_bdev; | ||
259 | sector_t bi_sector; | ||
260 | unsigned bi_size; | ||
261 | unsigned long bi_rw; | ||
262 | }; | ||
263 | typedef int (merge_bvec_fn) (struct request_queue *, struct bvec_merge_data *, | ||
264 | struct bio_vec *); | ||
258 | typedef void (prepare_flush_fn) (struct request_queue *, struct request *); | 265 | typedef void (prepare_flush_fn) (struct request_queue *, struct request *); |
259 | typedef void (softirq_done_fn)(struct request *); | 266 | typedef void (softirq_done_fn)(struct request *); |
260 | typedef int (dma_drain_needed_fn)(struct request *); | 267 | typedef int (dma_drain_needed_fn)(struct request *); |