This patch removes the ls_remove_wait waitqueue handling. The current
handling tries to wait before a lookup is send out for a identically
resource name which is going to be removed. Hereby the remove message
should be send out before the new lookup message. The reason is that
after a lookup request and response will actually use the specific
remote rsb. A followed remove message would delete the rsb on the remote
side but it's still being used.

To reach a similar behaviour we simple send the remove message out while
the rsb lookup lock is held and the rsb is removed from the toss list.
Other find_rsb() calls would never have the change to get a rsb back to
live while a remove message will be send out (without holding the lock).

This behaviour requires a non-sleepable context which should be provided
now and might be the reason why it was not implemented so in the first
place.

Signed-off-by: Alexander Aring <aahri...@redhat.com>
---
 fs/dlm/dlm_internal.h |  4 ----
 fs/dlm/lock.c         | 56 ++-----------------------------------------
 fs/dlm/lockspace.c    |  3 ---
 3 files changed, 2 insertions(+), 61 deletions(-)

diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h
index 0f32c780ce2c..a2cd4f291fd5 100644
--- a/fs/dlm/dlm_internal.h
+++ b/fs/dlm/dlm_internal.h
@@ -592,11 +592,7 @@ struct dlm_ls {
        int                     ls_new_rsb_count;
        struct list_head        ls_new_rsb;     /* new rsb structs */
 
-       spinlock_t              ls_remove_spin;
-       wait_queue_head_t       ls_remove_wait;
-       char                    ls_remove_name[DLM_RESNAME_MAXLEN+1];
        char                    *ls_remove_names[DLM_REMOVE_NAMES_MAX];
-       int                     ls_remove_len;
        int                     ls_remove_lens[DLM_REMOVE_NAMES_MAX];
 
        struct list_head        ls_nodes;       /* current nodes in ls */
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index 52bdaca400f4..3454fe3971a2 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -1590,37 +1590,6 @@ static int remove_from_waiters_ms(struct dlm_lkb *lkb, 
struct dlm_message *ms)
        return error;
 }
 
-/* If there's an rsb for the same resource being removed, ensure
- * that the remove message is sent before the new lookup message.
- */
-
-#define DLM_WAIT_PENDING_COND(ls, r)           \
-       (ls->ls_remove_len &&                   \
-        !rsb_cmp(r, ls->ls_remove_name,        \
-                 ls->ls_remove_len))
-
-static void wait_pending_remove(struct dlm_rsb *r)
-{
-       struct dlm_ls *ls = r->res_ls;
- restart:
-       spin_lock(&ls->ls_remove_spin);
-       if (DLM_WAIT_PENDING_COND(ls, r)) {
-               log_debug(ls, "delay lookup for remove dir %d %s",
-                         r->res_dir_nodeid, r->res_name);
-               spin_unlock(&ls->ls_remove_spin);
-               wait_event(ls->ls_remove_wait, !DLM_WAIT_PENDING_COND(ls, r));
-               goto restart;
-       }
-       spin_unlock(&ls->ls_remove_spin);
-}
-
-/*
- * ls_remove_spin protects ls_remove_name and ls_remove_len which are
- * read by other threads in wait_pending_remove.  ls_remove_names
- * and ls_remove_lens are only used by the scan thread, so they do
- * not need protection.
- */
-
 static void shrink_bucket(struct dlm_ls *ls, int b)
 {
        struct rb_node *n, *next;
@@ -1702,11 +1671,6 @@ static void shrink_bucket(struct dlm_ls *ls, int b)
         * list and sending the removal.  Keeping this gap small is
         * important to keep us (the master node) from being out of sync
         * with the remote dir node for very long.
-        *
-        * From the time the rsb is removed from toss until just after
-        * send_remove, the rsb name is saved in ls_remove_name.  A new
-        * lookup checks this to ensure that a new lookup message for the
-        * same resource name is not sent just before the remove message.
         */
 
        for (i = 0; i < remote_count; i++) {
@@ -1753,22 +1717,8 @@ static void shrink_bucket(struct dlm_ls *ls, int b)
                }
 
                rb_erase(&r->res_hashnode, &ls->ls_rsbtbl[b].toss);
-
-               /* block lookup of same name until we've sent remove */
-               spin_lock(&ls->ls_remove_spin);
-               ls->ls_remove_len = len;
-               memcpy(ls->ls_remove_name, name, DLM_RESNAME_MAXLEN);
-               spin_unlock(&ls->ls_remove_spin);
-               spin_unlock(&ls->ls_rsbtbl[b].lock);
-
                send_remove(r);
-
-               /* allow lookup of name again */
-               spin_lock(&ls->ls_remove_spin);
-               ls->ls_remove_len = 0;
-               memset(ls->ls_remove_name, 0, DLM_RESNAME_MAXLEN);
-               spin_unlock(&ls->ls_remove_spin);
-               wake_up(&ls->ls_remove_wait);
+               spin_unlock(&ls->ls_rsbtbl[b].lock);
 
                dlm_free_rsb(r);
        }
@@ -2719,8 +2669,6 @@ static int set_master(struct dlm_rsb *r, struct dlm_lkb 
*lkb)
                return 0;
        }
 
-       wait_pending_remove(r);
-
        r->res_first_lkid = lkb->lkb_id;
        send_lookup(r, lkb);
        return 1;
@@ -3814,7 +3762,7 @@ static int send_remove(struct dlm_rsb *r)
        to_nodeid = dlm_dir_nodeid(r);
 
        error = create_message(r, NULL, to_nodeid, DLM_MSG_REMOVE, &ms, &mh,
-                              GFP_NOFS);
+                              GFP_ATOMIC);
        if (error)
                goto out;
 
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
index 72fa8a9d7a40..c438b909f221 100644
--- a/fs/dlm/lockspace.c
+++ b/fs/dlm/lockspace.c
@@ -524,9 +524,6 @@ static int new_lockspace(const char *name, const char 
*cluster,
                spin_lock_init(&ls->ls_rsbtbl[i].lock);
        }
 
-       spin_lock_init(&ls->ls_remove_spin);
-       init_waitqueue_head(&ls->ls_remove_wait);
-
        for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++) {
                ls->ls_remove_names[i] = kzalloc(DLM_RESNAME_MAXLEN+1,
                                                 GFP_KERNEL);
-- 
2.31.1

Reply via email to