mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 00:34:20 +08:00
md/dm-raid: don't call md_reap_sync_thread() directly
[ Upstream commitcd32b27a66
] 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, commit130443d60b
("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:be83651f00
("DM RAID: Add message/status support for changing sync action") Cc: stable@vger.kernel.org # v6.7+ Signed-off-by: Yu Kuai <yukuai3@huawei.com> Signed-off-by: Xiao Ni <xni@redhat.com> Acked-by: Mike Snitzer <snitzer@kernel.org> Signed-off-by: Song Liu <song@kernel.org> Link: https://lore.kernel.org/r/20240305072306.2562024-7-yukuai1@huaweicloud.com Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
eaa8fc9b09
commit
9e59b8d76f
@ -3719,6 +3719,7 @@ static int raid_message(struct dm_target *ti, unsigned int argc, char **argv,
|
||||
{
|
||||
struct raid_set *rs = ti->private;
|
||||
struct mddev *mddev = &rs->md;
|
||||
int ret = 0;
|
||||
|
||||
if (!mddev->pers || !mddev->pers->sync_request)
|
||||
return -EINVAL;
|
||||
@ -3726,17 +3727,24 @@ static int raid_message(struct dm_target *ti, unsigned int argc, char **argv,
|
||||
if (test_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags))
|
||||
return -EBUSY;
|
||||
|
||||
if (!strcasecmp(argv[0], "frozen"))
|
||||
set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
|
||||
else
|
||||
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
|
||||
if (!strcasecmp(argv[0], "frozen")) {
|
||||
ret = mddev_lock(mddev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!strcasecmp(argv[0], "idle") || !strcasecmp(argv[0], "frozen")) {
|
||||
if (mddev->sync_thread) {
|
||||
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
|
||||
md_reap_sync_thread(mddev);
|
||||
}
|
||||
} else if (decipher_sync_action(mddev, mddev->recovery) != st_idle)
|
||||
md_frozen_sync_thread(mddev);
|
||||
mddev_unlock(mddev);
|
||||
} else if (!strcasecmp(argv[0], "idle")) {
|
||||
ret = mddev_lock(mddev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
md_idle_sync_thread(mddev);
|
||||
mddev_unlock(mddev);
|
||||
}
|
||||
|
||||
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
|
||||
if (decipher_sync_action(mddev, mddev->recovery) != st_idle)
|
||||
return -EBUSY;
|
||||
else if (!strcasecmp(argv[0], "resync"))
|
||||
; /* MD_RECOVERY_NEEDED set below */
|
||||
|
Loading…
Reference in New Issue
Block a user