diff options
Diffstat (limited to 'drivers/md/dm.c')
| -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 | } |
