aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-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;