diff options
Diffstat (limited to 'fs/ocfs2/dlm')
-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); |