diff options
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r-- | drivers/md/dm.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 1116097bd780..38f26941c7a1 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -517,7 +517,7 @@ static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode, | |||
517 | * subset of the parent bdev; require extra privileges. | 517 | * subset of the parent bdev; require extra privileges. |
518 | */ | 518 | */ |
519 | if (!capable(CAP_SYS_RAWIO)) { | 519 | if (!capable(CAP_SYS_RAWIO)) { |
520 | DMWARN_LIMIT( | 520 | DMDEBUG_LIMIT( |
521 | "%s: sending ioctl %x to DM device without required privilege.", | 521 | "%s: sending ioctl %x to DM device without required privilege.", |
522 | current->comm, cmd); | 522 | current->comm, cmd); |
523 | r = -ENOIOCTLCMD; | 523 | r = -ENOIOCTLCMD; |
@@ -623,21 +623,20 @@ static void start_io_acct(struct dm_io *io) | |||
623 | false, 0, &io->stats_aux); | 623 | false, 0, &io->stats_aux); |
624 | } | 624 | } |
625 | 625 | ||
626 | static void end_io_acct(struct dm_io *io) | 626 | static void end_io_acct(struct mapped_device *md, struct bio *bio, |
627 | unsigned long start_time, struct dm_stats_aux *stats_aux) | ||
627 | { | 628 | { |
628 | struct mapped_device *md = io->md; | 629 | unsigned long duration = jiffies - start_time; |
629 | struct bio *bio = io->orig_bio; | ||
630 | unsigned long duration = jiffies - io->start_time; | ||
631 | int pending; | 630 | int pending; |
632 | int rw = bio_data_dir(bio); | 631 | int rw = bio_data_dir(bio); |
633 | 632 | ||
634 | generic_end_io_acct(md->queue, bio_op(bio), &dm_disk(md)->part0, | 633 | generic_end_io_acct(md->queue, bio_op(bio), &dm_disk(md)->part0, |
635 | io->start_time); | 634 | start_time); |
636 | 635 | ||
637 | if (unlikely(dm_stats_used(&md->stats))) | 636 | if (unlikely(dm_stats_used(&md->stats))) |
638 | dm_stats_account_io(&md->stats, bio_data_dir(bio), | 637 | dm_stats_account_io(&md->stats, bio_data_dir(bio), |
639 | bio->bi_iter.bi_sector, bio_sectors(bio), | 638 | bio->bi_iter.bi_sector, bio_sectors(bio), |
640 | true, duration, &io->stats_aux); | 639 | true, duration, stats_aux); |
641 | 640 | ||
642 | /* | 641 | /* |
643 | * After this is decremented the bio must not be touched if it is | 642 | * After this is decremented the bio must not be touched if it is |
@@ -864,6 +863,8 @@ static void dec_pending(struct dm_io *io, blk_status_t error) | |||
864 | blk_status_t io_error; | 863 | blk_status_t io_error; |
865 | struct bio *bio; | 864 | struct bio *bio; |
866 | struct mapped_device *md = io->md; | 865 | struct mapped_device *md = io->md; |
866 | unsigned long start_time = 0; | ||
867 | struct dm_stats_aux stats_aux; | ||
867 | 868 | ||
868 | /* Push-back supersedes any I/O errors */ | 869 | /* Push-back supersedes any I/O errors */ |
869 | if (unlikely(error)) { | 870 | if (unlikely(error)) { |
@@ -890,8 +891,10 @@ static void dec_pending(struct dm_io *io, blk_status_t error) | |||
890 | 891 | ||
891 | io_error = io->status; | 892 | io_error = io->status; |
892 | bio = io->orig_bio; | 893 | bio = io->orig_bio; |
893 | end_io_acct(io); | 894 | start_time = io->start_time; |
895 | stats_aux = io->stats_aux; | ||
894 | free_io(md, io); | 896 | free_io(md, io); |
897 | end_io_acct(md, bio, start_time, &stats_aux); | ||
895 | 898 | ||
896 | if (io_error == BLK_STS_DM_REQUEUE) | 899 | if (io_error == BLK_STS_DM_REQUEUE) |
897 | return; | 900 | return; |
@@ -2589,6 +2592,8 @@ static int dm_wait_for_completion(struct mapped_device *md, long task_state) | |||
2589 | } | 2592 | } |
2590 | finish_wait(&md->wait, &wait); | 2593 | finish_wait(&md->wait, &wait); |
2591 | 2594 | ||
2595 | smp_rmb(); /* paired with atomic_dec_return in end_io_acct */ | ||
2596 | |||
2592 | return r; | 2597 | return r; |
2593 | } | 2598 | } |
2594 | 2599 | ||