From c23e1cd19b200f40df955a828422f46848c4f74b Mon Sep 17 00:00:00 2001 From: Li Nan Date: Sat, 3 Jun 2023 14:50:46 +0800 Subject: [PATCH] md/raid10: fix io hung in md_wait_for_blocked_rdev() hulk inclusion category: bugfix bugzilla: 188569, https://gitee.com/openeuler/kernel/issues/I6XBZQ CVE: NA -------------------------------- If badblocks are merged but bb->count exceedded, badblocks_set() will return 1 and merged badblocks will become un-ack. rdev_set_badblocks() will not set sb_flags and wakeup mddev->thread, io wait in md_wait_for_blocked_rdev() will hung because BlockedBadBlocks may not be cleared. Fix it by checking badblocks->changed instead of return value. This flag is set when badblocks changes. Signed-off-by: Li Nan Reviewed-by: Yu Kuai Reviewed-by: Hou Tao --- drivers/md/md.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 4d744cf8ffc6..f50e0255f3f8 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -9577,13 +9577,13 @@ int rdev_set_badblocks(struct md_rdev *rdev, sector_t s, int sectors, int is_new) { struct mddev *mddev = rdev->mddev; - int rv; + if (is_new) s += rdev->new_data_offset; else s += rdev->data_offset; - rv = badblocks_set(&rdev->badblocks, s, sectors, 0); - if (rv == 0) { + badblocks_set(&rdev->badblocks, s, sectors, 0); + if (rdev->badblocks.changed) { /* Make sure they get written out promptly */ if (test_bit(ExternalBbl, &rdev->flags)) sysfs_notify_dirent_safe(rdev->sysfs_unack_badblocks); -- GitLab