Skip to content

Commit 26208a7

Browse files
YuKuai-huaweiliu-song-6
authored andcommitted
md/raid10: fix leak of 'r10bio->remaining' for recovery
raid10_sync_request() will add 'r10bio->remaining' for both rdev and replacement rdev. However, if the read io fails, recovery_request_write() returns without issuing the write io, in this case, end_sync_request() is only called once and 'remaining' is leaked, cause an io hang. Fix the problem by decreasing 'remaining' according to if 'bio' and 'repl_bio' is valid. Fixes: 24afd80 ("md/raid10: handle recovery of replacement devices.") Signed-off-by: Yu Kuai <yukuai3@huawei.com> Signed-off-by: Song Liu <song@kernel.org> Link: https://lore.kernel.org/r/20230310073855.1337560-5-yukuai1@huaweicloud.com
1 parent 9fdfe6d commit 26208a7

1 file changed

Lines changed: 13 additions & 10 deletions

File tree

drivers/md/raid10.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2615,11 +2615,22 @@ static void recovery_request_write(struct mddev *mddev, struct r10bio *r10_bio)
26152615
{
26162616
struct r10conf *conf = mddev->private;
26172617
int d;
2618-
struct bio *wbio, *wbio2;
2618+
struct bio *wbio = r10_bio->devs[1].bio;
2619+
struct bio *wbio2 = r10_bio->devs[1].repl_bio;
2620+
2621+
/* Need to test wbio2->bi_end_io before we call
2622+
* submit_bio_noacct as if the former is NULL,
2623+
* the latter is free to free wbio2.
2624+
*/
2625+
if (wbio2 && !wbio2->bi_end_io)
2626+
wbio2 = NULL;
26192627

26202628
if (!test_bit(R10BIO_Uptodate, &r10_bio->state)) {
26212629
fix_recovery_read_error(r10_bio);
2622-
end_sync_request(r10_bio);
2630+
if (wbio->bi_end_io)
2631+
end_sync_request(r10_bio);
2632+
if (wbio2)
2633+
end_sync_request(r10_bio);
26232634
return;
26242635
}
26252636

@@ -2628,14 +2639,6 @@ static void recovery_request_write(struct mddev *mddev, struct r10bio *r10_bio)
26282639
* and submit the write request
26292640
*/
26302641
d = r10_bio->devs[1].devnum;
2631-
wbio = r10_bio->devs[1].bio;
2632-
wbio2 = r10_bio->devs[1].repl_bio;
2633-
/* Need to test wbio2->bi_end_io before we call
2634-
* submit_bio_noacct as if the former is NULL,
2635-
* the latter is free to free wbio2.
2636-
*/
2637-
if (wbio2 && !wbio2->bi_end_io)
2638-
wbio2 = NULL;
26392642
if (wbio->bi_end_io) {
26402643
atomic_inc(&conf->mirrors[d].rdev->nr_pending);
26412644
md_sync_acct(conf->mirrors[d].rdev->bdev, bio_sectors(wbio));

0 commit comments

Comments
 (0)