aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/dlm/dlmcommon.h2
-rw-r--r--fs/ocfs2/dlm/dlmdebug.c6
-rw-r--r--fs/ocfs2/dlm/dlmdomain.c84
-rw-r--r--fs/ocfs2/dlm/dlmrecovery.c1
4 files changed, 82 insertions, 11 deletions
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
index 1aac42a2974..d602abb51b6 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
465struct dlm_reco_node_data 467struct dlm_reco_node_data
diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
index 04a32be0aeb..56f82cb912e 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 3b179d6cbde..3aff23feefd 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 */
136static const struct dlm_protocol_version dlm_protocol = { 138static 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
491static 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
489static void dlm_mark_domain_leaving(struct dlm_ctxt *dlm) 513static 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
557static int dlm_send_one_domain_exit(struct dlm_ctxt *dlm, 582static 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
604static 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
581static void dlm_leave_domain(struct dlm_ctxt *dlm) 633static 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
1796bail: 1858bail:
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 f1beb6fc254..7efab6d28a2 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);