diff options
-rw-r--r-- | fs/ocfs2/dlm/dlmcommon.h | 2 | ||||
-rw-r--r-- | fs/ocfs2/dlm/dlmdomain.c | 3 | ||||
-rw-r--r-- | fs/ocfs2/dlm/dlmmaster.c | 24 | ||||
-rw-r--r-- | fs/ocfs2/dlm/dlmthread.c | 4 |
4 files changed, 29 insertions, 4 deletions
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index 2df6fde3e652..3f554711efe5 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h | |||
@@ -224,6 +224,7 @@ static inline void __dlm_set_joining_node(struct dlm_ctxt *dlm, | |||
224 | #define DLM_LOCK_RES_MIGRATING 0x00000020 | 224 | #define DLM_LOCK_RES_MIGRATING 0x00000020 |
225 | #define DLM_LOCK_RES_DROPPING_REF 0x00000040 | 225 | #define DLM_LOCK_RES_DROPPING_REF 0x00000040 |
226 | #define DLM_LOCK_RES_BLOCK_DIRTY 0x00001000 | 226 | #define DLM_LOCK_RES_BLOCK_DIRTY 0x00001000 |
227 | #define DLM_LOCK_RES_SETREF_INPROG 0x00002000 | ||
227 | 228 | ||
228 | /* max milliseconds to wait to sync up a network failure with a node death */ | 229 | /* max milliseconds to wait to sync up a network failure with a node death */ |
229 | #define DLM_NODE_DEATH_WAIT_MAX (5 * 1000) | 230 | #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, | |||
879 | void **ret_data); | 880 | void **ret_data); |
880 | int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data, | 881 | int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data, |
881 | void **ret_data); | 882 | void **ret_data); |
883 | void dlm_assert_master_post_handler(int status, void *data, void *ret_data); | ||
882 | int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data, | 884 | int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data, |
883 | void **ret_data); | 885 | void **ret_data); |
884 | int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data, | 886 | int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data, |
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 8a208b06fdd7..6590e1bca23c 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c | |||
@@ -1101,7 +1101,8 @@ static int dlm_register_domain_handlers(struct dlm_ctxt *dlm) | |||
1101 | status = o2net_register_handler(DLM_ASSERT_MASTER_MSG, dlm->key, | 1101 | status = o2net_register_handler(DLM_ASSERT_MASTER_MSG, dlm->key, |
1102 | sizeof(struct dlm_assert_master), | 1102 | sizeof(struct dlm_assert_master), |
1103 | dlm_assert_master_handler, | 1103 | dlm_assert_master_handler, |
1104 | dlm, NULL, &dlm->dlm_domain_handlers); | 1104 | dlm, dlm_assert_master_post_handler, |
1105 | &dlm->dlm_domain_handlers); | ||
1105 | if (status) | 1106 | if (status) |
1106 | goto bail; | 1107 | goto bail; |
1107 | 1108 | ||
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index bd1268778b66..84f36db8ada3 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
@@ -2036,8 +2036,12 @@ ok: | |||
2036 | 2036 | ||
2037 | done: | 2037 | done: |
2038 | ret = 0; | 2038 | ret = 0; |
2039 | if (res) | 2039 | if (res) { |
2040 | dlm_lockres_put(res); | 2040 | spin_lock(&res->spinlock); |
2041 | res->state |= DLM_LOCK_RES_SETREF_INPROG; | ||
2042 | spin_unlock(&res->spinlock); | ||
2043 | *ret_data = (void *)res; | ||
2044 | } | ||
2041 | dlm_put(dlm); | 2045 | dlm_put(dlm); |
2042 | if (master_request) { | 2046 | if (master_request) { |
2043 | mlog(0, "need to tell master to reassert\n"); | 2047 | mlog(0, "need to tell master to reassert\n"); |
@@ -2064,11 +2068,25 @@ kill: | |||
2064 | __dlm_print_one_lock_resource(res); | 2068 | __dlm_print_one_lock_resource(res); |
2065 | spin_unlock(&res->spinlock); | 2069 | spin_unlock(&res->spinlock); |
2066 | spin_unlock(&dlm->spinlock); | 2070 | spin_unlock(&dlm->spinlock); |
2067 | dlm_lockres_put(res); | 2071 | *ret_data = (void *)res; |
2068 | dlm_put(dlm); | 2072 | dlm_put(dlm); |
2069 | return -EINVAL; | 2073 | return -EINVAL; |
2070 | } | 2074 | } |
2071 | 2075 | ||
2076 | void dlm_assert_master_post_handler(int status, void *data, void *ret_data) | ||
2077 | { | ||
2078 | struct dlm_lock_resource *res = (struct dlm_lock_resource *)ret_data; | ||
2079 | |||
2080 | if (ret_data) { | ||
2081 | spin_lock(&res->spinlock); | ||
2082 | res->state &= ~DLM_LOCK_RES_SETREF_INPROG; | ||
2083 | spin_unlock(&res->spinlock); | ||
2084 | wake_up(&res->wq); | ||
2085 | dlm_lockres_put(res); | ||
2086 | } | ||
2087 | return; | ||
2088 | } | ||
2089 | |||
2072 | int dlm_dispatch_assert_master(struct dlm_ctxt *dlm, | 2090 | int dlm_dispatch_assert_master(struct dlm_ctxt *dlm, |
2073 | struct dlm_lock_resource *res, | 2091 | struct dlm_lock_resource *res, |
2074 | int ignore_higher, u8 request_from, u32 flags) | 2092 | int ignore_higher, u8 request_from, u32 flags) |
diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index 3b94e4dec351..8ffa0916eb86 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c | |||
@@ -176,6 +176,10 @@ static int dlm_purge_lockres(struct dlm_ctxt *dlm, | |||
176 | res->lockname.name, master); | 176 | res->lockname.name, master); |
177 | 177 | ||
178 | if (!master) { | 178 | if (!master) { |
179 | spin_lock(&res->spinlock); | ||
180 | /* This ensures that clear refmap is sent after the set */ | ||
181 | __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG); | ||
182 | spin_unlock(&res->spinlock); | ||
179 | /* drop spinlock to do messaging, retake below */ | 183 | /* drop spinlock to do messaging, retake below */ |
180 | spin_unlock(&dlm->spinlock); | 184 | spin_unlock(&dlm->spinlock); |
181 | /* clear our bit from the master's refmap, ignore errors */ | 185 | /* clear our bit from the master's refmap, ignore errors */ |