Skip to content

Commit cd32b27

Browse files
YuKuai-huaweiliu-song-6
authored andcommitted
md/dm-raid: don't call md_reap_sync_thread() directly
Currently md_reap_sync_thread() is called from raid_message() directly without holding 'reconfig_mutex', this is definitely unsafe because md_reap_sync_thread() can change many fields that is protected by 'reconfig_mutex'. However, hold 'reconfig_mutex' here is still problematic because this will cause deadlock, for example, commit 130443d ("md: refactor idle/frozen_sync_thread() to fix deadlock"). Fix this problem by using stop_sync_thread() to unregister sync_thread, like md/raid did. Fixes: be83651 ("DM RAID: Add message/status support for changing sync action") Cc: [email protected] # v6.7+ Signed-off-by: Yu Kuai <[email protected]> Signed-off-by: Xiao Ni <[email protected]> Acked-by: Mike Snitzer <[email protected]> Signed-off-by: Song Liu <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 16c4770 commit cd32b27

File tree

1 file changed

+18
-10
lines changed

1 file changed

+18
-10
lines changed

drivers/md/dm-raid.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3719,24 +3719,32 @@ static int raid_message(struct dm_target *ti, unsigned int argc, char **argv,
37193719
{
37203720
struct raid_set *rs = ti->private;
37213721
struct mddev *mddev = &rs->md;
3722+
int ret = 0;
37223723

37233724
if (!mddev->pers || !mddev->pers->sync_request)
37243725
return -EINVAL;
37253726

37263727
if (test_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags))
37273728
return -EBUSY;
37283729

3729-
if (!strcasecmp(argv[0], "frozen"))
3730-
set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
3731-
else
3732-
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
3730+
if (!strcasecmp(argv[0], "frozen")) {
3731+
ret = mddev_lock(mddev);
3732+
if (ret)
3733+
return ret;
37333734

3734-
if (!strcasecmp(argv[0], "idle") || !strcasecmp(argv[0], "frozen")) {
3735-
if (mddev->sync_thread) {
3736-
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
3737-
md_reap_sync_thread(mddev);
3738-
}
3739-
} else if (decipher_sync_action(mddev, mddev->recovery) != st_idle)
3735+
md_frozen_sync_thread(mddev);
3736+
mddev_unlock(mddev);
3737+
} else if (!strcasecmp(argv[0], "idle")) {
3738+
ret = mddev_lock(mddev);
3739+
if (ret)
3740+
return ret;
3741+
3742+
md_idle_sync_thread(mddev);
3743+
mddev_unlock(mddev);
3744+
}
3745+
3746+
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
3747+
if (decipher_sync_action(mddev, mddev->recovery) != st_idle)
37403748
return -EBUSY;
37413749
else if (!strcasecmp(argv[0], "resync"))
37423750
; /* MD_RECOVERY_NEEDED set below */

0 commit comments

Comments
 (0)