aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm.c56
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
21static const char *_name = DM_NAME; 22static 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}