ocfs2: purge lockres' sooner
authorKurt Hackel <kurt.hackel@oracle.com>
Mon, 1 May 2006 18:16:45 +0000 (11:16 -0700)
committerMark Fasheh <mark.fasheh@oracle.com>
Mon, 26 Jun 2006 21:43:00 +0000 (14:43 -0700)
Immediately purge a lockress that the local node is not the master of.

Signed-off-by: Kurt Hackel <kurt.hackel@oracle.com>
Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
fs/ocfs2/dlm/dlmthread.c

index 71302b90daf5b6fd2869aac669fae6f27b8eca14..76526ea95bb2a58a286c4003740b95bc4eefadc7 100644 (file)
@@ -54,6 +54,8 @@
 #include "cluster/masklog.h"
 
 static int dlm_thread(void *data);
+static void dlm_purge_lockres_now(struct dlm_ctxt *dlm,
+                                 struct dlm_lock_resource *lockres);
 
 static void dlm_flush_asts(struct dlm_ctxt *dlm);
 
@@ -111,10 +113,23 @@ void __dlm_lockres_calc_usage(struct dlm_ctxt *dlm,
                        res->last_used = jiffies;
                        list_add_tail(&res->purge, &dlm->purge_list);
                        dlm->purge_count++;
+
+                       /* if this node is not the owner, there is
+                        * no way to keep track of who the owner could be.
+                        * unhash it to avoid serious problems. */
+                       if (res->owner != dlm->node_num) {
+                               mlog(0, "%s:%.*s: doing immediate "
+                                    "purge of lockres owned by %u\n",
+                                    dlm->name, res->lockname.len,
+                                    res->lockname.name, res->owner);
+
+                               dlm_purge_lockres_now(dlm, res);
+                       }
                }
        } else if (!list_empty(&res->purge)) {
-               mlog(0, "removing lockres %.*s from purge list\n",
-                    res->lockname.len, res->lockname.name);
+               mlog(0, "removing lockres %.*s from purge list, "
+                    "owner=%u\n", res->lockname.len, res->lockname.name,
+                    res->owner);
 
                list_del_init(&res->purge);
                dlm->purge_count--;
@@ -180,6 +195,24 @@ finish:
        __dlm_unhash_lockres(lockres);
 }
 
+/* make an unused lockres go away immediately.
+ * as soon as the dlm spinlock is dropped, this lockres
+ * will not be found. kfree still happens on last put. */
+static void dlm_purge_lockres_now(struct dlm_ctxt *dlm,
+                                 struct dlm_lock_resource *lockres)
+{
+       assert_spin_locked(&dlm->spinlock);
+       assert_spin_locked(&lockres->spinlock);
+
+       BUG_ON(!__dlm_lockres_unused(lockres));
+
+       if (!list_empty(&lockres->purge)) {
+               list_del_init(&lockres->purge);
+               dlm->purge_count--;
+       }
+       __dlm_unhash_lockres(lockres);
+}
+
 static void dlm_run_purge_list(struct dlm_ctxt *dlm,
                               int purge_now)
 {