diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ocfs2/dlm/dlmcommon.h | 12 | ||||
-rw-r--r-- | fs/ocfs2/dlm/dlmdomain.c | 11 | ||||
-rw-r--r-- | fs/ocfs2/dlm/dlmmaster.c | 116 |
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 | ||
456 | struct dlm_reco_node_data | 457 | struct 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 | ||
786 | struct 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 | |||
785 | static inline enum dlm_status | 795 | static 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, | |||
968 | void dlm_assert_master_post_handler(int status, void *data, void *ret_data); | 978 | void dlm_assert_master_post_handler(int status, void *data, void *ret_data); |
969 | int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data, | 979 | int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data, |
970 | void **ret_data); | 980 | void **ret_data); |
981 | int dlm_deref_lockres_done_handler(struct o2net_msg *msg, u32 len, void *data, | ||
982 | void **ret_data); | ||
971 | int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data, | 983 | int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data, |
972 | void **ret_data); | 984 | void **ret_data); |
973 | int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data, | 985 | int 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 | */ |
136 | static const struct dlm_protocol_version dlm_protocol = { | 139 | static 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); | ||
1857 | bail: | 1866 | bail: |
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 | ||
2378 | int 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 | |||
2458 | done: | ||
2459 | dlm_put(dlm); | ||
2460 | return ret; | ||
2461 | } | ||
2462 | |||
2463 | static 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 | |||
2378 | static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data) | 2494 | static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data) |
2379 | { | 2495 | { |
2380 | struct dlm_ctxt *dlm; | 2496 | struct dlm_ctxt *dlm; |