Skip to content

Commit

Permalink
[PATCH] dm: bio split bvec fix
Browse files Browse the repository at this point in the history
The code that handles bios that span table target boundaries by breaking
them up into smaller bios will not split an individual struct bio_vec into
more than two pieces.  Sometimes more than that are required.

This patch adds a loop to break the second piece up into as many pieces as
are necessary.

Cc: "Abhishek Gupta" <abhishekgupt@gmail.com>
Cc: Dan Smith <danms@us.ibm.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Alasdair G Kergon authored and Linus Torvalds committed Mar 22, 2006
1 parent 06f9d4f commit d2044a9
Showing 1 changed file with 24 additions and 19 deletions.
43 changes: 24 additions & 19 deletions drivers/md/dm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++;
}
}
Expand Down

0 comments on commit d2044a9

Please sign in to comment.