diff options
author | Alasdair G Kergon <agk@redhat.com> | 2008-07-03 03:53:43 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-07-03 07:21:15 -0400 |
commit | cc371e66e340f35eed8dc4651c7c18e754c7fb26 (patch) | |
tree | 5a2d6727eb07a05999c531a90da43ab1c36b713e /drivers/md/raid10.c | |
parent | b24498d477a14680fc3bb3ad884fa9fa76a2d237 (diff) |
Add bvec_merge_data to handle stacked devices and ->merge_bvec()
When devices are stacked, one device's merge_bvec_fn may need to perform
the mapping and then call one or more functions for its underlying devices.
The following bio fields are used:
bio->bi_sector
bio->bi_bdev
bio->bi_size
bio->bi_rw using bio_data_dir()
This patch creates a new struct bvec_merge_data holding a copy of those
fields to avoid having to change them directly in the struct bio when
going down the stack only to have to change them back again on the way
back up. (And then when the bio gets mapped for real, the whole
exercise gets repeated, but that's a problem for another day...)
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Cc: Neil Brown <neilb@suse.de>
Cc: Milan Broz <mbroz@redhat.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r-- | drivers/md/raid10.c | 15 |
1 files changed, 8 insertions, 7 deletions
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 | } |