diff options
-rw-r--r-- | drivers/md/dm.c | 43 |
1 files changed, 24 insertions, 19 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 88d60202b9db..26b08ee425c7 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -533,30 +533,35 @@ static void __clone_and_map(struct clone_info *ci) | |||
533 | 533 | ||
534 | } else { | 534 | } else { |
535 | /* | 535 | /* |
536 | * Create two copy bios to deal with io that has | 536 | * Handle a bvec that must be split between two or more targets. |
537 | * been split across a target. | ||
538 | */ | 537 | */ |
539 | struct bio_vec *bv = bio->bi_io_vec + ci->idx; | 538 | struct bio_vec *bv = bio->bi_io_vec + ci->idx; |
539 | sector_t remaining = to_sector(bv->bv_len); | ||
540 | unsigned int offset = 0; | ||
540 | 541 | ||
541 | clone = split_bvec(bio, ci->sector, ci->idx, | 542 | do { |
542 | bv->bv_offset, max); | 543 | if (offset) { |
543 | __map_bio(ti, clone, tio); | 544 | ti = dm_table_find_target(ci->map, ci->sector); |
545 | max = max_io_len(ci->md, ci->sector, ti); | ||
544 | 546 | ||
545 | ci->sector += max; | 547 | tio = alloc_tio(ci->md); |
546 | ci->sector_count -= max; | 548 | tio->io = ci->io; |
547 | ti = dm_table_find_target(ci->map, ci->sector); | 549 | tio->ti = ti; |
548 | 550 | memset(&tio->info, 0, sizeof(tio->info)); | |
549 | len = to_sector(bv->bv_len) - max; | 551 | } |
550 | clone = split_bvec(bio, ci->sector, ci->idx, | 552 | |
551 | bv->bv_offset + to_bytes(max), len); | 553 | len = min(remaining, max); |
552 | tio = alloc_tio(ci->md); | 554 | |
553 | tio->io = ci->io; | 555 | clone = split_bvec(bio, ci->sector, ci->idx, |
554 | tio->ti = ti; | 556 | bv->bv_offset + offset, len); |
555 | memset(&tio->info, 0, sizeof(tio->info)); | 557 | |
556 | __map_bio(ti, clone, tio); | 558 | __map_bio(ti, clone, tio); |
559 | |||
560 | ci->sector += len; | ||
561 | ci->sector_count -= len; | ||
562 | offset += to_bytes(len); | ||
563 | } while (remaining -= len); | ||
557 | 564 | ||
558 | ci->sector += len; | ||
559 | ci->sector_count -= len; | ||
560 | ci->idx++; | 565 | ci->idx++; |
561 | } | 566 | } |
562 | } | 567 | } |