Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

raid5: fix missing io accounting in raid5_align_endio()

Io will only be accounted as done from raid5_align_endio() if the io
succeeded, and io inflight counter will be leaked if such io failed.

Fix this problem by switching to use md_account_bio() for io accounting.

Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Reviewed-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Song Liu <song@kernel.org>
Link: https://lore.kernel.org/r/20230621165110.1498313-4-yukuai1@huaweicloud.com

authored by

Yu Kuai and committed by
Song Liu
05048cbc c687297b

+8 -21
+8 -21
drivers/md/raid5.c
··· 5468 5468 */ 5469 5469 static void raid5_align_endio(struct bio *bi) 5470 5470 { 5471 - struct md_io_clone *md_io_clone = bi->bi_private; 5472 - struct bio *raid_bi = md_io_clone->orig_bio; 5473 - struct mddev *mddev; 5474 - struct r5conf *conf; 5475 - struct md_rdev *rdev; 5471 + struct bio *raid_bi = bi->bi_private; 5472 + struct md_rdev *rdev = (void *)raid_bi->bi_next; 5473 + struct mddev *mddev = rdev->mddev; 5474 + struct r5conf *conf = mddev->private; 5476 5475 blk_status_t error = bi->bi_status; 5477 - unsigned long start_time = md_io_clone->start_time; 5478 5476 5479 5477 bio_put(bi); 5480 - 5481 - rdev = (void*)raid_bi->bi_next; 5482 5478 raid_bi->bi_next = NULL; 5483 - mddev = rdev->mddev; 5484 - conf = mddev->private; 5485 - 5486 5479 rdev_dec_pending(rdev, conf->mddev); 5487 5480 5488 5481 if (!error) { 5489 - if (blk_queue_io_stat(raid_bi->bi_bdev->bd_disk->queue)) 5490 - bio_end_io_acct(raid_bi, start_time); 5491 5482 bio_endio(raid_bi); 5492 5483 if (atomic_dec_and_test(&conf->active_aligned_reads)) 5493 5484 wake_up(&conf->wait_for_quiescent); ··· 5497 5506 struct md_rdev *rdev; 5498 5507 sector_t sector, end_sector, first_bad; 5499 5508 int bad_sectors, dd_idx; 5500 - struct md_io_clone *md_io_clone; 5501 5509 bool did_inc; 5502 5510 5503 5511 if (!in_chunk_boundary(mddev, raid_bio)) { ··· 5533 5543 return 0; 5534 5544 } 5535 5545 5536 - align_bio = bio_alloc_clone(rdev->bdev, raid_bio, GFP_NOIO, 5537 - &mddev->io_clone_set); 5538 - md_io_clone = container_of(align_bio, struct md_io_clone, bio_clone); 5546 + md_account_bio(mddev, &raid_bio); 5539 5547 raid_bio->bi_next = (void *)rdev; 5540 - if (blk_queue_io_stat(raid_bio->bi_bdev->bd_disk->queue)) 5541 - md_io_clone->start_time = bio_start_io_acct(raid_bio); 5542 - md_io_clone->orig_bio = raid_bio; 5543 5548 5549 + align_bio = bio_alloc_clone(rdev->bdev, raid_bio, GFP_NOIO, 5550 + &mddev->bio_set); 5544 5551 align_bio->bi_end_io = raid5_align_endio; 5545 - align_bio->bi_private = md_io_clone; 5552 + align_bio->bi_private = raid_bio; 5546 5553 align_bio->bi_iter.bi_sector = sector; 5547 5554 5548 5555 /* No reshape active, so we can trust rdev->data_offset */