diff options
| author | Jeff Garzik <jeff@garzik.org> | 2006-03-22 19:13:54 -0500 |
|---|---|---|
| committer | Jeff Garzik <jeff@garzik.org> | 2006-03-22 19:13:54 -0500 |
| commit | f01c18456993bab43067b678f56c87ca954aa43b (patch) | |
| tree | 3e0cd0cdf1a57618202b46a7126125902e3ab832 /drivers/md/dm.c | |
| parent | 949ec2c8e6b7b89179b85baf6309c009e1a1b951 (diff) | |
| parent | 1c2e02750b992703a8a18634e08b04353face243 (diff) | |
Merge branch 'master'
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) } else { /* - * Create two copy bios to deal with io that has - * been split across a target. + * Handle a bvec that must be split between two or more targets. */ struct bio_vec *bv = bio->bi_io_vec + ci->idx; + sector_t remaining = to_sector(bv->bv_len); + unsigned int offset = 0; - clone = split_bvec(bio, ci->sector, ci->idx, - bv->bv_offset, max); - __map_bio(ti, clone, tio); + do { + if (offset) { + ti = dm_table_find_target(ci->map, ci->sector); + max = max_io_len(ci->md, ci->sector, ti); - ci->sector += max; - ci->sector_count -= max; - ti = dm_table_find_target(ci->map, ci->sector); - - len = to_sector(bv->bv_len) - max; - clone = split_bvec(bio, ci->sector, ci->idx, - bv->bv_offset + to_bytes(max), len); - tio = alloc_tio(ci->md); - tio->io = ci->io; - tio->ti = ti; - memset(&tio->info, 0, sizeof(tio->info)); - __map_bio(ti, clone, tio); + tio = alloc_tio(ci->md); + tio->io = ci->io; + tio->ti = ti; + memset(&tio->info, 0, sizeof(tio->info)); + } + + len = min(remaining, max); + + clone = split_bvec(bio, ci->sector, ci->idx, + bv->bv_offset + offset, len); + + __map_bio(ti, clone, tio); + + ci->sector += len; + ci->sector_count -= len; + offset += to_bytes(len); + } while (remaining -= len); - ci->sector += len; - ci->sector_count -= len; ci->idx++; } } |
