aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r--drivers/md/dm.c21
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
626static void end_io_acct(struct dm_io *io) 626static 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