fs: dlm: fix cleanup pending ops when interrupted
authorAlexander Aring <aahringo@redhat.com>
Fri, 19 May 2023 15:21:25 +0000 (11:21 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 23 Jul 2023 11:49:38 +0000 (13:49 +0200)
commit c847f4e203046a2c93d8a1cf0348315c0b655a60 upstream.

Immediately clean up a posix lock request if it is interrupted
while waiting for a result from user space (dlm_controld.)  This
largely reverts the recent commit b92a4e3f86b1 ("fs: dlm: change
posix lock sigint handling"). That previous commit attempted
to defer lock cleanup to the point in time when a result from
user space arrived. The deferred approach was not reliable
because some dlm plock ops may not receive replies.

Cc: stable@vger.kernel.org
Fixes: b92a4e3f86b1 ("fs: dlm: change posix lock sigint handling")
Signed-off-by: Alexander Aring <aahringo@redhat.com>
Signed-off-by: David Teigland <teigland@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/dlm/plock.c

index b2d3f52..d6196ab 100644 (file)
@@ -29,8 +29,6 @@ struct plock_async_data {
 struct plock_op {
        struct list_head list;
        int done;
-       /* if lock op got interrupted while waiting dlm_controld reply */
-       bool sigint;
        struct dlm_plock_info info;
        /* if set indicates async handling */
        struct plock_async_data *data;
@@ -166,12 +164,14 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
                        spin_unlock(&ops_lock);
                        goto do_lock_wait;
                }
-
-               op->sigint = true;
+               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;
        }
 
@@ -433,19 +433,6 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
                if (iter->info.fsid == info.fsid &&
                    iter->info.number == info.number &&
                    iter->info.owner == info.owner) {
-                       if (iter->sigint) {
-                               list_del(&iter->list);
-                               spin_unlock(&ops_lock);
-
-                               pr_debug("%s: sigint cleanup %x %llx pid %d",
-                                         __func__, iter->info.fsid,
-                                         (unsigned long long)iter->info.number,
-                                         iter->info.pid);
-                               do_unlock_close(&iter->info);
-                               memcpy(&iter->info, &info, sizeof(info));
-                               dlm_release_plock_op(iter);
-                               return count;
-                       }
                        list_del_init(&iter->list);
                        memcpy(&iter->info, &info, sizeof(info));
                        if (iter->data)
@@ -464,8 +451,8 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
                else
                        wake_up(&recv_wq);
        } else
-               log_print("%s: no op %x %llx", __func__,
-                         info.fsid, (unsigned long long)info.number);
+               pr_debug("%s: no op %x %llx", __func__,
+                        info.fsid, (unsigned long long)info.number);
        return count;
 }