diff options
Diffstat (limited to 'fs/dlm')
-rw-r--r-- | fs/dlm/config.c | 79 | ||||
-rw-r--r-- | fs/dlm/config.h | 2 | ||||
-rw-r--r-- | fs/dlm/lowcomms.c | 205 | ||||
-rw-r--r-- | fs/dlm/lowcomms.h | 2 | ||||
-rw-r--r-- | fs/dlm/main.c | 2 |
5 files changed, 200 insertions, 90 deletions
diff --git a/fs/dlm/config.c b/fs/dlm/config.c index 9ccf7346834a..a0387dd8b1f0 100644 --- a/fs/dlm/config.c +++ b/fs/dlm/config.c | |||
@@ -750,6 +750,7 @@ static ssize_t comm_local_write(struct dlm_comm *cm, const char *buf, | |||
750 | static ssize_t comm_addr_write(struct dlm_comm *cm, const char *buf, size_t len) | 750 | static ssize_t comm_addr_write(struct dlm_comm *cm, const char *buf, size_t len) |
751 | { | 751 | { |
752 | struct sockaddr_storage *addr; | 752 | struct sockaddr_storage *addr; |
753 | int rv; | ||
753 | 754 | ||
754 | if (len != sizeof(struct sockaddr_storage)) | 755 | if (len != sizeof(struct sockaddr_storage)) |
755 | return -EINVAL; | 756 | return -EINVAL; |
@@ -762,6 +763,13 @@ static ssize_t comm_addr_write(struct dlm_comm *cm, const char *buf, size_t len) | |||
762 | return -ENOMEM; | 763 | return -ENOMEM; |
763 | 764 | ||
764 | memcpy(addr, buf, len); | 765 | memcpy(addr, buf, len); |
766 | |||
767 | rv = dlm_lowcomms_addr(cm->nodeid, addr, len); | ||
768 | if (rv) { | ||
769 | kfree(addr); | ||
770 | return rv; | ||
771 | } | ||
772 | |||
765 | cm->addr[cm->addr_count++] = addr; | 773 | cm->addr[cm->addr_count++] = addr; |
766 | return len; | 774 | return len; |
767 | } | 775 | } |
@@ -878,34 +886,7 @@ static void put_space(struct dlm_space *sp) | |||
878 | config_item_put(&sp->group.cg_item); | 886 | config_item_put(&sp->group.cg_item); |
879 | } | 887 | } |
880 | 888 | ||
881 | static int addr_compare(struct sockaddr_storage *x, struct sockaddr_storage *y) | 889 | static struct dlm_comm *get_comm(int nodeid) |
882 | { | ||
883 | switch (x->ss_family) { | ||
884 | case AF_INET: { | ||
885 | struct sockaddr_in *sinx = (struct sockaddr_in *)x; | ||
886 | struct sockaddr_in *siny = (struct sockaddr_in *)y; | ||
887 | if (sinx->sin_addr.s_addr != siny->sin_addr.s_addr) | ||
888 | return 0; | ||
889 | if (sinx->sin_port != siny->sin_port) | ||
890 | return 0; | ||
891 | break; | ||
892 | } | ||
893 | case AF_INET6: { | ||
894 | struct sockaddr_in6 *sinx = (struct sockaddr_in6 *)x; | ||
895 | struct sockaddr_in6 *siny = (struct sockaddr_in6 *)y; | ||
896 | if (!ipv6_addr_equal(&sinx->sin6_addr, &siny->sin6_addr)) | ||
897 | return 0; | ||
898 | if (sinx->sin6_port != siny->sin6_port) | ||
899 | return 0; | ||
900 | break; | ||
901 | } | ||
902 | default: | ||
903 | return 0; | ||
904 | } | ||
905 | return 1; | ||
906 | } | ||
907 | |||
908 | static struct dlm_comm *get_comm(int nodeid, struct sockaddr_storage *addr) | ||
909 | { | 890 | { |
910 | struct config_item *i; | 891 | struct config_item *i; |
911 | struct dlm_comm *cm = NULL; | 892 | struct dlm_comm *cm = NULL; |
@@ -919,19 +900,11 @@ static struct dlm_comm *get_comm(int nodeid, struct sockaddr_storage *addr) | |||
919 | list_for_each_entry(i, &comm_list->cg_children, ci_entry) { | 900 | list_for_each_entry(i, &comm_list->cg_children, ci_entry) { |
920 | cm = config_item_to_comm(i); | 901 | cm = config_item_to_comm(i); |
921 | 902 | ||
922 | if (nodeid) { | 903 | if (cm->nodeid != nodeid) |
923 | if (cm->nodeid != nodeid) | 904 | continue; |
924 | continue; | 905 | found = 1; |
925 | found = 1; | 906 | config_item_get(i); |
926 | config_item_get(i); | 907 | break; |
927 | break; | ||
928 | } else { | ||
929 | if (!cm->addr_count || !addr_compare(cm->addr[0], addr)) | ||
930 | continue; | ||
931 | found = 1; | ||
932 | config_item_get(i); | ||
933 | break; | ||
934 | } | ||
935 | } | 908 | } |
936 | mutex_unlock(&clusters_root.subsys.su_mutex); | 909 | mutex_unlock(&clusters_root.subsys.su_mutex); |
937 | 910 | ||
@@ -995,7 +968,7 @@ int dlm_config_nodes(char *lsname, struct dlm_config_node **nodes_out, | |||
995 | 968 | ||
996 | int dlm_comm_seq(int nodeid, uint32_t *seq) | 969 | int dlm_comm_seq(int nodeid, uint32_t *seq) |
997 | { | 970 | { |
998 | struct dlm_comm *cm = get_comm(nodeid, NULL); | 971 | struct dlm_comm *cm = get_comm(nodeid); |
999 | if (!cm) | 972 | if (!cm) |
1000 | return -EEXIST; | 973 | return -EEXIST; |
1001 | *seq = cm->seq; | 974 | *seq = cm->seq; |
@@ -1003,28 +976,6 @@ int dlm_comm_seq(int nodeid, uint32_t *seq) | |||
1003 | return 0; | 976 | return 0; |
1004 | } | 977 | } |
1005 | 978 | ||
1006 | int dlm_nodeid_to_addr(int nodeid, struct sockaddr_storage *addr) | ||
1007 | { | ||
1008 | struct dlm_comm *cm = get_comm(nodeid, NULL); | ||
1009 | if (!cm) | ||
1010 | return -EEXIST; | ||
1011 | if (!cm->addr_count) | ||
1012 | return -ENOENT; | ||
1013 | memcpy(addr, cm->addr[0], sizeof(*addr)); | ||
1014 | put_comm(cm); | ||
1015 | return 0; | ||
1016 | } | ||
1017 | |||
1018 | int dlm_addr_to_nodeid(struct sockaddr_storage *addr, int *nodeid) | ||
1019 | { | ||
1020 | struct dlm_comm *cm = get_comm(0, addr); | ||
1021 | if (!cm) | ||
1022 | return -EEXIST; | ||
1023 | *nodeid = cm->nodeid; | ||
1024 | put_comm(cm); | ||
1025 | return 0; | ||
1026 | } | ||
1027 | |||
1028 | int dlm_our_nodeid(void) | 979 | int dlm_our_nodeid(void) |
1029 | { | 980 | { |
1030 | return local_comm ? local_comm->nodeid : 0; | 981 | return local_comm ? local_comm->nodeid : 0; |
diff --git a/fs/dlm/config.h b/fs/dlm/config.h index dbd35a08f3a5..f30697bc2780 100644 --- a/fs/dlm/config.h +++ b/fs/dlm/config.h | |||
@@ -46,8 +46,6 @@ void dlm_config_exit(void); | |||
46 | int dlm_config_nodes(char *lsname, struct dlm_config_node **nodes_out, | 46 | int dlm_config_nodes(char *lsname, struct dlm_config_node **nodes_out, |
47 | int *count_out); | 47 | int *count_out); |
48 | int dlm_comm_seq(int nodeid, uint32_t *seq); | 48 | int dlm_comm_seq(int nodeid, uint32_t *seq); |
49 | int dlm_nodeid_to_addr(int nodeid, struct sockaddr_storage *addr); | ||
50 | int dlm_addr_to_nodeid(struct sockaddr_storage *addr, int *nodeid); | ||
51 | int dlm_our_nodeid(void); | 49 | int dlm_our_nodeid(void); |
52 | int dlm_our_addr(struct sockaddr_storage *addr, int num); | 50 | int dlm_our_addr(struct sockaddr_storage *addr, int num); |
53 | 51 | ||
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 5c1b0e38c7a4..522a69fccd84 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c | |||
@@ -140,6 +140,16 @@ struct writequeue_entry { | |||
140 | struct connection *con; | 140 | struct connection *con; |
141 | }; | 141 | }; |
142 | 142 | ||
143 | struct dlm_node_addr { | ||
144 | struct list_head list; | ||
145 | int nodeid; | ||
146 | int addr_count; | ||
147 | struct sockaddr_storage *addr[DLM_MAX_ADDR_COUNT]; | ||
148 | }; | ||
149 | |||
150 | static LIST_HEAD(dlm_node_addrs); | ||
151 | static DEFINE_SPINLOCK(dlm_node_addrs_spin); | ||
152 | |||
143 | static struct sockaddr_storage *dlm_local_addr[DLM_MAX_ADDR_COUNT]; | 153 | static struct sockaddr_storage *dlm_local_addr[DLM_MAX_ADDR_COUNT]; |
144 | static int dlm_local_count; | 154 | static int dlm_local_count; |
145 | static int dlm_allow_conn; | 155 | static int dlm_allow_conn; |
@@ -264,31 +274,146 @@ static struct connection *assoc2con(int assoc_id) | |||
264 | return NULL; | 274 | return NULL; |
265 | } | 275 | } |
266 | 276 | ||
267 | static int nodeid_to_addr(int nodeid, struct sockaddr *retaddr) | 277 | static struct dlm_node_addr *find_node_addr(int nodeid) |
278 | { | ||
279 | struct dlm_node_addr *na; | ||
280 | |||
281 | list_for_each_entry(na, &dlm_node_addrs, list) { | ||
282 | if (na->nodeid == nodeid) | ||
283 | return na; | ||
284 | } | ||
285 | return NULL; | ||
286 | } | ||
287 | |||
288 | static int addr_compare(struct sockaddr_storage *x, struct sockaddr_storage *y) | ||
268 | { | 289 | { |
269 | struct sockaddr_storage addr; | 290 | switch (x->ss_family) { |
270 | int error; | 291 | case AF_INET: { |
292 | struct sockaddr_in *sinx = (struct sockaddr_in *)x; | ||
293 | struct sockaddr_in *siny = (struct sockaddr_in *)y; | ||
294 | if (sinx->sin_addr.s_addr != siny->sin_addr.s_addr) | ||
295 | return 0; | ||
296 | if (sinx->sin_port != siny->sin_port) | ||
297 | return 0; | ||
298 | break; | ||
299 | } | ||
300 | case AF_INET6: { | ||
301 | struct sockaddr_in6 *sinx = (struct sockaddr_in6 *)x; | ||
302 | struct sockaddr_in6 *siny = (struct sockaddr_in6 *)y; | ||
303 | if (!ipv6_addr_equal(&sinx->sin6_addr, &siny->sin6_addr)) | ||
304 | return 0; | ||
305 | if (sinx->sin6_port != siny->sin6_port) | ||
306 | return 0; | ||
307 | break; | ||
308 | } | ||
309 | default: | ||
310 | return 0; | ||
311 | } | ||
312 | return 1; | ||
313 | } | ||
314 | |||
315 | static int nodeid_to_addr(int nodeid, struct sockaddr_storage *sas_out, | ||
316 | struct sockaddr *sa_out) | ||
317 | { | ||
318 | struct sockaddr_storage sas; | ||
319 | struct dlm_node_addr *na; | ||
271 | 320 | ||
272 | if (!dlm_local_count) | 321 | if (!dlm_local_count) |
273 | return -1; | 322 | return -1; |
274 | 323 | ||
275 | error = dlm_nodeid_to_addr(nodeid, &addr); | 324 | spin_lock(&dlm_node_addrs_spin); |
276 | if (error) | 325 | na = find_node_addr(nodeid); |
277 | return error; | 326 | if (na && na->addr_count) |
327 | memcpy(&sas, na->addr[0], sizeof(struct sockaddr_storage)); | ||
328 | spin_unlock(&dlm_node_addrs_spin); | ||
329 | |||
330 | if (!na) | ||
331 | return -EEXIST; | ||
332 | |||
333 | if (!na->addr_count) | ||
334 | return -ENOENT; | ||
335 | |||
336 | if (sas_out) | ||
337 | memcpy(sas_out, &sas, sizeof(struct sockaddr_storage)); | ||
338 | |||
339 | if (!sa_out) | ||
340 | return 0; | ||
278 | 341 | ||
279 | if (dlm_local_addr[0]->ss_family == AF_INET) { | 342 | if (dlm_local_addr[0]->ss_family == AF_INET) { |
280 | struct sockaddr_in *in4 = (struct sockaddr_in *) &addr; | 343 | struct sockaddr_in *in4 = (struct sockaddr_in *) &sas; |
281 | struct sockaddr_in *ret4 = (struct sockaddr_in *) retaddr; | 344 | struct sockaddr_in *ret4 = (struct sockaddr_in *) sa_out; |
282 | ret4->sin_addr.s_addr = in4->sin_addr.s_addr; | 345 | ret4->sin_addr.s_addr = in4->sin_addr.s_addr; |
283 | } else { | 346 | } else { |
284 | struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &addr; | 347 | struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &sas; |
285 | struct sockaddr_in6 *ret6 = (struct sockaddr_in6 *) retaddr; | 348 | struct sockaddr_in6 *ret6 = (struct sockaddr_in6 *) sa_out; |
286 | ret6->sin6_addr = in6->sin6_addr; | 349 | ret6->sin6_addr = in6->sin6_addr; |
287 | } | 350 | } |
288 | 351 | ||
289 | return 0; | 352 | return 0; |
290 | } | 353 | } |
291 | 354 | ||
355 | static int addr_to_nodeid(struct sockaddr_storage *addr, int *nodeid) | ||
356 | { | ||
357 | struct dlm_node_addr *na; | ||
358 | int rv = -EEXIST; | ||
359 | |||
360 | spin_lock(&dlm_node_addrs_spin); | ||
361 | list_for_each_entry(na, &dlm_node_addrs, list) { | ||
362 | if (!na->addr_count) | ||
363 | continue; | ||
364 | |||
365 | if (!addr_compare(na->addr[0], addr)) | ||
366 | continue; | ||
367 | |||
368 | *nodeid = na->nodeid; | ||
369 | rv = 0; | ||
370 | break; | ||
371 | } | ||
372 | spin_unlock(&dlm_node_addrs_spin); | ||
373 | return rv; | ||
374 | } | ||
375 | |||
376 | int dlm_lowcomms_addr(int nodeid, struct sockaddr_storage *addr, int len) | ||
377 | { | ||
378 | struct sockaddr_storage *new_addr; | ||
379 | struct dlm_node_addr *new_node, *na; | ||
380 | |||
381 | new_node = kzalloc(sizeof(struct dlm_node_addr), GFP_NOFS); | ||
382 | if (!new_node) | ||
383 | return -ENOMEM; | ||
384 | |||
385 | new_addr = kzalloc(sizeof(struct sockaddr_storage), GFP_NOFS); | ||
386 | if (!new_addr) { | ||
387 | kfree(new_node); | ||
388 | return -ENOMEM; | ||
389 | } | ||
390 | |||
391 | memcpy(new_addr, addr, len); | ||
392 | |||
393 | spin_lock(&dlm_node_addrs_spin); | ||
394 | na = find_node_addr(nodeid); | ||
395 | if (!na) { | ||
396 | new_node->nodeid = nodeid; | ||
397 | new_node->addr[0] = new_addr; | ||
398 | new_node->addr_count = 1; | ||
399 | list_add(&new_node->list, &dlm_node_addrs); | ||
400 | spin_unlock(&dlm_node_addrs_spin); | ||
401 | return 0; | ||
402 | } | ||
403 | |||
404 | if (na->addr_count >= DLM_MAX_ADDR_COUNT) { | ||
405 | spin_unlock(&dlm_node_addrs_spin); | ||
406 | kfree(new_addr); | ||
407 | kfree(new_node); | ||
408 | return -ENOSPC; | ||
409 | } | ||
410 | |||
411 | na->addr[na->addr_count++] = new_addr; | ||
412 | spin_unlock(&dlm_node_addrs_spin); | ||
413 | kfree(new_node); | ||
414 | return 0; | ||
415 | } | ||
416 | |||
292 | /* Data available on socket or listen socket received a connect */ | 417 | /* Data available on socket or listen socket received a connect */ |
293 | static void lowcomms_data_ready(struct sock *sk, int count_unused) | 418 | static void lowcomms_data_ready(struct sock *sk, int count_unused) |
294 | { | 419 | { |
@@ -510,7 +635,7 @@ static void process_sctp_notification(struct connection *con, | |||
510 | return; | 635 | return; |
511 | } | 636 | } |
512 | make_sockaddr(&prim.ssp_addr, 0, &addr_len); | 637 | make_sockaddr(&prim.ssp_addr, 0, &addr_len); |
513 | if (dlm_addr_to_nodeid(&prim.ssp_addr, &nodeid)) { | 638 | if (addr_to_nodeid(&prim.ssp_addr, &nodeid)) { |
514 | unsigned char *b=(unsigned char *)&prim.ssp_addr; | 639 | unsigned char *b=(unsigned char *)&prim.ssp_addr; |
515 | log_print("reject connect from unknown addr"); | 640 | log_print("reject connect from unknown addr"); |
516 | print_hex_dump_bytes("ss: ", DUMP_PREFIX_NONE, | 641 | print_hex_dump_bytes("ss: ", DUMP_PREFIX_NONE, |
@@ -747,7 +872,7 @@ static int tcp_accept_from_sock(struct connection *con) | |||
747 | 872 | ||
748 | /* Get the new node's NODEID */ | 873 | /* Get the new node's NODEID */ |
749 | make_sockaddr(&peeraddr, 0, &len); | 874 | make_sockaddr(&peeraddr, 0, &len); |
750 | if (dlm_addr_to_nodeid(&peeraddr, &nodeid)) { | 875 | if (addr_to_nodeid(&peeraddr, &nodeid)) { |
751 | unsigned char *b=(unsigned char *)&peeraddr; | 876 | unsigned char *b=(unsigned char *)&peeraddr; |
752 | log_print("connect from non cluster node"); | 877 | log_print("connect from non cluster node"); |
753 | print_hex_dump_bytes("ss: ", DUMP_PREFIX_NONE, | 878 | print_hex_dump_bytes("ss: ", DUMP_PREFIX_NONE, |
@@ -862,7 +987,7 @@ static void sctp_init_assoc(struct connection *con) | |||
862 | if (con->retries++ > MAX_CONNECT_RETRIES) | 987 | if (con->retries++ > MAX_CONNECT_RETRIES) |
863 | return; | 988 | return; |
864 | 989 | ||
865 | if (nodeid_to_addr(con->nodeid, (struct sockaddr *)&rem_addr)) { | 990 | if (nodeid_to_addr(con->nodeid, NULL, (struct sockaddr *)&rem_addr)) { |
866 | log_print("no address for nodeid %d", con->nodeid); | 991 | log_print("no address for nodeid %d", con->nodeid); |
867 | return; | 992 | return; |
868 | } | 993 | } |
@@ -928,11 +1053,11 @@ static void sctp_init_assoc(struct connection *con) | |||
928 | /* Connect a new socket to its peer */ | 1053 | /* Connect a new socket to its peer */ |
929 | static void tcp_connect_to_sock(struct connection *con) | 1054 | static void tcp_connect_to_sock(struct connection *con) |
930 | { | 1055 | { |
931 | int result = -EHOSTUNREACH; | ||
932 | struct sockaddr_storage saddr, src_addr; | 1056 | struct sockaddr_storage saddr, src_addr; |
933 | int addr_len; | 1057 | int addr_len; |
934 | struct socket *sock = NULL; | 1058 | struct socket *sock = NULL; |
935 | int one = 1; | 1059 | int one = 1; |
1060 | int result; | ||
936 | 1061 | ||
937 | if (con->nodeid == 0) { | 1062 | if (con->nodeid == 0) { |
938 | log_print("attempt to connect sock 0 foiled"); | 1063 | log_print("attempt to connect sock 0 foiled"); |
@@ -944,10 +1069,8 @@ static void tcp_connect_to_sock(struct connection *con) | |||
944 | goto out; | 1069 | goto out; |
945 | 1070 | ||
946 | /* Some odd races can cause double-connects, ignore them */ | 1071 | /* Some odd races can cause double-connects, ignore them */ |
947 | if (con->sock) { | 1072 | if (con->sock) |
948 | result = 0; | ||
949 | goto out; | 1073 | goto out; |
950 | } | ||
951 | 1074 | ||
952 | /* Create a socket to communicate with */ | 1075 | /* Create a socket to communicate with */ |
953 | result = sock_create_kern(dlm_local_addr[0]->ss_family, SOCK_STREAM, | 1076 | result = sock_create_kern(dlm_local_addr[0]->ss_family, SOCK_STREAM, |
@@ -956,8 +1079,11 @@ static void tcp_connect_to_sock(struct connection *con) | |||
956 | goto out_err; | 1079 | goto out_err; |
957 | 1080 | ||
958 | memset(&saddr, 0, sizeof(saddr)); | 1081 | memset(&saddr, 0, sizeof(saddr)); |
959 | if (dlm_nodeid_to_addr(con->nodeid, &saddr)) | 1082 | result = nodeid_to_addr(con->nodeid, &saddr, NULL); |
1083 | if (result < 0) { | ||
1084 | log_print("no address for nodeid %d", con->nodeid); | ||
960 | goto out_err; | 1085 | goto out_err; |
1086 | } | ||
961 | 1087 | ||
962 | sock->sk->sk_user_data = con; | 1088 | sock->sk->sk_user_data = con; |
963 | con->rx_action = receive_from_sock; | 1089 | con->rx_action = receive_from_sock; |
@@ -983,8 +1109,7 @@ static void tcp_connect_to_sock(struct connection *con) | |||
983 | kernel_setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&one, | 1109 | kernel_setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&one, |
984 | sizeof(one)); | 1110 | sizeof(one)); |
985 | 1111 | ||
986 | result = | 1112 | result = sock->ops->connect(sock, (struct sockaddr *)&saddr, addr_len, |
987 | sock->ops->connect(sock, (struct sockaddr *)&saddr, addr_len, | ||
988 | O_NONBLOCK); | 1113 | O_NONBLOCK); |
989 | if (result == -EINPROGRESS) | 1114 | if (result == -EINPROGRESS) |
990 | result = 0; | 1115 | result = 0; |
@@ -1002,11 +1127,17 @@ out_err: | |||
1002 | * Some errors are fatal and this list might need adjusting. For other | 1127 | * Some errors are fatal and this list might need adjusting. For other |
1003 | * errors we try again until the max number of retries is reached. | 1128 | * errors we try again until the max number of retries is reached. |
1004 | */ | 1129 | */ |
1005 | if (result != -EHOSTUNREACH && result != -ENETUNREACH && | 1130 | if (result != -EHOSTUNREACH && |
1006 | result != -ENETDOWN && result != -EINVAL | 1131 | result != -ENETUNREACH && |
1007 | && result != -EPROTONOSUPPORT) { | 1132 | result != -ENETDOWN && |
1133 | result != -EINVAL && | ||
1134 | result != -EPROTONOSUPPORT) { | ||
1135 | log_print("connect %d try %d error %d", con->nodeid, | ||
1136 | con->retries, result); | ||
1137 | mutex_unlock(&con->sock_mutex); | ||
1138 | msleep(1000); | ||
1008 | lowcomms_connect_sock(con); | 1139 | lowcomms_connect_sock(con); |
1009 | result = 0; | 1140 | return; |
1010 | } | 1141 | } |
1011 | out: | 1142 | out: |
1012 | mutex_unlock(&con->sock_mutex); | 1143 | mutex_unlock(&con->sock_mutex); |
@@ -1414,6 +1545,7 @@ static void clean_one_writequeue(struct connection *con) | |||
1414 | int dlm_lowcomms_close(int nodeid) | 1545 | int dlm_lowcomms_close(int nodeid) |
1415 | { | 1546 | { |
1416 | struct connection *con; | 1547 | struct connection *con; |
1548 | struct dlm_node_addr *na; | ||
1417 | 1549 | ||
1418 | log_print("closing connection to node %d", nodeid); | 1550 | log_print("closing connection to node %d", nodeid); |
1419 | con = nodeid2con(nodeid, 0); | 1551 | con = nodeid2con(nodeid, 0); |
@@ -1428,6 +1560,17 @@ int dlm_lowcomms_close(int nodeid) | |||
1428 | clean_one_writequeue(con); | 1560 | clean_one_writequeue(con); |
1429 | close_connection(con, true); | 1561 | close_connection(con, true); |
1430 | } | 1562 | } |
1563 | |||
1564 | spin_lock(&dlm_node_addrs_spin); | ||
1565 | na = find_node_addr(nodeid); | ||
1566 | if (na) { | ||
1567 | list_del(&na->list); | ||
1568 | while (na->addr_count--) | ||
1569 | kfree(na->addr[na->addr_count]); | ||
1570 | kfree(na); | ||
1571 | } | ||
1572 | spin_unlock(&dlm_node_addrs_spin); | ||
1573 | |||
1431 | return 0; | 1574 | return 0; |
1432 | } | 1575 | } |
1433 | 1576 | ||
@@ -1577,3 +1720,17 @@ fail_destroy: | |||
1577 | fail: | 1720 | fail: |
1578 | return error; | 1721 | return error; |
1579 | } | 1722 | } |
1723 | |||
1724 | void dlm_lowcomms_exit(void) | ||
1725 | { | ||
1726 | struct dlm_node_addr *na, *safe; | ||
1727 | |||
1728 | spin_lock(&dlm_node_addrs_spin); | ||
1729 | list_for_each_entry_safe(na, safe, &dlm_node_addrs, list) { | ||
1730 | list_del(&na->list); | ||
1731 | while (na->addr_count--) | ||
1732 | kfree(na->addr[na->addr_count]); | ||
1733 | kfree(na); | ||
1734 | } | ||
1735 | spin_unlock(&dlm_node_addrs_spin); | ||
1736 | } | ||
diff --git a/fs/dlm/lowcomms.h b/fs/dlm/lowcomms.h index 1311e6426287..67462e54fc2f 100644 --- a/fs/dlm/lowcomms.h +++ b/fs/dlm/lowcomms.h | |||
@@ -16,10 +16,12 @@ | |||
16 | 16 | ||
17 | int dlm_lowcomms_start(void); | 17 | int dlm_lowcomms_start(void); |
18 | void dlm_lowcomms_stop(void); | 18 | void dlm_lowcomms_stop(void); |
19 | void dlm_lowcomms_exit(void); | ||
19 | int dlm_lowcomms_close(int nodeid); | 20 | int dlm_lowcomms_close(int nodeid); |
20 | void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc); | 21 | void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc); |
21 | void dlm_lowcomms_commit_buffer(void *mh); | 22 | void dlm_lowcomms_commit_buffer(void *mh); |
22 | int dlm_lowcomms_connect_node(int nodeid); | 23 | int dlm_lowcomms_connect_node(int nodeid); |
24 | int dlm_lowcomms_addr(int nodeid, struct sockaddr_storage *addr, int len); | ||
23 | 25 | ||
24 | #endif /* __LOWCOMMS_DOT_H__ */ | 26 | #endif /* __LOWCOMMS_DOT_H__ */ |
25 | 27 | ||
diff --git a/fs/dlm/main.c b/fs/dlm/main.c index 5a59efa0bb46..079c0bd71ab7 100644 --- a/fs/dlm/main.c +++ b/fs/dlm/main.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include "user.h" | 17 | #include "user.h" |
18 | #include "memory.h" | 18 | #include "memory.h" |
19 | #include "config.h" | 19 | #include "config.h" |
20 | #include "lowcomms.h" | ||
20 | 21 | ||
21 | static int __init init_dlm(void) | 22 | static int __init init_dlm(void) |
22 | { | 23 | { |
@@ -78,6 +79,7 @@ static void __exit exit_dlm(void) | |||
78 | dlm_config_exit(); | 79 | dlm_config_exit(); |
79 | dlm_memory_exit(); | 80 | dlm_memory_exit(); |
80 | dlm_lockspace_exit(); | 81 | dlm_lockspace_exit(); |
82 | dlm_lowcomms_exit(); | ||
81 | dlm_unregister_debugfs(); | 83 | dlm_unregister_debugfs(); |
82 | } | 84 | } |
83 | 85 | ||