aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/dlm/dlmdomain.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/dlm/dlmdomain.c')
-rw-r--r--fs/ocfs2/dlm/dlmdomain.c173
1 files changed, 131 insertions, 42 deletions
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index 638d2ebb892b..63f8125824e8 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -33,6 +33,7 @@
33#include <linux/spinlock.h> 33#include <linux/spinlock.h>
34#include <linux/delay.h> 34#include <linux/delay.h>
35#include <linux/err.h> 35#include <linux/err.h>
36#include <linux/debugfs.h>
36 37
37#include "cluster/heartbeat.h" 38#include "cluster/heartbeat.h"
38#include "cluster/nodemanager.h" 39#include "cluster/nodemanager.h"
@@ -40,8 +41,8 @@
40 41
41#include "dlmapi.h" 42#include "dlmapi.h"
42#include "dlmcommon.h" 43#include "dlmcommon.h"
43
44#include "dlmdomain.h" 44#include "dlmdomain.h"
45#include "dlmdebug.h"
45 46
46#include "dlmver.h" 47#include "dlmver.h"
47 48
@@ -298,6 +299,8 @@ static int dlm_wait_on_domain_helper(const char *domain)
298 299
299static void dlm_free_ctxt_mem(struct dlm_ctxt *dlm) 300static void dlm_free_ctxt_mem(struct dlm_ctxt *dlm)
300{ 301{
302 dlm_destroy_debugfs_subroot(dlm);
303
301 if (dlm->lockres_hash) 304 if (dlm->lockres_hash)
302 dlm_free_pagevec((void **)dlm->lockres_hash, DLM_HASH_PAGES); 305 dlm_free_pagevec((void **)dlm->lockres_hash, DLM_HASH_PAGES);
303 306
@@ -395,6 +398,7 @@ static void dlm_destroy_dlm_worker(struct dlm_ctxt *dlm)
395static void dlm_complete_dlm_shutdown(struct dlm_ctxt *dlm) 398static void dlm_complete_dlm_shutdown(struct dlm_ctxt *dlm)
396{ 399{
397 dlm_unregister_domain_handlers(dlm); 400 dlm_unregister_domain_handlers(dlm);
401 dlm_debug_shutdown(dlm);
398 dlm_complete_thread(dlm); 402 dlm_complete_thread(dlm);
399 dlm_complete_recovery_thread(dlm); 403 dlm_complete_recovery_thread(dlm);
400 dlm_destroy_dlm_worker(dlm); 404 dlm_destroy_dlm_worker(dlm);
@@ -644,6 +648,7 @@ int dlm_shutting_down(struct dlm_ctxt *dlm)
644void dlm_unregister_domain(struct dlm_ctxt *dlm) 648void dlm_unregister_domain(struct dlm_ctxt *dlm)
645{ 649{
646 int leave = 0; 650 int leave = 0;
651 struct dlm_lock_resource *res;
647 652
648 spin_lock(&dlm_domain_lock); 653 spin_lock(&dlm_domain_lock);
649 BUG_ON(dlm->dlm_state != DLM_CTXT_JOINED); 654 BUG_ON(dlm->dlm_state != DLM_CTXT_JOINED);
@@ -673,6 +678,15 @@ void dlm_unregister_domain(struct dlm_ctxt *dlm)
673 msleep(500); 678 msleep(500);
674 mlog(0, "%s: more migration to do\n", dlm->name); 679 mlog(0, "%s: more migration to do\n", dlm->name);
675 } 680 }
681
682 /* This list should be empty. If not, print remaining lockres */
683 if (!list_empty(&dlm->tracking_list)) {
684 mlog(ML_ERROR, "Following lockres' are still on the "
685 "tracking list:\n");
686 list_for_each_entry(res, &dlm->tracking_list, tracking)
687 dlm_print_one_lock_resource(res);
688 }
689
676 dlm_mark_domain_leaving(dlm); 690 dlm_mark_domain_leaving(dlm);
677 dlm_leave_domain(dlm); 691 dlm_leave_domain(dlm);
678 dlm_complete_dlm_shutdown(dlm); 692 dlm_complete_dlm_shutdown(dlm);
@@ -713,14 +727,46 @@ static int dlm_query_join_proto_check(char *proto_type, int node,
713 return rc; 727 return rc;
714} 728}
715 729
730/*
731 * struct dlm_query_join_packet is made up of four one-byte fields. They
732 * are effectively in big-endian order already. However, little-endian
733 * machines swap them before putting the packet on the wire (because
734 * query_join's response is a status, and that status is treated as a u32
735 * on the wire). Thus, a big-endian and little-endian machines will treat
736 * this structure differently.
737 *
738 * The solution is to have little-endian machines swap the structure when
739 * converting from the structure to the u32 representation. This will
740 * result in the structure having the correct format on the wire no matter
741 * the host endian format.
742 */
743static void dlm_query_join_packet_to_wire(struct dlm_query_join_packet *packet,
744 u32 *wire)
745{
746 union dlm_query_join_response response;
747
748 response.packet = *packet;
749 *wire = cpu_to_be32(response.intval);
750}
751
752static void dlm_query_join_wire_to_packet(u32 wire,
753 struct dlm_query_join_packet *packet)
754{
755 union dlm_query_join_response response;
756
757 response.intval = cpu_to_be32(wire);
758 *packet = response.packet;
759}
760
716static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data, 761static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
717 void **ret_data) 762 void **ret_data)
718{ 763{
719 struct dlm_query_join_request *query; 764 struct dlm_query_join_request *query;
720 union dlm_query_join_response response = { 765 struct dlm_query_join_packet packet = {
721 .packet.code = JOIN_DISALLOW, 766 .code = JOIN_DISALLOW,
722 }; 767 };
723 struct dlm_ctxt *dlm = NULL; 768 struct dlm_ctxt *dlm = NULL;
769 u32 response;
724 u8 nodenum; 770 u8 nodenum;
725 771
726 query = (struct dlm_query_join_request *) msg->buf; 772 query = (struct dlm_query_join_request *) msg->buf;
@@ -737,11 +783,11 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
737 mlog(0, "node %u is not in our live map yet\n", 783 mlog(0, "node %u is not in our live map yet\n",
738 query->node_idx); 784 query->node_idx);
739 785
740 response.packet.code = JOIN_DISALLOW; 786 packet.code = JOIN_DISALLOW;
741 goto respond; 787 goto respond;
742 } 788 }
743 789
744 response.packet.code = JOIN_OK_NO_MAP; 790 packet.code = JOIN_OK_NO_MAP;
745 791
746 spin_lock(&dlm_domain_lock); 792 spin_lock(&dlm_domain_lock);
747 dlm = __dlm_lookup_domain_full(query->domain, query->name_len); 793 dlm = __dlm_lookup_domain_full(query->domain, query->name_len);
@@ -760,7 +806,7 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
760 mlog(0, "disallow join as node %u does not " 806 mlog(0, "disallow join as node %u does not "
761 "have node %u in its nodemap\n", 807 "have node %u in its nodemap\n",
762 query->node_idx, nodenum); 808 query->node_idx, nodenum);
763 response.packet.code = JOIN_DISALLOW; 809 packet.code = JOIN_DISALLOW;
764 goto unlock_respond; 810 goto unlock_respond;
765 } 811 }
766 } 812 }
@@ -780,23 +826,23 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
780 /*If this is a brand new context and we 826 /*If this is a brand new context and we
781 * haven't started our join process yet, then 827 * haven't started our join process yet, then
782 * the other node won the race. */ 828 * the other node won the race. */
783 response.packet.code = JOIN_OK_NO_MAP; 829 packet.code = JOIN_OK_NO_MAP;
784 } else if (dlm->joining_node != DLM_LOCK_RES_OWNER_UNKNOWN) { 830 } else if (dlm->joining_node != DLM_LOCK_RES_OWNER_UNKNOWN) {
785 /* Disallow parallel joins. */ 831 /* Disallow parallel joins. */
786 response.packet.code = JOIN_DISALLOW; 832 packet.code = JOIN_DISALLOW;
787 } else if (dlm->reco.state & DLM_RECO_STATE_ACTIVE) { 833 } else if (dlm->reco.state & DLM_RECO_STATE_ACTIVE) {
788 mlog(0, "node %u trying to join, but recovery " 834 mlog(0, "node %u trying to join, but recovery "
789 "is ongoing.\n", bit); 835 "is ongoing.\n", bit);
790 response.packet.code = JOIN_DISALLOW; 836 packet.code = JOIN_DISALLOW;
791 } else if (test_bit(bit, dlm->recovery_map)) { 837 } else if (test_bit(bit, dlm->recovery_map)) {
792 mlog(0, "node %u trying to join, but it " 838 mlog(0, "node %u trying to join, but it "
793 "still needs recovery.\n", bit); 839 "still needs recovery.\n", bit);
794 response.packet.code = JOIN_DISALLOW; 840 packet.code = JOIN_DISALLOW;
795 } else if (test_bit(bit, dlm->domain_map)) { 841 } else if (test_bit(bit, dlm->domain_map)) {
796 mlog(0, "node %u trying to join, but it " 842 mlog(0, "node %u trying to join, but it "
797 "is still in the domain! needs recovery?\n", 843 "is still in the domain! needs recovery?\n",
798 bit); 844 bit);
799 response.packet.code = JOIN_DISALLOW; 845 packet.code = JOIN_DISALLOW;
800 } else { 846 } else {
801 /* Alright we're fully a part of this domain 847 /* Alright we're fully a part of this domain
802 * so we keep some state as to who's joining 848 * so we keep some state as to who's joining
@@ -807,19 +853,15 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
807 if (dlm_query_join_proto_check("DLM", bit, 853 if (dlm_query_join_proto_check("DLM", bit,
808 &dlm->dlm_locking_proto, 854 &dlm->dlm_locking_proto,
809 &query->dlm_proto)) { 855 &query->dlm_proto)) {
810 response.packet.code = 856 packet.code = JOIN_PROTOCOL_MISMATCH;
811 JOIN_PROTOCOL_MISMATCH;
812 } else if (dlm_query_join_proto_check("fs", bit, 857 } else if (dlm_query_join_proto_check("fs", bit,
813 &dlm->fs_locking_proto, 858 &dlm->fs_locking_proto,
814 &query->fs_proto)) { 859 &query->fs_proto)) {
815 response.packet.code = 860 packet.code = JOIN_PROTOCOL_MISMATCH;
816 JOIN_PROTOCOL_MISMATCH;
817 } else { 861 } else {
818 response.packet.dlm_minor = 862 packet.dlm_minor = query->dlm_proto.pv_minor;
819 query->dlm_proto.pv_minor; 863 packet.fs_minor = query->fs_proto.pv_minor;
820 response.packet.fs_minor = 864 packet.code = JOIN_OK;
821 query->fs_proto.pv_minor;
822 response.packet.code = JOIN_OK;
823 __dlm_set_joining_node(dlm, query->node_idx); 865 __dlm_set_joining_node(dlm, query->node_idx);
824 } 866 }
825 } 867 }
@@ -830,9 +872,10 @@ unlock_respond:
830 spin_unlock(&dlm_domain_lock); 872 spin_unlock(&dlm_domain_lock);
831 873
832respond: 874respond:
833 mlog(0, "We respond with %u\n", response.packet.code); 875 mlog(0, "We respond with %u\n", packet.code);
834 876
835 return response.intval; 877 dlm_query_join_packet_to_wire(&packet, &response);
878 return response;
836} 879}
837 880
838static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data, 881static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data,
@@ -937,7 +980,7 @@ static int dlm_send_join_cancels(struct dlm_ctxt *dlm,
937 sizeof(unsigned long))) { 980 sizeof(unsigned long))) {
938 mlog(ML_ERROR, 981 mlog(ML_ERROR,
939 "map_size %u != BITS_TO_LONGS(O2NM_MAX_NODES) %u\n", 982 "map_size %u != BITS_TO_LONGS(O2NM_MAX_NODES) %u\n",
940 map_size, BITS_TO_LONGS(O2NM_MAX_NODES)); 983 map_size, (unsigned)BITS_TO_LONGS(O2NM_MAX_NODES));
941 return -EINVAL; 984 return -EINVAL;
942 } 985 }
943 986
@@ -968,7 +1011,8 @@ static int dlm_request_join(struct dlm_ctxt *dlm,
968{ 1011{
969 int status; 1012 int status;
970 struct dlm_query_join_request join_msg; 1013 struct dlm_query_join_request join_msg;
971 union dlm_query_join_response join_resp; 1014 struct dlm_query_join_packet packet;
1015 u32 join_resp;
972 1016
973 mlog(0, "querying node %d\n", node); 1017 mlog(0, "querying node %d\n", node);
974 1018
@@ -984,11 +1028,12 @@ static int dlm_request_join(struct dlm_ctxt *dlm,
984 1028
985 status = o2net_send_message(DLM_QUERY_JOIN_MSG, DLM_MOD_KEY, &join_msg, 1029 status = o2net_send_message(DLM_QUERY_JOIN_MSG, DLM_MOD_KEY, &join_msg,
986 sizeof(join_msg), node, 1030 sizeof(join_msg), node,
987 &join_resp.intval); 1031 &join_resp);
988 if (status < 0 && status != -ENOPROTOOPT) { 1032 if (status < 0 && status != -ENOPROTOOPT) {
989 mlog_errno(status); 1033 mlog_errno(status);
990 goto bail; 1034 goto bail;
991 } 1035 }
1036 dlm_query_join_wire_to_packet(join_resp, &packet);
992 1037
993 /* -ENOPROTOOPT from the net code means the other side isn't 1038 /* -ENOPROTOOPT from the net code means the other side isn't
994 listening for our message type -- that's fine, it means 1039 listening for our message type -- that's fine, it means
@@ -997,10 +1042,10 @@ static int dlm_request_join(struct dlm_ctxt *dlm,
997 if (status == -ENOPROTOOPT) { 1042 if (status == -ENOPROTOOPT) {
998 status = 0; 1043 status = 0;
999 *response = JOIN_OK_NO_MAP; 1044 *response = JOIN_OK_NO_MAP;
1000 } else if (join_resp.packet.code == JOIN_DISALLOW || 1045 } else if (packet.code == JOIN_DISALLOW ||
1001 join_resp.packet.code == JOIN_OK_NO_MAP) { 1046 packet.code == JOIN_OK_NO_MAP) {
1002 *response = join_resp.packet.code; 1047 *response = packet.code;
1003 } else if (join_resp.packet.code == JOIN_PROTOCOL_MISMATCH) { 1048 } else if (packet.code == JOIN_PROTOCOL_MISMATCH) {
1004 mlog(ML_NOTICE, 1049 mlog(ML_NOTICE,
1005 "This node requested DLM locking protocol %u.%u and " 1050 "This node requested DLM locking protocol %u.%u and "
1006 "filesystem locking protocol %u.%u. At least one of " 1051 "filesystem locking protocol %u.%u. At least one of "
@@ -1012,14 +1057,12 @@ static int dlm_request_join(struct dlm_ctxt *dlm,
1012 dlm->fs_locking_proto.pv_minor, 1057 dlm->fs_locking_proto.pv_minor,
1013 node); 1058 node);
1014 status = -EPROTO; 1059 status = -EPROTO;
1015 *response = join_resp.packet.code; 1060 *response = packet.code;
1016 } else if (join_resp.packet.code == JOIN_OK) { 1061 } else if (packet.code == JOIN_OK) {
1017 *response = join_resp.packet.code; 1062 *response = packet.code;
1018 /* Use the same locking protocol as the remote node */ 1063 /* Use the same locking protocol as the remote node */
1019 dlm->dlm_locking_proto.pv_minor = 1064 dlm->dlm_locking_proto.pv_minor = packet.dlm_minor;
1020 join_resp.packet.dlm_minor; 1065 dlm->fs_locking_proto.pv_minor = packet.fs_minor;
1021 dlm->fs_locking_proto.pv_minor =
1022 join_resp.packet.fs_minor;
1023 mlog(0, 1066 mlog(0,
1024 "Node %d responds JOIN_OK with DLM locking protocol " 1067 "Node %d responds JOIN_OK with DLM locking protocol "
1025 "%u.%u and fs locking protocol %u.%u\n", 1068 "%u.%u and fs locking protocol %u.%u\n",
@@ -1031,11 +1074,11 @@ static int dlm_request_join(struct dlm_ctxt *dlm,
1031 } else { 1074 } else {
1032 status = -EINVAL; 1075 status = -EINVAL;
1033 mlog(ML_ERROR, "invalid response %d from node %u\n", 1076 mlog(ML_ERROR, "invalid response %d from node %u\n",
1034 join_resp.packet.code, node); 1077 packet.code, node);
1035 } 1078 }
1036 1079
1037 mlog(0, "status %d, node %d response is %d\n", status, node, 1080 mlog(0, "status %d, node %d response is %d\n", status, node,
1038 *response); 1081 *response);
1039 1082
1040bail: 1083bail:
1041 return status; 1084 return status;
@@ -1376,6 +1419,12 @@ static int dlm_join_domain(struct dlm_ctxt *dlm)
1376 goto bail; 1419 goto bail;
1377 } 1420 }
1378 1421
1422 status = dlm_debug_init(dlm);
1423 if (status < 0) {
1424 mlog_errno(status);
1425 goto bail;
1426 }
1427
1379 status = dlm_launch_thread(dlm); 1428 status = dlm_launch_thread(dlm);
1380 if (status < 0) { 1429 if (status < 0) {
1381 mlog_errno(status); 1430 mlog_errno(status);
@@ -1443,6 +1492,7 @@ bail:
1443 1492
1444 if (status) { 1493 if (status) {
1445 dlm_unregister_domain_handlers(dlm); 1494 dlm_unregister_domain_handlers(dlm);
1495 dlm_debug_shutdown(dlm);
1446 dlm_complete_thread(dlm); 1496 dlm_complete_thread(dlm);
1447 dlm_complete_recovery_thread(dlm); 1497 dlm_complete_recovery_thread(dlm);
1448 dlm_destroy_dlm_worker(dlm); 1498 dlm_destroy_dlm_worker(dlm);
@@ -1455,6 +1505,7 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain,
1455 u32 key) 1505 u32 key)
1456{ 1506{
1457 int i; 1507 int i;
1508 int ret;
1458 struct dlm_ctxt *dlm = NULL; 1509 struct dlm_ctxt *dlm = NULL;
1459 1510
1460 dlm = kzalloc(sizeof(*dlm), GFP_KERNEL); 1511 dlm = kzalloc(sizeof(*dlm), GFP_KERNEL);
@@ -1487,6 +1538,15 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain,
1487 dlm->key = key; 1538 dlm->key = key;
1488 dlm->node_num = o2nm_this_node(); 1539 dlm->node_num = o2nm_this_node();
1489 1540
1541 ret = dlm_create_debugfs_subroot(dlm);
1542 if (ret < 0) {
1543 dlm_free_pagevec((void **)dlm->lockres_hash, DLM_HASH_PAGES);
1544 kfree(dlm->name);
1545 kfree(dlm);
1546 dlm = NULL;
1547 goto leave;
1548 }
1549
1490 spin_lock_init(&dlm->spinlock); 1550 spin_lock_init(&dlm->spinlock);
1491 spin_lock_init(&dlm->master_lock); 1551 spin_lock_init(&dlm->master_lock);
1492 spin_lock_init(&dlm->ast_lock); 1552 spin_lock_init(&dlm->ast_lock);
@@ -1497,6 +1557,7 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain,
1497 INIT_LIST_HEAD(&dlm->reco.node_data); 1557 INIT_LIST_HEAD(&dlm->reco.node_data);
1498 INIT_LIST_HEAD(&dlm->purge_list); 1558 INIT_LIST_HEAD(&dlm->purge_list);
1499 INIT_LIST_HEAD(&dlm->dlm_domain_handlers); 1559 INIT_LIST_HEAD(&dlm->dlm_domain_handlers);
1560 INIT_LIST_HEAD(&dlm->tracking_list);
1500 dlm->reco.state = 0; 1561 dlm->reco.state = 0;
1501 1562
1502 INIT_LIST_HEAD(&dlm->pending_asts); 1563 INIT_LIST_HEAD(&dlm->pending_asts);
@@ -1787,21 +1848,49 @@ static int __init dlm_init(void)
1787 dlm_print_version(); 1848 dlm_print_version();
1788 1849
1789 status = dlm_init_mle_cache(); 1850 status = dlm_init_mle_cache();
1790 if (status) 1851 if (status) {
1791 return -1; 1852 mlog(ML_ERROR, "Could not create o2dlm_mle slabcache\n");
1853 goto error;
1854 }
1855
1856 status = dlm_init_master_caches();
1857 if (status) {
1858 mlog(ML_ERROR, "Could not create o2dlm_lockres and "
1859 "o2dlm_lockname slabcaches\n");
1860 goto error;
1861 }
1862
1863 status = dlm_init_lock_cache();
1864 if (status) {
1865 mlog(ML_ERROR, "Count not create o2dlm_lock slabcache\n");
1866 goto error;
1867 }
1792 1868
1793 status = dlm_register_net_handlers(); 1869 status = dlm_register_net_handlers();
1794 if (status) { 1870 if (status) {
1795 dlm_destroy_mle_cache(); 1871 mlog(ML_ERROR, "Unable to register network handlers\n");
1796 return -1; 1872 goto error;
1797 } 1873 }
1798 1874
1875 status = dlm_create_debugfs_root();
1876 if (status)
1877 goto error;
1878
1799 return 0; 1879 return 0;
1880error:
1881 dlm_unregister_net_handlers();
1882 dlm_destroy_lock_cache();
1883 dlm_destroy_master_caches();
1884 dlm_destroy_mle_cache();
1885 return -1;
1800} 1886}
1801 1887
1802static void __exit dlm_exit (void) 1888static void __exit dlm_exit (void)
1803{ 1889{
1890 dlm_destroy_debugfs_root();
1804 dlm_unregister_net_handlers(); 1891 dlm_unregister_net_handlers();
1892 dlm_destroy_lock_cache();
1893 dlm_destroy_master_caches();
1805 dlm_destroy_mle_cache(); 1894 dlm_destroy_mle_cache();
1806} 1895}
1807 1896