diff options
| -rw-r--r-- | fs/ocfs2/dlm/dlmcommon.h | 2 | ||||
| -rw-r--r-- | fs/ocfs2/dlm/dlmdebug.c | 6 | ||||
| -rw-r--r-- | fs/ocfs2/dlm/dlmdomain.c | 84 | ||||
| -rw-r--r-- | fs/ocfs2/dlm/dlmrecovery.c | 1 |
4 files changed, 82 insertions, 11 deletions
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index 1aac42a29745..d602abb51b61 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h | |||
| @@ -144,6 +144,7 @@ struct dlm_ctxt | |||
| 144 | wait_queue_head_t dlm_join_events; | 144 | wait_queue_head_t dlm_join_events; |
| 145 | unsigned long live_nodes_map[BITS_TO_LONGS(O2NM_MAX_NODES)]; | 145 | unsigned long live_nodes_map[BITS_TO_LONGS(O2NM_MAX_NODES)]; |
| 146 | unsigned long domain_map[BITS_TO_LONGS(O2NM_MAX_NODES)]; | 146 | unsigned long domain_map[BITS_TO_LONGS(O2NM_MAX_NODES)]; |
| 147 | unsigned long exit_domain_map[BITS_TO_LONGS(O2NM_MAX_NODES)]; | ||
| 147 | unsigned long recovery_map[BITS_TO_LONGS(O2NM_MAX_NODES)]; | 148 | unsigned long recovery_map[BITS_TO_LONGS(O2NM_MAX_NODES)]; |
| 148 | struct dlm_recovery_ctxt reco; | 149 | struct dlm_recovery_ctxt reco; |
| 149 | spinlock_t master_lock; | 150 | spinlock_t master_lock; |
| @@ -460,6 +461,7 @@ enum { | |||
| 460 | DLM_FINALIZE_RECO_MSG = 518, | 461 | DLM_FINALIZE_RECO_MSG = 518, |
| 461 | DLM_QUERY_REGION = 519, | 462 | DLM_QUERY_REGION = 519, |
| 462 | DLM_QUERY_NODEINFO = 520, | 463 | DLM_QUERY_NODEINFO = 520, |
| 464 | DLM_BEGIN_EXIT_DOMAIN_MSG = 521, | ||
| 463 | }; | 465 | }; |
| 464 | 466 | ||
| 465 | struct dlm_reco_node_data | 467 | struct dlm_reco_node_data |
diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c index 04a32be0aeb9..56f82cb912e3 100644 --- a/fs/ocfs2/dlm/dlmdebug.c +++ b/fs/ocfs2/dlm/dlmdebug.c | |||
| @@ -756,6 +756,12 @@ static int debug_state_print(struct dlm_ctxt *dlm, char *buf, int len) | |||
| 756 | buf + out, len - out); | 756 | buf + out, len - out); |
| 757 | out += snprintf(buf + out, len - out, "\n"); | 757 | out += snprintf(buf + out, len - out, "\n"); |
| 758 | 758 | ||
| 759 | /* Exit Domain Map: xx xx xx */ | ||
| 760 | out += snprintf(buf + out, len - out, "Exit Domain Map: "); | ||
| 761 | out += stringify_nodemap(dlm->exit_domain_map, O2NM_MAX_NODES, | ||
| 762 | buf + out, len - out); | ||
| 763 | out += snprintf(buf + out, len - out, "\n"); | ||
| 764 | |||
| 759 | /* Live Map: xx xx xx */ | 765 | /* Live Map: xx xx xx */ |
| 760 | out += snprintf(buf + out, len - out, "Live Map: "); | 766 | out += snprintf(buf + out, len - out, "Live Map: "); |
| 761 | out += stringify_nodemap(dlm->live_nodes_map, O2NM_MAX_NODES, | 767 | out += stringify_nodemap(dlm->live_nodes_map, O2NM_MAX_NODES, |
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 3b179d6cbde0..3aff23feefdc 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c | |||
| @@ -132,10 +132,12 @@ static DECLARE_WAIT_QUEUE_HEAD(dlm_domain_events); | |||
| 132 | * New in version 1.1: | 132 | * New in version 1.1: |
| 133 | * - Message DLM_QUERY_REGION added to support global heartbeat | 133 | * - Message DLM_QUERY_REGION added to support global heartbeat |
| 134 | * - Message DLM_QUERY_NODEINFO added to allow online node removes | 134 | * - Message DLM_QUERY_NODEINFO added to allow online node removes |
| 135 | * New in version 1.2: | ||
| 136 | * - Message DLM_BEGIN_EXIT_DOMAIN_MSG added to mark start of exit domain | ||
| 135 | */ | 137 | */ |
| 136 | static const struct dlm_protocol_version dlm_protocol = { | 138 | static const struct dlm_protocol_version dlm_protocol = { |
| 137 | .pv_major = 1, | 139 | .pv_major = 1, |
| 138 | .pv_minor = 1, | 140 | .pv_minor = 2, |
| 139 | }; | 141 | }; |
| 140 | 142 | ||
| 141 | #define DLM_DOMAIN_BACKOFF_MS 200 | 143 | #define DLM_DOMAIN_BACKOFF_MS 200 |
| @@ -486,6 +488,28 @@ static int dlm_no_joining_node(struct dlm_ctxt *dlm) | |||
| 486 | return ret; | 488 | return ret; |
| 487 | } | 489 | } |
| 488 | 490 | ||
| 491 | static int dlm_begin_exit_domain_handler(struct o2net_msg *msg, u32 len, | ||
| 492 | void *data, void **ret_data) | ||
| 493 | { | ||
| 494 | struct dlm_ctxt *dlm = data; | ||
| 495 | unsigned int node; | ||
| 496 | struct dlm_exit_domain *exit_msg = (struct dlm_exit_domain *) msg->buf; | ||
| 497 | |||
| 498 | if (!dlm_grab(dlm)) | ||
| 499 | return 0; | ||
| 500 | |||
| 501 | node = exit_msg->node_idx; | ||
| 502 | mlog(0, "%s: Node %u sent a begin exit domain message\n", dlm->name, node); | ||
| 503 | |||
| 504 | spin_lock(&dlm->spinlock); | ||
| 505 | set_bit(node, dlm->exit_domain_map); | ||
| 506 | spin_unlock(&dlm->spinlock); | ||
| 507 | |||
| 508 | dlm_put(dlm); | ||
| 509 | |||
| 510 | return 0; | ||
| 511 | } | ||
| 512 | |||
| 489 | static void dlm_mark_domain_leaving(struct dlm_ctxt *dlm) | 513 | static void dlm_mark_domain_leaving(struct dlm_ctxt *dlm) |
| 490 | { | 514 | { |
| 491 | /* Yikes, a double spinlock! I need domain_lock for the dlm | 515 | /* Yikes, a double spinlock! I need domain_lock for the dlm |
| @@ -542,6 +566,7 @@ static int dlm_exit_domain_handler(struct o2net_msg *msg, u32 len, void *data, | |||
| 542 | 566 | ||
| 543 | spin_lock(&dlm->spinlock); | 567 | spin_lock(&dlm->spinlock); |
| 544 | clear_bit(node, dlm->domain_map); | 568 | clear_bit(node, dlm->domain_map); |
| 569 | clear_bit(node, dlm->exit_domain_map); | ||
| 545 | __dlm_print_nodes(dlm); | 570 | __dlm_print_nodes(dlm); |
| 546 | 571 | ||
| 547 | /* notify anything attached to the heartbeat events */ | 572 | /* notify anything attached to the heartbeat events */ |
| @@ -554,29 +579,56 @@ static int dlm_exit_domain_handler(struct o2net_msg *msg, u32 len, void *data, | |||
| 554 | return 0; | 579 | return 0; |
| 555 | } | 580 | } |
| 556 | 581 | ||
| 557 | static int dlm_send_one_domain_exit(struct dlm_ctxt *dlm, | 582 | static int dlm_send_one_domain_exit(struct dlm_ctxt *dlm, u32 msg_type, |
| 558 | unsigned int node) | 583 | unsigned int node) |
| 559 | { | 584 | { |
| 560 | int status; | 585 | int status; |
| 561 | struct dlm_exit_domain leave_msg; | 586 | struct dlm_exit_domain leave_msg; |
| 562 | 587 | ||
| 563 | mlog(0, "Asking node %u if we can leave the domain %s me = %u\n", | 588 | mlog(0, "%s: Sending domain exit message %u to node %u\n", dlm->name, |
| 564 | node, dlm->name, dlm->node_num); | 589 | msg_type, node); |
| 565 | 590 | ||
| 566 | memset(&leave_msg, 0, sizeof(leave_msg)); | 591 | memset(&leave_msg, 0, sizeof(leave_msg)); |
| 567 | leave_msg.node_idx = dlm->node_num; | 592 | leave_msg.node_idx = dlm->node_num; |
| 568 | 593 | ||
| 569 | status = o2net_send_message(DLM_EXIT_DOMAIN_MSG, dlm->key, | 594 | status = o2net_send_message(msg_type, dlm->key, &leave_msg, |
| 570 | &leave_msg, sizeof(leave_msg), node, | 595 | sizeof(leave_msg), node, NULL); |
| 571 | NULL); | ||
| 572 | if (status < 0) | 596 | if (status < 0) |
| 573 | mlog(ML_ERROR, "Error %d when sending message %u (key 0x%x) to " | 597 | mlog(ML_ERROR, "Error %d sending domain exit message %u " |
| 574 | "node %u\n", status, DLM_EXIT_DOMAIN_MSG, dlm->key, node); | 598 | "to node %u on domain %s\n", status, msg_type, node, |
| 575 | mlog(0, "status return %d from o2net_send_message\n", status); | 599 | dlm->name); |
| 576 | 600 | ||
| 577 | return status; | 601 | return status; |
| 578 | } | 602 | } |
| 579 | 603 | ||
| 604 | static void dlm_begin_exit_domain(struct dlm_ctxt *dlm) | ||
| 605 | { | ||
| 606 | int node = -1; | ||
| 607 | |||
| 608 | /* Support for begin exit domain was added in 1.2 */ | ||
| 609 | if (dlm->dlm_locking_proto.pv_major == 1 && | ||
| 610 | dlm->dlm_locking_proto.pv_minor < 2) | ||
| 611 | return; | ||
| 612 | |||
| 613 | /* | ||
| 614 | * Unlike DLM_EXIT_DOMAIN_MSG, DLM_BEGIN_EXIT_DOMAIN_MSG is purely | ||
| 615 | * informational. Meaning if a node does not receive the message, | ||
| 616 | * so be it. | ||
| 617 | */ | ||
| 618 | spin_lock(&dlm->spinlock); | ||
| 619 | while (1) { | ||
| 620 | node = find_next_bit(dlm->domain_map, O2NM_MAX_NODES, node + 1); | ||
| 621 | if (node >= O2NM_MAX_NODES) | ||
| 622 | break; | ||
| 623 | if (node == dlm->node_num) | ||
| 624 | continue; | ||
| 625 | |||
| 626 | spin_unlock(&dlm->spinlock); | ||
| 627 | dlm_send_one_domain_exit(dlm, DLM_BEGIN_EXIT_DOMAIN_MSG, node); | ||
| 628 | spin_lock(&dlm->spinlock); | ||
| 629 | } | ||
| 630 | spin_unlock(&dlm->spinlock); | ||
| 631 | } | ||
| 580 | 632 | ||
| 581 | static void dlm_leave_domain(struct dlm_ctxt *dlm) | 633 | static void dlm_leave_domain(struct dlm_ctxt *dlm) |
| 582 | { | 634 | { |
| @@ -602,7 +654,8 @@ static void dlm_leave_domain(struct dlm_ctxt *dlm) | |||
| 602 | 654 | ||
| 603 | clear_node = 1; | 655 | clear_node = 1; |
| 604 | 656 | ||
| 605 | status = dlm_send_one_domain_exit(dlm, node); | 657 | status = dlm_send_one_domain_exit(dlm, DLM_EXIT_DOMAIN_MSG, |
| 658 | node); | ||
| 606 | if (status < 0 && | 659 | if (status < 0 && |
| 607 | status != -ENOPROTOOPT && | 660 | status != -ENOPROTOOPT && |
| 608 | status != -ENOTCONN) { | 661 | status != -ENOTCONN) { |
| @@ -677,6 +730,7 @@ void dlm_unregister_domain(struct dlm_ctxt *dlm) | |||
| 677 | 730 | ||
| 678 | if (leave) { | 731 | if (leave) { |
| 679 | mlog(0, "shutting down domain %s\n", dlm->name); | 732 | mlog(0, "shutting down domain %s\n", dlm->name); |
| 733 | dlm_begin_exit_domain(dlm); | ||
| 680 | 734 | ||
| 681 | /* We changed dlm state, notify the thread */ | 735 | /* We changed dlm state, notify the thread */ |
| 682 | dlm_kick_thread(dlm, NULL); | 736 | dlm_kick_thread(dlm, NULL); |
| @@ -909,6 +963,7 @@ static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data, | |||
| 909 | * leftover join state. */ | 963 | * leftover join state. */ |
| 910 | BUG_ON(dlm->joining_node != assert->node_idx); | 964 | BUG_ON(dlm->joining_node != assert->node_idx); |
| 911 | set_bit(assert->node_idx, dlm->domain_map); | 965 | set_bit(assert->node_idx, dlm->domain_map); |
| 966 | clear_bit(assert->node_idx, dlm->exit_domain_map); | ||
| 912 | __dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN); | 967 | __dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN); |
| 913 | 968 | ||
| 914 | printk(KERN_NOTICE "o2dlm: Node %u joins domain %s\n", | 969 | printk(KERN_NOTICE "o2dlm: Node %u joins domain %s\n", |
| @@ -1793,6 +1848,13 @@ static int dlm_register_domain_handlers(struct dlm_ctxt *dlm) | |||
| 1793 | if (status) | 1848 | if (status) |
| 1794 | goto bail; | 1849 | goto bail; |
| 1795 | 1850 | ||
| 1851 | status = o2net_register_handler(DLM_BEGIN_EXIT_DOMAIN_MSG, dlm->key, | ||
| 1852 | sizeof(struct dlm_exit_domain), | ||
| 1853 | dlm_begin_exit_domain_handler, | ||
| 1854 | dlm, NULL, &dlm->dlm_domain_handlers); | ||
| 1855 | if (status) | ||
| 1856 | goto bail; | ||
| 1857 | |||
| 1796 | bail: | 1858 | bail: |
| 1797 | if (status) | 1859 | if (status) |
| 1798 | dlm_unregister_domain_handlers(dlm); | 1860 | dlm_unregister_domain_handlers(dlm); |
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index f1beb6fc254d..7efab6d28a21 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c | |||
| @@ -2393,6 +2393,7 @@ static void __dlm_hb_node_down(struct dlm_ctxt *dlm, int idx) | |||
| 2393 | 2393 | ||
| 2394 | mlog(0, "node %u being removed from domain map!\n", idx); | 2394 | mlog(0, "node %u being removed from domain map!\n", idx); |
| 2395 | clear_bit(idx, dlm->domain_map); | 2395 | clear_bit(idx, dlm->domain_map); |
| 2396 | clear_bit(idx, dlm->exit_domain_map); | ||
| 2396 | /* wake up migration waiters if a node goes down. | 2397 | /* wake up migration waiters if a node goes down. |
| 2397 | * perhaps later we can genericize this for other waiters. */ | 2398 | * perhaps later we can genericize this for other waiters. */ |
| 2398 | wake_up(&dlm->migration_wq); | 2399 | wake_up(&dlm->migration_wq); |
