diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 07d2949a87464a2d7efb008276530797bcd7efed..7b3d048a28560437ae431a1a38eeb7e98013f47c 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1622,9 +1622,23 @@ static blk_qc_t __split_and_process_bio(struct mapped_device *md, * the usage of io->orig_bio in dm_remap_zone_report() * won't be affected by this reassignment. */ + int cpu; struct bio *b = bio_split(bio, bio_sectors(bio) - ci.sector_count, GFP_NOIO, &md->queue->bio_split); ci.io->orig_bio = b; + + /* + * Adjust IO stats for each split, otherwise upon queue + * reentry there will be redundant IO accounting. + * NOTE: this is a stop-gap fix, a proper fix involves + * significant refactoring of DM core's bio splitting + * (by eliminating DM's splitting and just using bio_split) + */ + cpu = part_stat_lock(); + __part_stat_add(cpu, &dm_disk(md)->part0, + sectors[op_stat_group(bio_op(bio))], -(ci.sector_count)); + part_stat_unlock(); + bio_chain(b, bio); ret = generic_make_request(bio); break;