fs: dlm: make F_SETLK use unkillable wait_event
authorAlexander Aring <aahringo@redhat.com>
Fri, 19 May 2023 15:21:27 +0000 (11:21 -0400)
committerDavid Teigland <teigland@redhat.com>
Tue, 23 May 2023 17:56:58 +0000 (12:56 -0500)
While a non-waiting posix lock request (F_SETLK) is waiting for
user space processing (in dlm_controld), wait for that processing
to complete with an unkillable wait_event(). This makes F_SETLK
behave the same way for F_RDLCK, F_WRLCK and F_UNLCK. F_SETLKW
continues to use wait_event_killable().

Cc: stable@vger.kernel.org
Signed-off-by: Alexander Aring <aahringo@redhat.com>
Signed-off-by: David Teigland <teigland@redhat.com>
fs/dlm/plock.c

index 31bc601..c9e1d5f 100644 (file)
@@ -155,25 +155,29 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
 
        send_op(op);
 
-       rv = wait_event_killable(recv_wq, (op->done != 0));
-       if (rv == -ERESTARTSYS) {
-               spin_lock(&ops_lock);
-               /* recheck under ops_lock if we got a done != 0,
-                * if so this interrupt case should be ignored
-                */
-               if (op->done != 0) {
+       if (op->info.wait) {
+               rv = wait_event_killable(recv_wq, (op->done != 0));
+               if (rv == -ERESTARTSYS) {
+                       spin_lock(&ops_lock);
+                       /* recheck under ops_lock if we got a done != 0,
+                        * if so this interrupt case should be ignored
+                        */
+                       if (op->done != 0) {
+                               spin_unlock(&ops_lock);
+                               goto do_lock_wait;
+                       }
+                       list_del(&op->list);
                        spin_unlock(&ops_lock);
-                       goto do_lock_wait;
-               }
-               list_del(&op->list);
-               spin_unlock(&ops_lock);
 
-               log_debug(ls, "%s: wait interrupted %x %llx pid %d",
-                         __func__, ls->ls_global_id,
-                         (unsigned long long)number, op->info.pid);
-               do_unlock_close(&op->info);
-               dlm_release_plock_op(op);
-               goto out;
+                       log_debug(ls, "%s: wait interrupted %x %llx pid %d",
+                                 __func__, ls->ls_global_id,
+                                 (unsigned long long)number, op->info.pid);
+                       do_unlock_close(&op->info);
+                       dlm_release_plock_op(op);
+                       goto out;
+               }
+       } else {
+               wait_event(recv_wq, (op->done != 0));
        }
 
 do_lock_wait: