DLM: fix race condition between dlm_recoverd_stop and dlm_recoverd
authortsutomu.owa@toshiba.co.jp <tsutomu.owa@toshiba.co.jp>
Tue, 12 Sep 2017 08:56:30 +0000 (08:56 +0000)
committerDavid Teigland <teigland@redhat.com>
Mon, 25 Sep 2017 17:45:21 +0000 (12:45 -0500)
When dlm_recoverd_stop() is called between kthread_should_stop() and
set_task_state(TASK_INTERRUPTIBLE), dlm_recoverd will not wake up.

Signed-off-by: Tadashi Miyauchi <miyauchi@toshiba-tops.co.jp>
Signed-off-by: Tsutomu Owa <tsutomu.owa@toshiba.co.jp>
Signed-off-by: David Teigland <teigland@redhat.com>
fs/dlm/recoverd.c

index 6859b4bf971ece075e6bee500e036807be88854f..d2ad1cab0f0559f400ebb8d8836c1a762e562320 100644 (file)
@@ -287,8 +287,17 @@ static int dlm_recoverd(void *arg)
        set_bit(LSFL_RECOVER_LOCK, &ls->ls_flags);
        wake_up(&ls->ls_recover_lock_wait);
 
-       while (!kthread_should_stop()) {
+       while (1) {
+               /*
+                * We call kthread_should_stop() after set_current_state().
+                * This is because it works correctly if kthread_stop() is
+                * called just before set_current_state().
+                */
                set_current_state(TASK_INTERRUPTIBLE);
+               if (kthread_should_stop()) {
+                       set_current_state(TASK_RUNNING);
+                       break;
+               }
                if (!test_bit(LSFL_RECOVER_WORK, &ls->ls_flags) &&
                    !test_bit(LSFL_RECOVER_DOWN, &ls->ls_flags))
                        schedule();