提交 c518d04f 编写于 作者: L Lars Ellenberg 提交者: Philipp Reisner

drbd: fix race between deconfiguring and reconfiguring network

If a drbd_nl_net_conf hits the small window between the state change
to C_STANDALONE and the corresponding cleanup in after_state_ch,
that cleanup would throw away stuff we now need again,
and later trigger BUG_ON()s.

Fixed by properly serializing the new config request with
any pending cleanup.
Signed-off-by: NPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: NLars Ellenberg <lars.ellenberg@linbit.com>
上级 0778286a
...@@ -750,14 +750,16 @@ void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_seg_s) __mu ...@@ -750,14 +750,16 @@ void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_seg_s) __mu
/* serialize deconfig (worker exiting, doing cleanup) /* serialize deconfig (worker exiting, doing cleanup)
* and reconfig (drbdsetup disk, drbdsetup net) * and reconfig (drbdsetup disk, drbdsetup net)
* *
* wait for a potentially exiting worker, then restart it, * Wait for a potentially exiting worker, then restart it,
* or start a new one. * or start a new one. Flush any pending work, there may still be an
* after_state_change queued.
*/ */
static void drbd_reconfig_start(struct drbd_conf *mdev) static void drbd_reconfig_start(struct drbd_conf *mdev)
{ {
wait_event(mdev->state_wait, !test_and_set_bit(CONFIG_PENDING, &mdev->flags)); wait_event(mdev->state_wait, !test_and_set_bit(CONFIG_PENDING, &mdev->flags));
wait_event(mdev->state_wait, !test_bit(DEVICE_DYING, &mdev->flags)); wait_event(mdev->state_wait, !test_bit(DEVICE_DYING, &mdev->flags));
drbd_thread_start(&mdev->worker); drbd_thread_start(&mdev->worker);
drbd_flush_workqueue(mdev);
} }
/* if still unconfigured, stops worker again. /* if still unconfigured, stops worker again.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册