ocfs2_dlm: Calling post handler function in assert master handler
authorKurt Hackel <kurt.hackel@oracle.com>
Thu, 18 Jan 2007 01:05:53 +0000 (17:05 -0800)
committerMark Fasheh <mark.fasheh@oracle.com>
Wed, 7 Feb 2007 20:07:24 +0000 (12:07 -0800)
This patch prevents the dlm from sending the clear refmap message
before the set refmap. We use the newly created post function handler
routine to accomplish the task.

Signed-off-by: Kurt Hackel <kurt.hackel@oracle.com>
Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
fs/ocfs2/dlm/dlmcommon.h
fs/ocfs2/dlm/dlmdomain.c
fs/ocfs2/dlm/dlmmaster.c
fs/ocfs2/dlm/dlmthread.c

index 2df6fde3e6528c4104459961b6516c66a5ab775c..3f554711efe55635b29cbe183d810c56eb8a7ecd 100644 (file)
@@ -224,6 +224,7 @@ static inline void __dlm_set_joining_node(struct dlm_ctxt *dlm,
 #define DLM_LOCK_RES_MIGRATING            0x00000020
 #define DLM_LOCK_RES_DROPPING_REF         0x00000040
 #define DLM_LOCK_RES_BLOCK_DIRTY          0x00001000
+#define DLM_LOCK_RES_SETREF_INPROG        0x00002000
 
 /* max milliseconds to wait to sync up a network failure with a node death */
 #define DLM_NODE_DEATH_WAIT_MAX (5 * 1000)
@@ -879,6 +880,7 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data,
                               void **ret_data);
 int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data,
                              void **ret_data);
+void dlm_assert_master_post_handler(int status, void *data, void *ret_data);
 int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
                              void **ret_data);
 int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data,
index 8a208b06fdd770824477c160354b90c25591cd92..6590e1bca23c9ffc38a2858e7506c07f7ddf517e 100644 (file)
@@ -1101,7 +1101,8 @@ static int dlm_register_domain_handlers(struct dlm_ctxt *dlm)
        status = o2net_register_handler(DLM_ASSERT_MASTER_MSG, dlm->key,
                                        sizeof(struct dlm_assert_master),
                                        dlm_assert_master_handler,
-                                       dlm, NULL, &dlm->dlm_domain_handlers);
+                                       dlm, dlm_assert_master_post_handler,
+                                       &dlm->dlm_domain_handlers);
        if (status)
                goto bail;
 
index bd1268778b660b5b54e28589f33ada63e2445540..84f36db8ada32b5a354f05846c43e6834178ee76 100644 (file)
@@ -2036,8 +2036,12 @@ ok:
 
 done:
        ret = 0;
-       if (res)
-               dlm_lockres_put(res);
+       if (res) {
+               spin_lock(&res->spinlock);
+               res->state |= DLM_LOCK_RES_SETREF_INPROG;
+               spin_unlock(&res->spinlock);
+               *ret_data = (void *)res;
+       }
        dlm_put(dlm);
        if (master_request) {
                mlog(0, "need to tell master to reassert\n");
@@ -2064,11 +2068,25 @@ kill:
        __dlm_print_one_lock_resource(res);
        spin_unlock(&res->spinlock);
        spin_unlock(&dlm->spinlock);
-       dlm_lockres_put(res);
+       *ret_data = (void *)res; 
        dlm_put(dlm);
        return -EINVAL;
 }
 
+void dlm_assert_master_post_handler(int status, void *data, void *ret_data)
+{
+       struct dlm_lock_resource *res = (struct dlm_lock_resource *)ret_data;
+
+       if (ret_data) {
+               spin_lock(&res->spinlock);
+               res->state &= ~DLM_LOCK_RES_SETREF_INPROG;
+               spin_unlock(&res->spinlock);
+               wake_up(&res->wq);
+               dlm_lockres_put(res);
+       }
+       return;
+}
+
 int dlm_dispatch_assert_master(struct dlm_ctxt *dlm,
                               struct dlm_lock_resource *res,
                               int ignore_higher, u8 request_from, u32 flags)
index 3b94e4dec351b8bbdfbe85137fb558aedbd5ef04..8ffa0916eb86fc1c111ae3964b156505f714c6e6 100644 (file)
@@ -176,6 +176,10 @@ static int dlm_purge_lockres(struct dlm_ctxt *dlm,
             res->lockname.name, master);
 
        if (!master) {
+               spin_lock(&res->spinlock);
+               /* This ensures that clear refmap is sent after the set */
+               __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG);
+               spin_unlock(&res->spinlock);
                /* drop spinlock to do messaging, retake below */
                spin_unlock(&dlm->spinlock);
                /* clear our bit from the master's refmap, ignore errors */