diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-23 23:44:19 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-23 23:44:19 -0500 |
commit | 1ebbe2b20091d306453a5cf480a87e6cd28ae76f (patch) | |
tree | f5cd7a0fa69b8b1938cb5a0faed2e7b0628072a5 /drivers/md | |
parent | ac58c9059da8886b5e8cde012a80266b18ca146e (diff) | |
parent | 674a396c6d2ba0341ebdd7c1c9950f32f018e2dd (diff) |
Merge branch 'linus'
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm.c | 56 |
1 files changed, 36 insertions, 20 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 88d60202b9db..8c82373f7ff3 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/mempool.h> | 17 | #include <linux/mempool.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/idr.h> | 19 | #include <linux/idr.h> |
20 | #include <linux/blktrace_api.h> | ||
20 | 21 | ||
21 | static const char *_name = DM_NAME; | 22 | static const char *_name = DM_NAME; |
22 | 23 | ||
@@ -334,6 +335,8 @@ static void dec_pending(struct dm_io *io, int error) | |||
334 | /* nudge anyone waiting on suspend queue */ | 335 | /* nudge anyone waiting on suspend queue */ |
335 | wake_up(&io->md->wait); | 336 | wake_up(&io->md->wait); |
336 | 337 | ||
338 | blk_add_trace_bio(io->md->queue, io->bio, BLK_TA_COMPLETE); | ||
339 | |||
337 | bio_endio(io->bio, io->bio->bi_size, io->error); | 340 | bio_endio(io->bio, io->bio->bi_size, io->error); |
338 | free_io(io->md, io); | 341 | free_io(io->md, io); |
339 | } | 342 | } |
@@ -392,6 +395,7 @@ static void __map_bio(struct dm_target *ti, struct bio *clone, | |||
392 | struct target_io *tio) | 395 | struct target_io *tio) |
393 | { | 396 | { |
394 | int r; | 397 | int r; |
398 | sector_t sector; | ||
395 | 399 | ||
396 | /* | 400 | /* |
397 | * Sanity checks. | 401 | * Sanity checks. |
@@ -407,10 +411,17 @@ static void __map_bio(struct dm_target *ti, struct bio *clone, | |||
407 | * this io. | 411 | * this io. |
408 | */ | 412 | */ |
409 | atomic_inc(&tio->io->io_count); | 413 | atomic_inc(&tio->io->io_count); |
414 | sector = clone->bi_sector; | ||
410 | r = ti->type->map(ti, clone, &tio->info); | 415 | r = ti->type->map(ti, clone, &tio->info); |
411 | if (r > 0) | 416 | if (r > 0) { |
412 | /* the bio has been remapped so dispatch it */ | 417 | /* the bio has been remapped so dispatch it */ |
418 | |||
419 | blk_add_trace_remap(bdev_get_queue(clone->bi_bdev), clone, | ||
420 | tio->io->bio->bi_bdev->bd_dev, sector, | ||
421 | clone->bi_sector); | ||
422 | |||
413 | generic_make_request(clone); | 423 | generic_make_request(clone); |
424 | } | ||
414 | 425 | ||
415 | else if (r < 0) { | 426 | else if (r < 0) { |
416 | /* error the io and bail out */ | 427 | /* error the io and bail out */ |
@@ -533,30 +544,35 @@ static void __clone_and_map(struct clone_info *ci) | |||
533 | 544 | ||
534 | } else { | 545 | } else { |
535 | /* | 546 | /* |
536 | * Create two copy bios to deal with io that has | 547 | * Handle a bvec that must be split between two or more targets. |
537 | * been split across a target. | ||
538 | */ | 548 | */ |
539 | struct bio_vec *bv = bio->bi_io_vec + ci->idx; | 549 | struct bio_vec *bv = bio->bi_io_vec + ci->idx; |
550 | sector_t remaining = to_sector(bv->bv_len); | ||
551 | unsigned int offset = 0; | ||
540 | 552 | ||
541 | clone = split_bvec(bio, ci->sector, ci->idx, | 553 | do { |
542 | bv->bv_offset, max); | 554 | if (offset) { |
543 | __map_bio(ti, clone, tio); | 555 | ti = dm_table_find_target(ci->map, ci->sector); |
556 | max = max_io_len(ci->md, ci->sector, ti); | ||
544 | 557 | ||
545 | ci->sector += max; | 558 | tio = alloc_tio(ci->md); |
546 | ci->sector_count -= max; | 559 | tio->io = ci->io; |
547 | ti = dm_table_find_target(ci->map, ci->sector); | 560 | tio->ti = ti; |
548 | 561 | memset(&tio->info, 0, sizeof(tio->info)); | |
549 | len = to_sector(bv->bv_len) - max; | 562 | } |
550 | clone = split_bvec(bio, ci->sector, ci->idx, | 563 | |
551 | bv->bv_offset + to_bytes(max), len); | 564 | len = min(remaining, max); |
552 | tio = alloc_tio(ci->md); | 565 | |
553 | tio->io = ci->io; | 566 | clone = split_bvec(bio, ci->sector, ci->idx, |
554 | tio->ti = ti; | 567 | bv->bv_offset + offset, len); |
555 | memset(&tio->info, 0, sizeof(tio->info)); | 568 | |
556 | __map_bio(ti, clone, tio); | 569 | __map_bio(ti, clone, tio); |
570 | |||
571 | ci->sector += len; | ||
572 | ci->sector_count -= len; | ||
573 | offset += to_bytes(len); | ||
574 | } while (remaining -= len); | ||
557 | 575 | ||
558 | ci->sector += len; | ||
559 | ci->sector_count -= len; | ||
560 | ci->idx++; | 576 | ci->idx++; |
561 | } | 577 | } |
562 | } | 578 | } |