summaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/dlm
diff options
context:
space:
mode:
authorxuejiufei <xuejiufei@huawei.com>2016-03-15 17:53:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-15 19:55:16 -0400
commit60d663cb527340c87c6cb98842e90a43243e1607 (patch)
tree759b66e37ff17a64cf23a15fc5efc53f96861567 /fs/ocfs2/dlm
parent39b29af03049421139656818f45b8ca7e12db3fa (diff)
ocfs2/dlm: add DEREF_DONE message
This series of patches is to fix the dis-order issue of setting/clearing refmap bit described below. Node 1 Node 2(master) dlmlock dlm_do_master_request dlm_master_request_handler -> dlm_lockres_set_refmap_bit dlmlock succeed dlmunlock succeed dlm_purge_lockres dlm_deref_handler -> find lock resource is in DLM_LOCK_RES_SETREF_INPROG state, so dispatch a deref work dlm_purge_lockres succeed. call dlmlock again dlm_do_master_request dlm_master_request_handler -> dlm_lockres_set_refmap_bit deref work trigger, call dlm_lockres_clear_refmap_bit to clear Node 1 from refmap dlm_purge_lockres succeed dlm_send_remote_lock_request return DLM_IVLOCKID because the lockres is not exist BUG if the lockres is $RECOVERY This series of patches add a new message to keep the order of set and clear. Other nodes can purge the lock resource only after the refmap bit on master is cleared. This patch is to add DEREF_DONE message and corresponding handler. Node can purge the lock resource after receiving this message. As a new message is added, so increase the minor number of dlm protocol version. Signed-off-by: xuejiufei <xuejiufei@huawei.com> Cc: Mark Fasheh <mfasheh@suse.de> Cc: Joel Becker <jlbec@evilplan.org> Cc: Junxiao Bi <junxiao.bi@oracle.com> Reviewed-by: Joseph Qi <joseph.qi@huawei.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ocfs2/dlm')
-rw-r--r--fs/ocfs2/dlm/dlmcommon.h12
-rw-r--r--fs/ocfs2/dlm/dlmdomain.c11
-rw-r--r--fs/ocfs2/dlm/dlmmaster.c116
3 files changed, 138 insertions, 1 deletions
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
index 62d932372585..c9f97da9231a 100644
--- a/fs/ocfs2/dlm/dlmcommon.h
+++ b/fs/ocfs2/dlm/dlmcommon.h
@@ -451,6 +451,7 @@ enum {
451 DLM_QUERY_REGION = 519, 451 DLM_QUERY_REGION = 519,
452 DLM_QUERY_NODEINFO = 520, 452 DLM_QUERY_NODEINFO = 520,
453 DLM_BEGIN_EXIT_DOMAIN_MSG = 521, 453 DLM_BEGIN_EXIT_DOMAIN_MSG = 521,
454 DLM_DEREF_LOCKRES_DONE = 522,
454}; 455};
455 456
456struct dlm_reco_node_data 457struct dlm_reco_node_data
@@ -782,6 +783,15 @@ struct dlm_deref_lockres
782 u8 name[O2NM_MAX_NAME_LEN]; 783 u8 name[O2NM_MAX_NAME_LEN];
783}; 784};
784 785
786struct dlm_deref_lockres_done {
787 u32 pad1;
788 u16 pad2;
789 u8 node_idx;
790 u8 namelen;
791
792 u8 name[O2NM_MAX_NAME_LEN];
793};
794
785static inline enum dlm_status 795static inline enum dlm_status
786__dlm_lockres_state_to_status(struct dlm_lock_resource *res) 796__dlm_lockres_state_to_status(struct dlm_lock_resource *res)
787{ 797{
@@ -968,6 +978,8 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data,
968void dlm_assert_master_post_handler(int status, void *data, void *ret_data); 978void dlm_assert_master_post_handler(int status, void *data, void *ret_data);
969int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data, 979int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
970 void **ret_data); 980 void **ret_data);
981int dlm_deref_lockres_done_handler(struct o2net_msg *msg, u32 len, void *data,
982 void **ret_data);
971int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data, 983int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data,
972 void **ret_data); 984 void **ret_data);
973int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data, 985int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index 2ee7fe747cea..c73c68efdf67 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -132,10 +132,13 @@ static DECLARE_WAIT_QUEUE_HEAD(dlm_domain_events);
132 * - Message DLM_QUERY_NODEINFO added to allow online node removes 132 * - Message DLM_QUERY_NODEINFO added to allow online node removes
133 * New in version 1.2: 133 * New in version 1.2:
134 * - Message DLM_BEGIN_EXIT_DOMAIN_MSG added to mark start of exit domain 134 * - Message DLM_BEGIN_EXIT_DOMAIN_MSG added to mark start of exit domain
135 * New in version 1.3:
136 * - Message DLM_DEREF_LOCKRES_DONE added to inform non-master that the
137 * refmap is cleared
135 */ 138 */
136static const struct dlm_protocol_version dlm_protocol = { 139static const struct dlm_protocol_version dlm_protocol = {
137 .pv_major = 1, 140 .pv_major = 1,
138 .pv_minor = 2, 141 .pv_minor = 3,
139}; 142};
140 143
141#define DLM_DOMAIN_BACKOFF_MS 200 144#define DLM_DOMAIN_BACKOFF_MS 200
@@ -1853,7 +1856,13 @@ static int dlm_register_domain_handlers(struct dlm_ctxt *dlm)
1853 sizeof(struct dlm_exit_domain), 1856 sizeof(struct dlm_exit_domain),
1854 dlm_begin_exit_domain_handler, 1857 dlm_begin_exit_domain_handler,
1855 dlm, NULL, &dlm->dlm_domain_handlers); 1858 dlm, NULL, &dlm->dlm_domain_handlers);
1859 if (status)
1860 goto bail;
1856 1861
1862 status = o2net_register_handler(DLM_DEREF_LOCKRES_DONE, dlm->key,
1863 sizeof(struct dlm_deref_lockres_done),
1864 dlm_deref_lockres_done_handler,
1865 dlm, NULL, &dlm->dlm_domain_handlers);
1857bail: 1866bail:
1858 if (status) 1867 if (status)
1859 dlm_unregister_domain_handlers(dlm); 1868 dlm_unregister_domain_handlers(dlm);
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index 9477d6e1de37..8913e7d443da 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -2375,6 +2375,122 @@ done:
2375 return ret; 2375 return ret;
2376} 2376}
2377 2377
2378int dlm_deref_lockres_done_handler(struct o2net_msg *msg, u32 len, void *data,
2379 void **ret_data)
2380{
2381 struct dlm_ctxt *dlm = data;
2382 struct dlm_deref_lockres_done *deref
2383 = (struct dlm_deref_lockres_done *)msg->buf;
2384 struct dlm_lock_resource *res = NULL;
2385 char *name;
2386 unsigned int namelen;
2387 int ret = -EINVAL;
2388 u8 node;
2389 unsigned int hash;
2390
2391 if (!dlm_grab(dlm))
2392 return 0;
2393
2394 name = deref->name;
2395 namelen = deref->namelen;
2396 node = deref->node_idx;
2397
2398 if (namelen > DLM_LOCKID_NAME_MAX) {
2399 mlog(ML_ERROR, "Invalid name length!");
2400 goto done;
2401 }
2402 if (deref->node_idx >= O2NM_MAX_NODES) {
2403 mlog(ML_ERROR, "Invalid node number: %u\n", node);
2404 goto done;
2405 }
2406
2407 hash = dlm_lockid_hash(name, namelen);
2408
2409 spin_lock(&dlm->spinlock);
2410 res = __dlm_lookup_lockres_full(dlm, name, namelen, hash);
2411 if (!res) {
2412 spin_unlock(&dlm->spinlock);
2413 mlog(ML_ERROR, "%s:%.*s: bad lockres name\n",
2414 dlm->name, namelen, name);
2415 goto done;
2416 }
2417
2418 spin_lock(&res->spinlock);
2419 BUG_ON(!(res->state & DLM_LOCK_RES_DROPPING_REF));
2420 if (!list_empty(&res->purge)) {
2421 mlog(0, "%s: Removing res %.*s from purgelist\n",
2422 dlm->name, res->lockname.len, res->lockname.name);
2423 list_del_init(&res->purge);
2424 dlm_lockres_put(res);
2425 dlm->purge_count--;
2426 }
2427
2428 if (!__dlm_lockres_unused(res)) {
2429 mlog(ML_ERROR, "%s: res %.*s in use after deref\n",
2430 dlm->name, res->lockname.len, res->lockname.name);
2431 __dlm_print_one_lock_resource(res);
2432 BUG();
2433 }
2434
2435 __dlm_unhash_lockres(dlm, res);
2436
2437 spin_lock(&dlm->track_lock);
2438 if (!list_empty(&res->tracking))
2439 list_del_init(&res->tracking);
2440 else {
2441 mlog(ML_ERROR, "%s: Resource %.*s not on the Tracking list\n",
2442 dlm->name, res->lockname.len, res->lockname.name);
2443 __dlm_print_one_lock_resource(res);
2444 }
2445 spin_unlock(&dlm->track_lock);
2446
2447 /* lockres is not in the hash now. drop the flag and wake up
2448 * any processes waiting in dlm_get_lock_resource.
2449 */
2450 res->state &= ~DLM_LOCK_RES_DROPPING_REF;
2451 spin_unlock(&res->spinlock);
2452 wake_up(&res->wq);
2453
2454 dlm_lockres_put(res);
2455
2456 spin_unlock(&dlm->spinlock);
2457
2458done:
2459 dlm_put(dlm);
2460 return ret;
2461}
2462
2463static void dlm_drop_lockres_ref_done(struct dlm_ctxt *dlm,
2464 struct dlm_lock_resource *res, u8 node)
2465{
2466 struct dlm_deref_lockres_done deref;
2467 int ret = 0, r;
2468 const char *lockname;
2469 unsigned int namelen;
2470
2471 lockname = res->lockname.name;
2472 namelen = res->lockname.len;
2473 BUG_ON(namelen > O2NM_MAX_NAME_LEN);
2474
2475 memset(&deref, 0, sizeof(deref));
2476 deref.node_idx = dlm->node_num;
2477 deref.namelen = namelen;
2478 memcpy(deref.name, lockname, namelen);
2479
2480 ret = o2net_send_message(DLM_DEREF_LOCKRES_DONE, dlm->key,
2481 &deref, sizeof(deref), node, &r);
2482 if (ret < 0) {
2483 mlog(ML_ERROR, "%s: res %.*s, error %d send DEREF DONE "
2484 " to node %u\n", dlm->name, namelen,
2485 lockname, ret, node);
2486 } else if (r < 0) {
2487 /* ignore the error */
2488 mlog(ML_ERROR, "%s: res %.*s, DEREF to node %u got %d\n",
2489 dlm->name, namelen, lockname, node, r);
2490 dlm_print_one_lock_resource(res);
2491 }
2492}
2493
2378static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data) 2494static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data)
2379{ 2495{
2380 struct dlm_ctxt *dlm; 2496 struct dlm_ctxt *dlm;