提交 eb448735 编写于 作者: Y Yu Kuai 提交者: Jialin Zhang

md: refactor action_store() for 'idle' and 'frozen'

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6OMCC
CVE: NA

--------------------------------

Prepare to handle 'idle' and 'frozen' differently to fix a deadlock, there
are no functional changes except that MD_RECOVERY_RUNNING is checked
again after 'reconfig_mutex' is held.
Signed-off-by: NYu Kuai <yukuai3@huawei.com>
Reviewed-by: NHou Tao <houtao1@huawei.com>
Signed-off-by: NJialin Zhang <zhangjialin11@huawei.com>
上级 f9483d2a
...@@ -4855,6 +4855,46 @@ action_show(struct mddev *mddev, char *page) ...@@ -4855,6 +4855,46 @@ action_show(struct mddev *mddev, char *page)
return sprintf(page, "%s\n", type); return sprintf(page, "%s\n", type);
} }
static void stop_sync_thread(struct mddev *mddev)
{
if (!test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
return;
if (mddev_lock(mddev))
return;
/*
* Check again in case MD_RECOVERY_RUNNING is cleared before lock is
* held.
*/
if (!test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) {
mddev_unlock(mddev);
return;
}
if (work_pending(&mddev->del_work))
flush_workqueue(md_misc_wq);
if (mddev->sync_thread) {
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
md_reap_sync_thread(mddev);
}
mddev_unlock(mddev);
}
static void idle_sync_thread(struct mddev *mddev)
{
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
stop_sync_thread(mddev);
}
static void frozen_sync_thread(struct mddev *mddev)
{
set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
stop_sync_thread(mddev);
}
static ssize_t static ssize_t
action_store(struct mddev *mddev, const char *page, size_t len) action_store(struct mddev *mddev, const char *page, size_t len)
{ {
...@@ -4862,22 +4902,11 @@ action_store(struct mddev *mddev, const char *page, size_t len) ...@@ -4862,22 +4902,11 @@ action_store(struct mddev *mddev, const char *page, size_t len)
return -EINVAL; return -EINVAL;
if (cmd_match(page, "idle") || cmd_match(page, "frozen")) { if (cmd_match(page, "idle"))
if (cmd_match(page, "frozen")) idle_sync_thread(mddev);
set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); else if (cmd_match(page, "frozen"))
else frozen_sync_thread(mddev);
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) &&
mddev_lock(mddev) == 0) {
if (work_pending(&mddev->del_work))
flush_workqueue(md_misc_wq);
if (mddev->sync_thread) {
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
md_reap_sync_thread(mddev);
}
mddev_unlock(mddev);
}
} else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
return -EBUSY; return -EBUSY;
else if (cmd_match(page, "resync")) else if (cmd_match(page, "resync"))
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册