diff options
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/bcast.c | 14 | ||||
-rw-r--r-- | net/tipc/bearer.c | 8 | ||||
-rw-r--r-- | net/tipc/cluster.c | 4 | ||||
-rw-r--r-- | net/tipc/config.c | 11 | ||||
-rw-r--r-- | net/tipc/core.c | 13 | ||||
-rw-r--r-- | net/tipc/core.h | 126 | ||||
-rw-r--r-- | net/tipc/dbg.c | 231 | ||||
-rw-r--r-- | net/tipc/dbg.h | 12 | ||||
-rw-r--r-- | net/tipc/discover.c | 14 | ||||
-rw-r--r-- | net/tipc/discover.h | 2 | ||||
-rw-r--r-- | net/tipc/eth_media.c | 10 | ||||
-rw-r--r-- | net/tipc/link.c | 98 | ||||
-rw-r--r-- | net/tipc/msg.c | 13 | ||||
-rw-r--r-- | net/tipc/msg.h | 42 | ||||
-rw-r--r-- | net/tipc/name_distr.c | 6 | ||||
-rw-r--r-- | net/tipc/name_table.c | 55 | ||||
-rw-r--r-- | net/tipc/net.c | 14 | ||||
-rw-r--r-- | net/tipc/net.h | 2 | ||||
-rw-r--r-- | net/tipc/netlink.c | 16 | ||||
-rw-r--r-- | net/tipc/node.c | 55 | ||||
-rw-r--r-- | net/tipc/port.c | 115 | ||||
-rw-r--r-- | net/tipc/ref.c | 14 | ||||
-rw-r--r-- | net/tipc/socket.c | 62 | ||||
-rw-r--r-- | net/tipc/subscr.c | 249 | ||||
-rw-r--r-- | net/tipc/subscr.h | 34 | ||||
-rw-r--r-- | net/tipc/user_reg.c | 14 |
26 files changed, 687 insertions, 547 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index e7880172ef19..b1ff16aa4bdb 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
@@ -276,7 +276,7 @@ static void bclink_send_nack(struct node *n_ptr) | |||
276 | if (buf) { | 276 | if (buf) { |
277 | msg = buf_msg(buf); | 277 | msg = buf_msg(buf); |
278 | msg_init(msg, BCAST_PROTOCOL, STATE_MSG, | 278 | msg_init(msg, BCAST_PROTOCOL, STATE_MSG, |
279 | TIPC_OK, INT_H_SIZE, n_ptr->addr); | 279 | INT_H_SIZE, n_ptr->addr); |
280 | msg_set_mc_netid(msg, tipc_net_id); | 280 | msg_set_mc_netid(msg, tipc_net_id); |
281 | msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in)); | 281 | msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in)); |
282 | msg_set_bcgap_after(msg, n_ptr->bclink.gap_after); | 282 | msg_set_bcgap_after(msg, n_ptr->bclink.gap_after); |
@@ -571,7 +571,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
571 | assert(tipc_cltr_bcast_nodes.count != 0); | 571 | assert(tipc_cltr_bcast_nodes.count != 0); |
572 | bcbuf_set_acks(buf, tipc_cltr_bcast_nodes.count); | 572 | bcbuf_set_acks(buf, tipc_cltr_bcast_nodes.count); |
573 | msg = buf_msg(buf); | 573 | msg = buf_msg(buf); |
574 | msg_set_non_seq(msg); | 574 | msg_set_non_seq(msg, 1); |
575 | msg_set_mc_netid(msg, tipc_net_id); | 575 | msg_set_mc_netid(msg, tipc_net_id); |
576 | } | 576 | } |
577 | 577 | ||
@@ -611,7 +611,7 @@ swap: | |||
611 | bcbearer->bpairs[bp_index].secondary = p; | 611 | bcbearer->bpairs[bp_index].secondary = p; |
612 | update: | 612 | update: |
613 | if (bcbearer->remains_new.count == 0) | 613 | if (bcbearer->remains_new.count == 0) |
614 | return TIPC_OK; | 614 | return 0; |
615 | 615 | ||
616 | bcbearer->remains = bcbearer->remains_new; | 616 | bcbearer->remains = bcbearer->remains_new; |
617 | } | 617 | } |
@@ -620,7 +620,7 @@ update: | |||
620 | 620 | ||
621 | bcbearer->bearer.publ.blocked = 1; | 621 | bcbearer->bearer.publ.blocked = 1; |
622 | bcl->stats.bearer_congs++; | 622 | bcl->stats.bearer_congs++; |
623 | return ~TIPC_OK; | 623 | return 1; |
624 | } | 624 | } |
625 | 625 | ||
626 | /** | 626 | /** |
@@ -756,7 +756,7 @@ int tipc_bclink_reset_stats(void) | |||
756 | spin_lock_bh(&bc_lock); | 756 | spin_lock_bh(&bc_lock); |
757 | memset(&bcl->stats, 0, sizeof(bcl->stats)); | 757 | memset(&bcl->stats, 0, sizeof(bcl->stats)); |
758 | spin_unlock_bh(&bc_lock); | 758 | spin_unlock_bh(&bc_lock); |
759 | return TIPC_OK; | 759 | return 0; |
760 | } | 760 | } |
761 | 761 | ||
762 | int tipc_bclink_set_queue_limits(u32 limit) | 762 | int tipc_bclink_set_queue_limits(u32 limit) |
@@ -769,7 +769,7 @@ int tipc_bclink_set_queue_limits(u32 limit) | |||
769 | spin_lock_bh(&bc_lock); | 769 | spin_lock_bh(&bc_lock); |
770 | tipc_link_set_queue_limits(bcl, limit); | 770 | tipc_link_set_queue_limits(bcl, limit); |
771 | spin_unlock_bh(&bc_lock); | 771 | spin_unlock_bh(&bc_lock); |
772 | return TIPC_OK; | 772 | return 0; |
773 | } | 773 | } |
774 | 774 | ||
775 | int tipc_bclink_init(void) | 775 | int tipc_bclink_init(void) |
@@ -810,7 +810,7 @@ int tipc_bclink_init(void) | |||
810 | tipc_printbuf_init(&bcl->print_buf, pb, BCLINK_LOG_BUF_SIZE); | 810 | tipc_printbuf_init(&bcl->print_buf, pb, BCLINK_LOG_BUF_SIZE); |
811 | } | 811 | } |
812 | 812 | ||
813 | return TIPC_OK; | 813 | return 0; |
814 | } | 814 | } |
815 | 815 | ||
816 | void tipc_bclink_stop(void) | 816 | void tipc_bclink_stop(void) |
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 271a375b49b7..6a9aba3edd08 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c | |||
@@ -370,7 +370,7 @@ void tipc_bearer_remove_dest(struct bearer *b_ptr, u32 dest) | |||
370 | */ | 370 | */ |
371 | static int bearer_push(struct bearer *b_ptr) | 371 | static int bearer_push(struct bearer *b_ptr) |
372 | { | 372 | { |
373 | u32 res = TIPC_OK; | 373 | u32 res = 0; |
374 | struct link *ln, *tln; | 374 | struct link *ln, *tln; |
375 | 375 | ||
376 | if (b_ptr->publ.blocked) | 376 | if (b_ptr->publ.blocked) |
@@ -607,7 +607,7 @@ int tipc_block_bearer(const char *name) | |||
607 | } | 607 | } |
608 | spin_unlock_bh(&b_ptr->publ.lock); | 608 | spin_unlock_bh(&b_ptr->publ.lock); |
609 | read_unlock_bh(&tipc_net_lock); | 609 | read_unlock_bh(&tipc_net_lock); |
610 | return TIPC_OK; | 610 | return 0; |
611 | } | 611 | } |
612 | 612 | ||
613 | /** | 613 | /** |
@@ -645,7 +645,7 @@ static int bearer_disable(const char *name) | |||
645 | } | 645 | } |
646 | spin_unlock_bh(&b_ptr->publ.lock); | 646 | spin_unlock_bh(&b_ptr->publ.lock); |
647 | memset(b_ptr, 0, sizeof(struct bearer)); | 647 | memset(b_ptr, 0, sizeof(struct bearer)); |
648 | return TIPC_OK; | 648 | return 0; |
649 | } | 649 | } |
650 | 650 | ||
651 | int tipc_disable_bearer(const char *name) | 651 | int tipc_disable_bearer(const char *name) |
@@ -668,7 +668,7 @@ int tipc_bearer_init(void) | |||
668 | tipc_bearers = kcalloc(MAX_BEARERS, sizeof(struct bearer), GFP_ATOMIC); | 668 | tipc_bearers = kcalloc(MAX_BEARERS, sizeof(struct bearer), GFP_ATOMIC); |
669 | media_list = kcalloc(MAX_MEDIA, sizeof(struct media), GFP_ATOMIC); | 669 | media_list = kcalloc(MAX_MEDIA, sizeof(struct media), GFP_ATOMIC); |
670 | if (tipc_bearers && media_list) { | 670 | if (tipc_bearers && media_list) { |
671 | res = TIPC_OK; | 671 | res = 0; |
672 | } else { | 672 | } else { |
673 | kfree(tipc_bearers); | 673 | kfree(tipc_bearers); |
674 | kfree(media_list); | 674 | kfree(media_list); |
diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c index 4bb3404f610b..46ee6c58532d 100644 --- a/net/tipc/cluster.c +++ b/net/tipc/cluster.c | |||
@@ -238,7 +238,7 @@ static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest) | |||
238 | if (buf) { | 238 | if (buf) { |
239 | msg = buf_msg(buf); | 239 | msg = buf_msg(buf); |
240 | memset((char *)msg, 0, size); | 240 | memset((char *)msg, 0, size); |
241 | msg_init(msg, ROUTE_DISTRIBUTOR, 0, TIPC_OK, INT_H_SIZE, dest); | 241 | msg_init(msg, ROUTE_DISTRIBUTOR, 0, INT_H_SIZE, dest); |
242 | } | 242 | } |
243 | return buf; | 243 | return buf; |
244 | } | 244 | } |
@@ -571,6 +571,6 @@ exit: | |||
571 | int tipc_cltr_init(void) | 571 | int tipc_cltr_init(void) |
572 | { | 572 | { |
573 | tipc_highest_allowed_slave = LOWEST_SLAVE + tipc_max_slaves; | 573 | tipc_highest_allowed_slave = LOWEST_SLAVE + tipc_max_slaves; |
574 | return tipc_cltr_create(tipc_own_addr) ? TIPC_OK : -ENOMEM; | 574 | return tipc_cltr_create(tipc_own_addr) ? 0 : -ENOMEM; |
575 | } | 575 | } |
576 | 576 | ||
diff --git a/net/tipc/config.c b/net/tipc/config.c index c71337a22d33..ca3544d030c7 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * net/tipc/config.c: TIPC configuration management code | 2 | * net/tipc/config.c: TIPC configuration management code |
3 | * | 3 | * |
4 | * Copyright (c) 2002-2006, Ericsson AB | 4 | * Copyright (c) 2002-2006, Ericsson AB |
5 | * Copyright (c) 2004-2006, Wind River Systems | 5 | * Copyright (c) 2004-2007, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -293,7 +293,6 @@ static struct sk_buff *cfg_set_own_addr(void) | |||
293 | if (tipc_mode == TIPC_NET_MODE) | 293 | if (tipc_mode == TIPC_NET_MODE) |
294 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | 294 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED |
295 | " (cannot change node address once assigned)"); | 295 | " (cannot change node address once assigned)"); |
296 | tipc_own_addr = addr; | ||
297 | 296 | ||
298 | /* | 297 | /* |
299 | * Must release all spinlocks before calling start_net() because | 298 | * Must release all spinlocks before calling start_net() because |
@@ -306,7 +305,7 @@ static struct sk_buff *cfg_set_own_addr(void) | |||
306 | */ | 305 | */ |
307 | 306 | ||
308 | spin_unlock_bh(&config_lock); | 307 | spin_unlock_bh(&config_lock); |
309 | tipc_core_start_net(); | 308 | tipc_core_start_net(addr); |
310 | spin_lock_bh(&config_lock); | 309 | spin_lock_bh(&config_lock); |
311 | return tipc_cfg_reply_none(); | 310 | return tipc_cfg_reply_none(); |
312 | } | 311 | } |
@@ -529,7 +528,7 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area | |||
529 | break; | 528 | break; |
530 | #endif | 529 | #endif |
531 | case TIPC_CMD_SET_LOG_SIZE: | 530 | case TIPC_CMD_SET_LOG_SIZE: |
532 | rep_tlv_buf = tipc_log_resize(req_tlv_area, req_tlv_space); | 531 | rep_tlv_buf = tipc_log_resize_cmd(req_tlv_area, req_tlv_space); |
533 | break; | 532 | break; |
534 | case TIPC_CMD_DUMP_LOG: | 533 | case TIPC_CMD_DUMP_LOG: |
535 | rep_tlv_buf = tipc_log_dump(); | 534 | rep_tlv_buf = tipc_log_dump(); |
@@ -602,6 +601,10 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area | |||
602 | case TIPC_CMD_GET_NETID: | 601 | case TIPC_CMD_GET_NETID: |
603 | rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id); | 602 | rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id); |
604 | break; | 603 | break; |
604 | case TIPC_CMD_NOT_NET_ADMIN: | ||
605 | rep_tlv_buf = | ||
606 | tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN); | ||
607 | break; | ||
605 | default: | 608 | default: |
606 | rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | 609 | rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED |
607 | " (unknown command)"); | 610 | " (unknown command)"); |
diff --git a/net/tipc/core.c b/net/tipc/core.c index 740aac5cdfb6..3256bd7d398f 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c | |||
@@ -49,7 +49,7 @@ | |||
49 | #include "config.h" | 49 | #include "config.h" |
50 | 50 | ||
51 | 51 | ||
52 | #define TIPC_MOD_VER "1.6.3" | 52 | #define TIPC_MOD_VER "1.6.4" |
53 | 53 | ||
54 | #ifndef CONFIG_TIPC_ZONES | 54 | #ifndef CONFIG_TIPC_ZONES |
55 | #define CONFIG_TIPC_ZONES 3 | 55 | #define CONFIG_TIPC_ZONES 3 |
@@ -117,11 +117,11 @@ void tipc_core_stop_net(void) | |||
117 | * start_net - start TIPC networking sub-systems | 117 | * start_net - start TIPC networking sub-systems |
118 | */ | 118 | */ |
119 | 119 | ||
120 | int tipc_core_start_net(void) | 120 | int tipc_core_start_net(unsigned long addr) |
121 | { | 121 | { |
122 | int res; | 122 | int res; |
123 | 123 | ||
124 | if ((res = tipc_net_start()) || | 124 | if ((res = tipc_net_start(addr)) || |
125 | (res = tipc_eth_media_start())) { | 125 | (res = tipc_eth_media_start())) { |
126 | tipc_core_stop_net(); | 126 | tipc_core_stop_net(); |
127 | } | 127 | } |
@@ -164,8 +164,7 @@ int tipc_core_start(void) | |||
164 | tipc_mode = TIPC_NODE_MODE; | 164 | tipc_mode = TIPC_NODE_MODE; |
165 | 165 | ||
166 | if ((res = tipc_handler_start()) || | 166 | if ((res = tipc_handler_start()) || |
167 | (res = tipc_ref_table_init(tipc_max_ports + tipc_max_subscriptions, | 167 | (res = tipc_ref_table_init(tipc_max_ports, tipc_random)) || |
168 | tipc_random)) || | ||
169 | (res = tipc_reg_start()) || | 168 | (res = tipc_reg_start()) || |
170 | (res = tipc_nametbl_init()) || | 169 | (res = tipc_nametbl_init()) || |
171 | (res = tipc_k_signal((Handler)tipc_subscr_start, 0)) || | 170 | (res = tipc_k_signal((Handler)tipc_subscr_start, 0)) || |
@@ -182,7 +181,7 @@ static int __init tipc_init(void) | |||
182 | { | 181 | { |
183 | int res; | 182 | int res; |
184 | 183 | ||
185 | tipc_log_reinit(CONFIG_TIPC_LOG); | 184 | tipc_log_resize(CONFIG_TIPC_LOG); |
186 | info("Activated (version " TIPC_MOD_VER | 185 | info("Activated (version " TIPC_MOD_VER |
187 | " compiled " __DATE__ " " __TIME__ ")\n"); | 186 | " compiled " __DATE__ " " __TIME__ ")\n"); |
188 | 187 | ||
@@ -209,7 +208,7 @@ static void __exit tipc_exit(void) | |||
209 | tipc_core_stop_net(); | 208 | tipc_core_stop_net(); |
210 | tipc_core_stop(); | 209 | tipc_core_stop(); |
211 | info("Deactivated\n"); | 210 | info("Deactivated\n"); |
212 | tipc_log_stop(); | 211 | tipc_log_resize(0); |
213 | } | 212 | } |
214 | 213 | ||
215 | module_init(tipc_init); | 214 | module_init(tipc_init); |
diff --git a/net/tipc/core.h b/net/tipc/core.h index 5a0e4878d3b7..a881f92a8537 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h | |||
@@ -2,7 +2,7 @@ | |||
2 | * net/tipc/core.h: Include file for TIPC global declarations | 2 | * net/tipc/core.h: Include file for TIPC global declarations |
3 | * | 3 | * |
4 | * Copyright (c) 2005-2006, Ericsson AB | 4 | * Copyright (c) 2005-2006, Ericsson AB |
5 | * Copyright (c) 2005-2006, Wind River Systems | 5 | * Copyright (c) 2005-2007, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -59,84 +59,108 @@ | |||
59 | #include <linux/vmalloc.h> | 59 | #include <linux/vmalloc.h> |
60 | 60 | ||
61 | /* | 61 | /* |
62 | * TIPC debugging code | 62 | * TIPC sanity test macros |
63 | */ | 63 | */ |
64 | 64 | ||
65 | #define assert(i) BUG_ON(!(i)) | 65 | #define assert(i) BUG_ON(!(i)) |
66 | 66 | ||
67 | struct tipc_msg; | ||
68 | extern struct print_buf *TIPC_NULL, *TIPC_CONS, *TIPC_LOG; | ||
69 | extern struct print_buf *TIPC_TEE(struct print_buf *, struct print_buf *); | ||
70 | void tipc_msg_print(struct print_buf*,struct tipc_msg *,const char*); | ||
71 | void tipc_printf(struct print_buf *, const char *fmt, ...); | ||
72 | void tipc_dump(struct print_buf*,const char *fmt, ...); | ||
73 | |||
74 | #ifdef CONFIG_TIPC_DEBUG | ||
75 | |||
76 | /* | 67 | /* |
77 | * TIPC debug support included: | 68 | * TIPC system monitoring code |
78 | * - system messages are printed to TIPC_OUTPUT print buffer | ||
79 | * - debug messages are printed to DBG_OUTPUT print buffer | ||
80 | */ | 69 | */ |
81 | 70 | ||
82 | #define err(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_ERR "TIPC: " fmt, ## arg) | 71 | /* |
83 | #define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_WARNING "TIPC: " fmt, ## arg) | 72 | * TIPC's print buffer subsystem supports the following print buffers: |
84 | #define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_NOTICE "TIPC: " fmt, ## arg) | 73 | * |
74 | * TIPC_NULL : null buffer (i.e. print nowhere) | ||
75 | * TIPC_CONS : system console | ||
76 | * TIPC_LOG : TIPC log buffer | ||
77 | * &buf : user-defined buffer (struct print_buf *) | ||
78 | * | ||
79 | * Note: TIPC_LOG is configured to echo its output to the system console; | ||
80 | * user-defined buffers can be configured to do the same thing. | ||
81 | */ | ||
85 | 82 | ||
86 | #define dbg(fmt, arg...) do {if (DBG_OUTPUT != TIPC_NULL) tipc_printf(DBG_OUTPUT, fmt, ## arg);} while(0) | 83 | extern struct print_buf *const TIPC_NULL; |
87 | #define msg_dbg(msg, txt) do {if (DBG_OUTPUT != TIPC_NULL) tipc_msg_print(DBG_OUTPUT, msg, txt);} while(0) | 84 | extern struct print_buf *const TIPC_CONS; |
88 | #define dump(fmt, arg...) do {if (DBG_OUTPUT != TIPC_NULL) tipc_dump(DBG_OUTPUT, fmt, ##arg);} while(0) | 85 | extern struct print_buf *const TIPC_LOG; |
89 | 86 | ||
87 | void tipc_printf(struct print_buf *, const char *fmt, ...); | ||
90 | 88 | ||
91 | /* | 89 | /* |
92 | * By default, TIPC_OUTPUT is defined to be system console and TIPC log buffer, | 90 | * TIPC_OUTPUT is the destination print buffer for system messages. |
93 | * while DBG_OUTPUT is the null print buffer. These defaults can be changed | ||
94 | * here, or on a per .c file basis, by redefining these symbols. The following | ||
95 | * print buffer options are available: | ||
96 | * | ||
97 | * TIPC_NULL : null buffer (i.e. print nowhere) | ||
98 | * TIPC_CONS : system console | ||
99 | * TIPC_LOG : TIPC log buffer | ||
100 | * &buf : user-defined buffer (struct print_buf *) | ||
101 | * TIPC_TEE(&buf_a,&buf_b) : list of buffers (eg. TIPC_TEE(TIPC_CONS,TIPC_LOG)) | ||
102 | */ | 91 | */ |
103 | 92 | ||
104 | #ifndef TIPC_OUTPUT | 93 | #ifndef TIPC_OUTPUT |
105 | #define TIPC_OUTPUT TIPC_TEE(TIPC_CONS,TIPC_LOG) | 94 | #define TIPC_OUTPUT TIPC_LOG |
106 | #endif | ||
107 | |||
108 | #ifndef DBG_OUTPUT | ||
109 | #define DBG_OUTPUT TIPC_NULL | ||
110 | #endif | 95 | #endif |
111 | 96 | ||
112 | #else | ||
113 | |||
114 | /* | 97 | /* |
115 | * TIPC debug support not included: | 98 | * TIPC can be configured to send system messages to TIPC_OUTPUT |
116 | * - system messages are printed to system console | 99 | * or to the system console only. |
117 | * - debug messages are not printed | ||
118 | */ | 100 | */ |
119 | 101 | ||
102 | #ifdef CONFIG_TIPC_DEBUG | ||
103 | |||
104 | #define err(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ | ||
105 | KERN_ERR "TIPC: " fmt, ## arg) | ||
106 | #define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ | ||
107 | KERN_WARNING "TIPC: " fmt, ## arg) | ||
108 | #define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ | ||
109 | KERN_NOTICE "TIPC: " fmt, ## arg) | ||
110 | |||
111 | #else | ||
112 | |||
120 | #define err(fmt, arg...) printk(KERN_ERR "TIPC: " fmt , ## arg) | 113 | #define err(fmt, arg...) printk(KERN_ERR "TIPC: " fmt , ## arg) |
121 | #define info(fmt, arg...) printk(KERN_INFO "TIPC: " fmt , ## arg) | 114 | #define info(fmt, arg...) printk(KERN_INFO "TIPC: " fmt , ## arg) |
122 | #define warn(fmt, arg...) printk(KERN_WARNING "TIPC: " fmt , ## arg) | 115 | #define warn(fmt, arg...) printk(KERN_WARNING "TIPC: " fmt , ## arg) |
123 | 116 | ||
124 | #define dbg(fmt, arg...) do {} while (0) | 117 | #endif |
125 | #define msg_dbg(msg,txt) do {} while (0) | ||
126 | #define dump(fmt,arg...) do {} while (0) | ||
127 | 118 | ||
119 | /* | ||
120 | * DBG_OUTPUT is the destination print buffer for debug messages. | ||
121 | * It defaults to the the null print buffer, but can be redefined | ||
122 | * (typically in the individual .c files being debugged) to allow | ||
123 | * selected debug messages to be generated where needed. | ||
124 | */ | ||
125 | |||
126 | #ifndef DBG_OUTPUT | ||
127 | #define DBG_OUTPUT TIPC_NULL | ||
128 | #endif | ||
128 | 129 | ||
129 | /* | 130 | /* |
130 | * TIPC_OUTPUT is defined to be the system console, while DBG_OUTPUT is | 131 | * TIPC can be configured to send debug messages to the specified print buffer |
131 | * the null print buffer. Thes ensures that any system or debug messages | 132 | * (typically DBG_OUTPUT) or to suppress them entirely. |
132 | * that are generated without using the above macros are handled correctly. | ||
133 | */ | 133 | */ |
134 | 134 | ||
135 | #undef TIPC_OUTPUT | 135 | #ifdef CONFIG_TIPC_DEBUG |
136 | #define TIPC_OUTPUT TIPC_CONS | ||
137 | 136 | ||
138 | #undef DBG_OUTPUT | 137 | #define dbg(fmt, arg...) \ |
139 | #define DBG_OUTPUT TIPC_NULL | 138 | do { \ |
139 | if (DBG_OUTPUT != TIPC_NULL) \ | ||
140 | tipc_printf(DBG_OUTPUT, fmt, ## arg); \ | ||
141 | } while (0) | ||
142 | #define msg_dbg(msg, txt) \ | ||
143 | do { \ | ||
144 | if (DBG_OUTPUT != TIPC_NULL) \ | ||
145 | tipc_msg_dbg(DBG_OUTPUT, msg, txt); \ | ||
146 | } while (0) | ||
147 | #define dump(fmt, arg...) \ | ||
148 | do { \ | ||
149 | if (DBG_OUTPUT != TIPC_NULL) \ | ||
150 | tipc_dump_dbg(DBG_OUTPUT, fmt, ##arg); \ | ||
151 | } while (0) | ||
152 | |||
153 | void tipc_msg_dbg(struct print_buf *, struct tipc_msg *, const char *); | ||
154 | void tipc_dump_dbg(struct print_buf *, const char *fmt, ...); | ||
155 | |||
156 | #else | ||
157 | |||
158 | #define dbg(fmt, arg...) do {} while (0) | ||
159 | #define msg_dbg(msg, txt) do {} while (0) | ||
160 | #define dump(fmt, arg...) do {} while (0) | ||
161 | |||
162 | #define tipc_msg_dbg(...) do {} while (0) | ||
163 | #define tipc_dump_dbg(...) do {} while (0) | ||
140 | 164 | ||
141 | #endif | 165 | #endif |
142 | 166 | ||
@@ -178,7 +202,7 @@ extern atomic_t tipc_user_count; | |||
178 | 202 | ||
179 | extern int tipc_core_start(void); | 203 | extern int tipc_core_start(void); |
180 | extern void tipc_core_stop(void); | 204 | extern void tipc_core_stop(void); |
181 | extern int tipc_core_start_net(void); | 205 | extern int tipc_core_start_net(unsigned long addr); |
182 | extern void tipc_core_stop_net(void); | 206 | extern void tipc_core_stop_net(void); |
183 | extern int tipc_handler_start(void); | 207 | extern int tipc_handler_start(void); |
184 | extern void tipc_handler_stop(void); | 208 | extern void tipc_handler_stop(void); |
diff --git a/net/tipc/dbg.c b/net/tipc/dbg.c index e809d2a2ce06..29ecae851668 100644 --- a/net/tipc/dbg.c +++ b/net/tipc/dbg.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * net/tipc/dbg.c: TIPC print buffer routines for debugging | 2 | * net/tipc/dbg.c: TIPC print buffer routines for debugging |
3 | * | 3 | * |
4 | * Copyright (c) 1996-2006, Ericsson AB | 4 | * Copyright (c) 1996-2006, Ericsson AB |
5 | * Copyright (c) 2005-2006, Wind River Systems | 5 | * Copyright (c) 2005-2007, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -38,17 +38,43 @@ | |||
38 | #include "config.h" | 38 | #include "config.h" |
39 | #include "dbg.h" | 39 | #include "dbg.h" |
40 | 40 | ||
41 | static char print_string[TIPC_PB_MAX_STR]; | 41 | /* |
42 | static DEFINE_SPINLOCK(print_lock); | 42 | * TIPC pre-defines the following print buffers: |
43 | * | ||
44 | * TIPC_NULL : null buffer (i.e. print nowhere) | ||
45 | * TIPC_CONS : system console | ||
46 | * TIPC_LOG : TIPC log buffer | ||
47 | * | ||
48 | * Additional user-defined print buffers are also permitted. | ||
49 | */ | ||
43 | 50 | ||
44 | static struct print_buf null_buf = { NULL, 0, NULL, NULL }; | 51 | static struct print_buf null_buf = { NULL, 0, NULL, 0 }; |
45 | struct print_buf *TIPC_NULL = &null_buf; | 52 | struct print_buf *const TIPC_NULL = &null_buf; |
46 | 53 | ||
47 | static struct print_buf cons_buf = { NULL, 0, NULL, NULL }; | 54 | static struct print_buf cons_buf = { NULL, 0, NULL, 1 }; |
48 | struct print_buf *TIPC_CONS = &cons_buf; | 55 | struct print_buf *const TIPC_CONS = &cons_buf; |
49 | 56 | ||
50 | static struct print_buf log_buf = { NULL, 0, NULL, NULL }; | 57 | static struct print_buf log_buf = { NULL, 0, NULL, 1 }; |
51 | struct print_buf *TIPC_LOG = &log_buf; | 58 | struct print_buf *const TIPC_LOG = &log_buf; |
59 | |||
60 | /* | ||
61 | * Locking policy when using print buffers. | ||
62 | * | ||
63 | * 1) tipc_printf() uses 'print_lock' to protect against concurrent access to | ||
64 | * 'print_string' when writing to a print buffer. This also protects against | ||
65 | * concurrent writes to the print buffer being written to. | ||
66 | * | ||
67 | * 2) tipc_dump() and tipc_log_XXX() leverage the aforementioned | ||
68 | * use of 'print_lock' to protect against all types of concurrent operations | ||
69 | * on their associated print buffer (not just write operations). | ||
70 | * | ||
71 | * Note: All routines of the form tipc_printbuf_XXX() are lock-free, and rely | ||
72 | * on the caller to prevent simultaneous use of the print buffer(s) being | ||
73 | * manipulated. | ||
74 | */ | ||
75 | |||
76 | static char print_string[TIPC_PB_MAX_STR]; | ||
77 | static DEFINE_SPINLOCK(print_lock); | ||
52 | 78 | ||
53 | 79 | ||
54 | #define FORMAT(PTR,LEN,FMT) \ | 80 | #define FORMAT(PTR,LEN,FMT) \ |
@@ -60,27 +86,14 @@ struct print_buf *TIPC_LOG = &log_buf; | |||
60 | *(PTR + LEN) = '\0';\ | 86 | *(PTR + LEN) = '\0';\ |
61 | } | 87 | } |
62 | 88 | ||
63 | /* | ||
64 | * Locking policy when using print buffers. | ||
65 | * | ||
66 | * The following routines use 'print_lock' for protection: | ||
67 | * 1) tipc_printf() - to protect its print buffer(s) and 'print_string' | ||
68 | * 2) TIPC_TEE() - to protect its print buffer(s) | ||
69 | * 3) tipc_dump() - to protect its print buffer(s) and 'print_string' | ||
70 | * 4) tipc_log_XXX() - to protect TIPC_LOG | ||
71 | * | ||
72 | * All routines of the form tipc_printbuf_XXX() rely on the caller to prevent | ||
73 | * simultaneous use of the print buffer(s) being manipulated. | ||
74 | */ | ||
75 | |||
76 | /** | 89 | /** |
77 | * tipc_printbuf_init - initialize print buffer to empty | 90 | * tipc_printbuf_init - initialize print buffer to empty |
78 | * @pb: pointer to print buffer structure | 91 | * @pb: pointer to print buffer structure |
79 | * @raw: pointer to character array used by print buffer | 92 | * @raw: pointer to character array used by print buffer |
80 | * @size: size of character array | 93 | * @size: size of character array |
81 | * | 94 | * |
82 | * Makes the print buffer a null device that discards anything written to it | 95 | * Note: If the character array is too small (or absent), the print buffer |
83 | * if the character array is too small (or absent). | 96 | * becomes a null device that discards anything written to it. |
84 | */ | 97 | */ |
85 | 98 | ||
86 | void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size) | 99 | void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size) |
@@ -88,13 +101,13 @@ void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size) | |||
88 | pb->buf = raw; | 101 | pb->buf = raw; |
89 | pb->crs = raw; | 102 | pb->crs = raw; |
90 | pb->size = size; | 103 | pb->size = size; |
91 | pb->next = NULL; | 104 | pb->echo = 0; |
92 | 105 | ||
93 | if (size < TIPC_PB_MIN_SIZE) { | 106 | if (size < TIPC_PB_MIN_SIZE) { |
94 | pb->buf = NULL; | 107 | pb->buf = NULL; |
95 | } else if (raw) { | 108 | } else if (raw) { |
96 | pb->buf[0] = 0; | 109 | pb->buf[0] = 0; |
97 | pb->buf[size-1] = ~0; | 110 | pb->buf[size - 1] = ~0; |
98 | } | 111 | } |
99 | } | 112 | } |
100 | 113 | ||
@@ -105,7 +118,11 @@ void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size) | |||
105 | 118 | ||
106 | void tipc_printbuf_reset(struct print_buf *pb) | 119 | void tipc_printbuf_reset(struct print_buf *pb) |
107 | { | 120 | { |
108 | tipc_printbuf_init(pb, pb->buf, pb->size); | 121 | if (pb->buf) { |
122 | pb->crs = pb->buf; | ||
123 | pb->buf[0] = 0; | ||
124 | pb->buf[pb->size - 1] = ~0; | ||
125 | } | ||
109 | } | 126 | } |
110 | 127 | ||
111 | /** | 128 | /** |
@@ -141,7 +158,7 @@ int tipc_printbuf_validate(struct print_buf *pb) | |||
141 | 158 | ||
142 | if (pb->buf[pb->size - 1] == 0) { | 159 | if (pb->buf[pb->size - 1] == 0) { |
143 | cp_buf = kmalloc(pb->size, GFP_ATOMIC); | 160 | cp_buf = kmalloc(pb->size, GFP_ATOMIC); |
144 | if (cp_buf != NULL){ | 161 | if (cp_buf) { |
145 | tipc_printbuf_init(&cb, cp_buf, pb->size); | 162 | tipc_printbuf_init(&cb, cp_buf, pb->size); |
146 | tipc_printbuf_move(&cb, pb); | 163 | tipc_printbuf_move(&cb, pb); |
147 | tipc_printbuf_move(pb, &cb); | 164 | tipc_printbuf_move(pb, &cb); |
@@ -179,15 +196,16 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from) | |||
179 | } | 196 | } |
180 | 197 | ||
181 | if (pb_to->size < pb_from->size) { | 198 | if (pb_to->size < pb_from->size) { |
182 | tipc_printbuf_reset(pb_to); | 199 | strcpy(pb_to->buf, "*** PRINT BUFFER MOVE ERROR ***"); |
183 | tipc_printf(pb_to, "*** PRINT BUFFER MOVE ERROR ***"); | 200 | pb_to->buf[pb_to->size - 1] = ~0; |
201 | pb_to->crs = strchr(pb_to->buf, 0); | ||
184 | return; | 202 | return; |
185 | } | 203 | } |
186 | 204 | ||
187 | /* Copy data from char after cursor to end (if used) */ | 205 | /* Copy data from char after cursor to end (if used) */ |
188 | 206 | ||
189 | len = pb_from->buf + pb_from->size - pb_from->crs - 2; | 207 | len = pb_from->buf + pb_from->size - pb_from->crs - 2; |
190 | if ((pb_from->buf[pb_from->size-1] == 0) && (len > 0)) { | 208 | if ((pb_from->buf[pb_from->size - 1] == 0) && (len > 0)) { |
191 | strcpy(pb_to->buf, pb_from->crs + 1); | 209 | strcpy(pb_to->buf, pb_from->crs + 1); |
192 | pb_to->crs = pb_to->buf + len; | 210 | pb_to->crs = pb_to->buf + len; |
193 | } else | 211 | } else |
@@ -203,8 +221,8 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from) | |||
203 | } | 221 | } |
204 | 222 | ||
205 | /** | 223 | /** |
206 | * tipc_printf - append formatted output to print buffer chain | 224 | * tipc_printf - append formatted output to print buffer |
207 | * @pb: pointer to chain of print buffers (may be NULL) | 225 | * @pb: pointer to print buffer |
208 | * @fmt: formatted info to be printed | 226 | * @fmt: formatted info to be printed |
209 | */ | 227 | */ |
210 | 228 | ||
@@ -213,68 +231,40 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...) | |||
213 | int chars_to_add; | 231 | int chars_to_add; |
214 | int chars_left; | 232 | int chars_left; |
215 | char save_char; | 233 | char save_char; |
216 | struct print_buf *pb_next; | ||
217 | 234 | ||
218 | spin_lock_bh(&print_lock); | 235 | spin_lock_bh(&print_lock); |
236 | |||
219 | FORMAT(print_string, chars_to_add, fmt); | 237 | FORMAT(print_string, chars_to_add, fmt); |
220 | if (chars_to_add >= TIPC_PB_MAX_STR) | 238 | if (chars_to_add >= TIPC_PB_MAX_STR) |
221 | strcpy(print_string, "*** PRINT BUFFER STRING TOO LONG ***"); | 239 | strcpy(print_string, "*** PRINT BUFFER STRING TOO LONG ***"); |
222 | 240 | ||
223 | while (pb) { | 241 | if (pb->buf) { |
224 | if (pb == TIPC_CONS) | 242 | chars_left = pb->buf + pb->size - pb->crs - 1; |
225 | printk(print_string); | 243 | if (chars_to_add <= chars_left) { |
226 | else if (pb->buf) { | 244 | strcpy(pb->crs, print_string); |
227 | chars_left = pb->buf + pb->size - pb->crs - 1; | 245 | pb->crs += chars_to_add; |
228 | if (chars_to_add <= chars_left) { | 246 | } else if (chars_to_add >= (pb->size - 1)) { |
229 | strcpy(pb->crs, print_string); | 247 | strcpy(pb->buf, print_string + chars_to_add + 1 |
230 | pb->crs += chars_to_add; | 248 | - pb->size); |
231 | } else if (chars_to_add >= (pb->size - 1)) { | 249 | pb->crs = pb->buf + pb->size - 1; |
232 | strcpy(pb->buf, print_string + chars_to_add + 1 | 250 | } else { |
233 | - pb->size); | 251 | strcpy(pb->buf, print_string + chars_left); |
234 | pb->crs = pb->buf + pb->size - 1; | 252 | save_char = print_string[chars_left]; |
235 | } else { | 253 | print_string[chars_left] = 0; |
236 | strcpy(pb->buf, print_string + chars_left); | 254 | strcpy(pb->crs, print_string); |
237 | save_char = print_string[chars_left]; | 255 | print_string[chars_left] = save_char; |
238 | print_string[chars_left] = 0; | 256 | pb->crs = pb->buf + chars_to_add - chars_left; |
239 | strcpy(pb->crs, print_string); | ||
240 | print_string[chars_left] = save_char; | ||
241 | pb->crs = pb->buf + chars_to_add - chars_left; | ||
242 | } | ||
243 | } | 257 | } |
244 | pb_next = pb->next; | ||
245 | pb->next = NULL; | ||
246 | pb = pb_next; | ||
247 | } | 258 | } |
248 | spin_unlock_bh(&print_lock); | ||
249 | } | ||
250 | 259 | ||
251 | /** | 260 | if (pb->echo) |
252 | * TIPC_TEE - perform next output operation on both print buffers | 261 | printk(print_string); |
253 | * @b0: pointer to chain of print buffers (may be NULL) | ||
254 | * @b1: pointer to print buffer to add to chain | ||
255 | * | ||
256 | * Returns pointer to print buffer chain. | ||
257 | */ | ||
258 | 262 | ||
259 | struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1) | ||
260 | { | ||
261 | struct print_buf *pb = b0; | ||
262 | |||
263 | if (!b0 || (b0 == b1)) | ||
264 | return b1; | ||
265 | |||
266 | spin_lock_bh(&print_lock); | ||
267 | while (pb->next) { | ||
268 | if ((pb->next == b1) || (pb->next == b0)) | ||
269 | pb->next = pb->next->next; | ||
270 | else | ||
271 | pb = pb->next; | ||
272 | } | ||
273 | pb->next = b1; | ||
274 | spin_unlock_bh(&print_lock); | 263 | spin_unlock_bh(&print_lock); |
275 | return b0; | ||
276 | } | 264 | } |
277 | 265 | ||
266 | #ifdef CONFIG_TIPC_DEBUG | ||
267 | |||
278 | /** | 268 | /** |
279 | * print_to_console - write string of bytes to console in multiple chunks | 269 | * print_to_console - write string of bytes to console in multiple chunks |
280 | */ | 270 | */ |
@@ -321,72 +311,66 @@ static void printbuf_dump(struct print_buf *pb) | |||
321 | } | 311 | } |
322 | 312 | ||
323 | /** | 313 | /** |
324 | * tipc_dump - dump non-console print buffer(s) to console | 314 | * tipc_dump_dbg - dump (non-console) print buffer to console |
325 | * @pb: pointer to chain of print buffers | 315 | * @pb: pointer to print buffer |
326 | */ | 316 | */ |
327 | 317 | ||
328 | void tipc_dump(struct print_buf *pb, const char *fmt, ...) | 318 | void tipc_dump_dbg(struct print_buf *pb, const char *fmt, ...) |
329 | { | 319 | { |
330 | struct print_buf *pb_next; | ||
331 | int len; | 320 | int len; |
332 | 321 | ||
322 | if (pb == TIPC_CONS) | ||
323 | return; | ||
324 | |||
333 | spin_lock_bh(&print_lock); | 325 | spin_lock_bh(&print_lock); |
326 | |||
334 | FORMAT(print_string, len, fmt); | 327 | FORMAT(print_string, len, fmt); |
335 | printk(print_string); | 328 | printk(print_string); |
336 | 329 | ||
337 | for (; pb; pb = pb->next) { | 330 | printk("\n---- Start of %s log dump ----\n\n", |
338 | if (pb != TIPC_CONS) { | 331 | (pb == TIPC_LOG) ? "global" : "local"); |
339 | printk("\n---- Start of %s log dump ----\n\n", | 332 | printbuf_dump(pb); |
340 | (pb == TIPC_LOG) ? "global" : "local"); | 333 | tipc_printbuf_reset(pb); |
341 | printbuf_dump(pb); | 334 | printk("\n---- End of dump ----\n"); |
342 | tipc_printbuf_reset(pb); | 335 | |
343 | printk("\n---- End of dump ----\n"); | ||
344 | } | ||
345 | pb_next = pb->next; | ||
346 | pb->next = NULL; | ||
347 | pb = pb_next; | ||
348 | } | ||
349 | spin_unlock_bh(&print_lock); | 336 | spin_unlock_bh(&print_lock); |
350 | } | 337 | } |
351 | 338 | ||
339 | #endif | ||
340 | |||
352 | /** | 341 | /** |
353 | * tipc_log_stop - free up TIPC log print buffer | 342 | * tipc_log_resize - change the size of the TIPC log buffer |
343 | * @log_size: print buffer size to use | ||
354 | */ | 344 | */ |
355 | 345 | ||
356 | void tipc_log_stop(void) | 346 | int tipc_log_resize(int log_size) |
357 | { | 347 | { |
348 | int res = 0; | ||
349 | |||
358 | spin_lock_bh(&print_lock); | 350 | spin_lock_bh(&print_lock); |
359 | if (TIPC_LOG->buf) { | 351 | if (TIPC_LOG->buf) { |
360 | kfree(TIPC_LOG->buf); | 352 | kfree(TIPC_LOG->buf); |
361 | TIPC_LOG->buf = NULL; | 353 | TIPC_LOG->buf = NULL; |
362 | } | 354 | } |
363 | spin_unlock_bh(&print_lock); | ||
364 | } | ||
365 | |||
366 | /** | ||
367 | * tipc_log_reinit - (re)initialize TIPC log print buffer | ||
368 | * @log_size: print buffer size to use | ||
369 | */ | ||
370 | |||
371 | void tipc_log_reinit(int log_size) | ||
372 | { | ||
373 | tipc_log_stop(); | ||
374 | |||
375 | if (log_size) { | 355 | if (log_size) { |
376 | if (log_size < TIPC_PB_MIN_SIZE) | 356 | if (log_size < TIPC_PB_MIN_SIZE) |
377 | log_size = TIPC_PB_MIN_SIZE; | 357 | log_size = TIPC_PB_MIN_SIZE; |
378 | spin_lock_bh(&print_lock); | 358 | res = TIPC_LOG->echo; |
379 | tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), | 359 | tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), |
380 | log_size); | 360 | log_size); |
381 | spin_unlock_bh(&print_lock); | 361 | TIPC_LOG->echo = res; |
362 | res = !TIPC_LOG->buf; | ||
382 | } | 363 | } |
364 | spin_unlock_bh(&print_lock); | ||
365 | |||
366 | return res; | ||
383 | } | 367 | } |
384 | 368 | ||
385 | /** | 369 | /** |
386 | * tipc_log_resize - reconfigure size of TIPC log buffer | 370 | * tipc_log_resize_cmd - reconfigure size of TIPC log buffer |
387 | */ | 371 | */ |
388 | 372 | ||
389 | struct sk_buff *tipc_log_resize(const void *req_tlv_area, int req_tlv_space) | 373 | struct sk_buff *tipc_log_resize_cmd(const void *req_tlv_area, int req_tlv_space) |
390 | { | 374 | { |
391 | u32 value; | 375 | u32 value; |
392 | 376 | ||
@@ -397,7 +381,9 @@ struct sk_buff *tipc_log_resize(const void *req_tlv_area, int req_tlv_space) | |||
397 | if (value != delimit(value, 0, 32768)) | 381 | if (value != delimit(value, 0, 32768)) |
398 | return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE | 382 | return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE |
399 | " (log size must be 0-32768)"); | 383 | " (log size must be 0-32768)"); |
400 | tipc_log_reinit(value); | 384 | if (tipc_log_resize(value)) |
385 | return tipc_cfg_reply_error_string( | ||
386 | "unable to create specified log (log size is now 0)"); | ||
401 | return tipc_cfg_reply_none(); | 387 | return tipc_cfg_reply_none(); |
402 | } | 388 | } |
403 | 389 | ||
@@ -410,27 +396,32 @@ struct sk_buff *tipc_log_dump(void) | |||
410 | struct sk_buff *reply; | 396 | struct sk_buff *reply; |
411 | 397 | ||
412 | spin_lock_bh(&print_lock); | 398 | spin_lock_bh(&print_lock); |
413 | if (!TIPC_LOG->buf) | 399 | if (!TIPC_LOG->buf) { |
400 | spin_unlock_bh(&print_lock); | ||
414 | reply = tipc_cfg_reply_ultra_string("log not activated\n"); | 401 | reply = tipc_cfg_reply_ultra_string("log not activated\n"); |
415 | else if (tipc_printbuf_empty(TIPC_LOG)) | 402 | } else if (tipc_printbuf_empty(TIPC_LOG)) { |
403 | spin_unlock_bh(&print_lock); | ||
416 | reply = tipc_cfg_reply_ultra_string("log is empty\n"); | 404 | reply = tipc_cfg_reply_ultra_string("log is empty\n"); |
405 | } | ||
417 | else { | 406 | else { |
418 | struct tlv_desc *rep_tlv; | 407 | struct tlv_desc *rep_tlv; |
419 | struct print_buf pb; | 408 | struct print_buf pb; |
420 | int str_len; | 409 | int str_len; |
421 | 410 | ||
422 | str_len = min(TIPC_LOG->size, 32768u); | 411 | str_len = min(TIPC_LOG->size, 32768u); |
412 | spin_unlock_bh(&print_lock); | ||
423 | reply = tipc_cfg_reply_alloc(TLV_SPACE(str_len)); | 413 | reply = tipc_cfg_reply_alloc(TLV_SPACE(str_len)); |
424 | if (reply) { | 414 | if (reply) { |
425 | rep_tlv = (struct tlv_desc *)reply->data; | 415 | rep_tlv = (struct tlv_desc *)reply->data; |
426 | tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), str_len); | 416 | tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), str_len); |
417 | spin_lock_bh(&print_lock); | ||
427 | tipc_printbuf_move(&pb, TIPC_LOG); | 418 | tipc_printbuf_move(&pb, TIPC_LOG); |
419 | spin_unlock_bh(&print_lock); | ||
428 | str_len = strlen(TLV_DATA(rep_tlv)) + 1; | 420 | str_len = strlen(TLV_DATA(rep_tlv)) + 1; |
429 | skb_put(reply, TLV_SPACE(str_len)); | 421 | skb_put(reply, TLV_SPACE(str_len)); |
430 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); | 422 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); |
431 | } | 423 | } |
432 | } | 424 | } |
433 | spin_unlock_bh(&print_lock); | ||
434 | return reply; | 425 | return reply; |
435 | } | 426 | } |
436 | 427 | ||
diff --git a/net/tipc/dbg.h b/net/tipc/dbg.h index c01b085000e0..5ef1bc8f64ef 100644 --- a/net/tipc/dbg.h +++ b/net/tipc/dbg.h | |||
@@ -2,7 +2,7 @@ | |||
2 | * net/tipc/dbg.h: Include file for TIPC print buffer routines | 2 | * net/tipc/dbg.h: Include file for TIPC print buffer routines |
3 | * | 3 | * |
4 | * Copyright (c) 1997-2006, Ericsson AB | 4 | * Copyright (c) 1997-2006, Ericsson AB |
5 | * Copyright (c) 2005-2006, Wind River Systems | 5 | * Copyright (c) 2005-2007, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -42,14 +42,14 @@ | |||
42 | * @buf: pointer to character array containing print buffer contents | 42 | * @buf: pointer to character array containing print buffer contents |
43 | * @size: size of character array | 43 | * @size: size of character array |
44 | * @crs: pointer to first unused space in character array (i.e. final NUL) | 44 | * @crs: pointer to first unused space in character array (i.e. final NUL) |
45 | * @next: used to link print buffers when printing to more than one at a time | 45 | * @echo: echo output to system console if non-zero |
46 | */ | 46 | */ |
47 | 47 | ||
48 | struct print_buf { | 48 | struct print_buf { |
49 | char *buf; | 49 | char *buf; |
50 | u32 size; | 50 | u32 size; |
51 | char *crs; | 51 | char *crs; |
52 | struct print_buf *next; | 52 | int echo; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | #define TIPC_PB_MIN_SIZE 64 /* minimum size for a print buffer's array */ | 55 | #define TIPC_PB_MIN_SIZE 64 /* minimum size for a print buffer's array */ |
@@ -61,10 +61,10 @@ int tipc_printbuf_empty(struct print_buf *pb); | |||
61 | int tipc_printbuf_validate(struct print_buf *pb); | 61 | int tipc_printbuf_validate(struct print_buf *pb); |
62 | void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from); | 62 | void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from); |
63 | 63 | ||
64 | void tipc_log_reinit(int log_size); | 64 | int tipc_log_resize(int log_size); |
65 | void tipc_log_stop(void); | ||
66 | 65 | ||
67 | struct sk_buff *tipc_log_resize(const void *req_tlv_area, int req_tlv_space); | 66 | struct sk_buff *tipc_log_resize_cmd(const void *req_tlv_area, |
67 | int req_tlv_space); | ||
68 | struct sk_buff *tipc_log_dump(void); | 68 | struct sk_buff *tipc_log_dump(void); |
69 | 69 | ||
70 | #endif | 70 | #endif |
diff --git a/net/tipc/discover.c b/net/tipc/discover.c index 5d643e5721eb..1657f0e795ff 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c | |||
@@ -120,9 +120,8 @@ static struct sk_buff *tipc_disc_init_msg(u32 type, | |||
120 | 120 | ||
121 | if (buf) { | 121 | if (buf) { |
122 | msg = buf_msg(buf); | 122 | msg = buf_msg(buf); |
123 | msg_init(msg, LINK_CONFIG, type, TIPC_OK, DSC_H_SIZE, | 123 | msg_init(msg, LINK_CONFIG, type, DSC_H_SIZE, dest_domain); |
124 | dest_domain); | 124 | msg_set_non_seq(msg, 1); |
125 | msg_set_non_seq(msg); | ||
126 | msg_set_req_links(msg, req_links); | 125 | msg_set_req_links(msg, req_links); |
127 | msg_set_dest_domain(msg, dest_domain); | 126 | msg_set_dest_domain(msg, dest_domain); |
128 | msg_set_bc_netid(msg, tipc_net_id); | 127 | msg_set_bc_netid(msg, tipc_net_id); |
@@ -156,11 +155,11 @@ static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr, | |||
156 | /** | 155 | /** |
157 | * tipc_disc_recv_msg - handle incoming link setup message (request or response) | 156 | * tipc_disc_recv_msg - handle incoming link setup message (request or response) |
158 | * @buf: buffer containing message | 157 | * @buf: buffer containing message |
158 | * @b_ptr: bearer that message arrived on | ||
159 | */ | 159 | */ |
160 | 160 | ||
161 | void tipc_disc_recv_msg(struct sk_buff *buf) | 161 | void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr) |
162 | { | 162 | { |
163 | struct bearer *b_ptr = (struct bearer *)TIPC_SKB_CB(buf)->handle; | ||
164 | struct link *link; | 163 | struct link *link; |
165 | struct tipc_media_addr media_addr; | 164 | struct tipc_media_addr media_addr; |
166 | struct tipc_msg *msg = buf_msg(buf); | 165 | struct tipc_msg *msg = buf_msg(buf); |
@@ -200,9 +199,8 @@ void tipc_disc_recv_msg(struct sk_buff *buf) | |||
200 | dbg(" in own cluster\n"); | 199 | dbg(" in own cluster\n"); |
201 | if (n_ptr == NULL) { | 200 | if (n_ptr == NULL) { |
202 | n_ptr = tipc_node_create(orig); | 201 | n_ptr = tipc_node_create(orig); |
203 | } | 202 | if (!n_ptr) |
204 | if (n_ptr == NULL) { | 203 | return; |
205 | return; | ||
206 | } | 204 | } |
207 | spin_lock_bh(&n_ptr->lock); | 205 | spin_lock_bh(&n_ptr->lock); |
208 | link = n_ptr->links[b_ptr->identity]; | 206 | link = n_ptr->links[b_ptr->identity]; |
diff --git a/net/tipc/discover.h b/net/tipc/discover.h index 9fd7587b143a..c36eaeb7d5d0 100644 --- a/net/tipc/discover.h +++ b/net/tipc/discover.h | |||
@@ -48,7 +48,7 @@ struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr, | |||
48 | void tipc_disc_update_link_req(struct link_req *req); | 48 | void tipc_disc_update_link_req(struct link_req *req); |
49 | void tipc_disc_stop_link_req(struct link_req *req); | 49 | void tipc_disc_stop_link_req(struct link_req *req); |
50 | 50 | ||
51 | void tipc_disc_recv_msg(struct sk_buff *buf); | 51 | void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr); |
52 | 52 | ||
53 | void tipc_disc_link_event(u32 addr, char *name, int up); | 53 | void tipc_disc_link_event(u32 addr, char *name, int up); |
54 | #if 0 | 54 | #if 0 |
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c index 9cd35eec3e7f..fe43ef7dd7e3 100644 --- a/net/tipc/eth_media.c +++ b/net/tipc/eth_media.c | |||
@@ -82,7 +82,7 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr, | |||
82 | dev->dev_addr, clone->len); | 82 | dev->dev_addr, clone->len); |
83 | dev_queue_xmit(clone); | 83 | dev_queue_xmit(clone); |
84 | } | 84 | } |
85 | return TIPC_OK; | 85 | return 0; |
86 | } | 86 | } |
87 | 87 | ||
88 | /** | 88 | /** |
@@ -101,7 +101,7 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev, | |||
101 | struct eth_bearer *eb_ptr = (struct eth_bearer *)pt->af_packet_priv; | 101 | struct eth_bearer *eb_ptr = (struct eth_bearer *)pt->af_packet_priv; |
102 | u32 size; | 102 | u32 size; |
103 | 103 | ||
104 | if (dev_net(dev) != &init_net) { | 104 | if (!net_eq(dev_net(dev), &init_net)) { |
105 | kfree_skb(buf); | 105 | kfree_skb(buf); |
106 | return 0; | 106 | return 0; |
107 | } | 107 | } |
@@ -113,12 +113,12 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev, | |||
113 | if (likely(buf->len == size)) { | 113 | if (likely(buf->len == size)) { |
114 | buf->next = NULL; | 114 | buf->next = NULL; |
115 | tipc_recv_msg(buf, eb_ptr->bearer); | 115 | tipc_recv_msg(buf, eb_ptr->bearer); |
116 | return TIPC_OK; | 116 | return 0; |
117 | } | 117 | } |
118 | } | 118 | } |
119 | } | 119 | } |
120 | kfree_skb(buf); | 120 | kfree_skb(buf); |
121 | return TIPC_OK; | 121 | return 0; |
122 | } | 122 | } |
123 | 123 | ||
124 | /** | 124 | /** |
@@ -198,7 +198,7 @@ static int recv_notification(struct notifier_block *nb, unsigned long evt, | |||
198 | struct eth_bearer *eb_ptr = ð_bearers[0]; | 198 | struct eth_bearer *eb_ptr = ð_bearers[0]; |
199 | struct eth_bearer *stop = ð_bearers[MAX_ETH_BEARERS]; | 199 | struct eth_bearer *stop = ð_bearers[MAX_ETH_BEARERS]; |
200 | 200 | ||
201 | if (dev_net(dev) != &init_net) | 201 | if (!net_eq(dev_net(dev), &init_net)) |
202 | return NOTIFY_DONE; | 202 | return NOTIFY_DONE; |
203 | 203 | ||
204 | while ((eb_ptr->dev != dev)) { | 204 | while ((eb_ptr->dev != dev)) { |
diff --git a/net/tipc/link.c b/net/tipc/link.c index 2a26a16e269f..d60113ba4b1b 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -51,6 +51,12 @@ | |||
51 | 51 | ||
52 | 52 | ||
53 | /* | 53 | /* |
54 | * Out-of-range value for link session numbers | ||
55 | */ | ||
56 | |||
57 | #define INVALID_SESSION 0x10000 | ||
58 | |||
59 | /* | ||
54 | * Limit for deferred reception queue: | 60 | * Limit for deferred reception queue: |
55 | */ | 61 | */ |
56 | 62 | ||
@@ -147,9 +153,21 @@ static void link_print(struct link *l_ptr, struct print_buf *buf, | |||
147 | 153 | ||
148 | #define LINK_LOG_BUF_SIZE 0 | 154 | #define LINK_LOG_BUF_SIZE 0 |
149 | 155 | ||
150 | #define dbg_link(fmt, arg...) do {if (LINK_LOG_BUF_SIZE) tipc_printf(&l_ptr->print_buf, fmt, ## arg); } while(0) | 156 | #define dbg_link(fmt, arg...) \ |
151 | #define dbg_link_msg(msg, txt) do {if (LINK_LOG_BUF_SIZE) tipc_msg_print(&l_ptr->print_buf, msg, txt); } while(0) | 157 | do { \ |
152 | #define dbg_link_state(txt) do {if (LINK_LOG_BUF_SIZE) link_print(l_ptr, &l_ptr->print_buf, txt); } while(0) | 158 | if (LINK_LOG_BUF_SIZE) \ |
159 | tipc_printf(&l_ptr->print_buf, fmt, ## arg); \ | ||
160 | } while (0) | ||
161 | #define dbg_link_msg(msg, txt) \ | ||
162 | do { \ | ||
163 | if (LINK_LOG_BUF_SIZE) \ | ||
164 | tipc_msg_dbg(&l_ptr->print_buf, msg, txt); \ | ||
165 | } while (0) | ||
166 | #define dbg_link_state(txt) \ | ||
167 | do { \ | ||
168 | if (LINK_LOG_BUF_SIZE) \ | ||
169 | link_print(l_ptr, &l_ptr->print_buf, txt); \ | ||
170 | } while (0) | ||
153 | #define dbg_link_dump() do { \ | 171 | #define dbg_link_dump() do { \ |
154 | if (LINK_LOG_BUF_SIZE) { \ | 172 | if (LINK_LOG_BUF_SIZE) { \ |
155 | tipc_printf(LOG, "\n\nDumping link <%s>:\n", l_ptr->name); \ | 173 | tipc_printf(LOG, "\n\nDumping link <%s>:\n", l_ptr->name); \ |
@@ -450,9 +468,9 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, | |||
450 | 468 | ||
451 | l_ptr->pmsg = (struct tipc_msg *)&l_ptr->proto_msg; | 469 | l_ptr->pmsg = (struct tipc_msg *)&l_ptr->proto_msg; |
452 | msg = l_ptr->pmsg; | 470 | msg = l_ptr->pmsg; |
453 | msg_init(msg, LINK_PROTOCOL, RESET_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr); | 471 | msg_init(msg, LINK_PROTOCOL, RESET_MSG, INT_H_SIZE, l_ptr->addr); |
454 | msg_set_size(msg, sizeof(l_ptr->proto_msg)); | 472 | msg_set_size(msg, sizeof(l_ptr->proto_msg)); |
455 | msg_set_session(msg, tipc_random); | 473 | msg_set_session(msg, (tipc_random & 0xffff)); |
456 | msg_set_bearer_id(msg, b_ptr->identity); | 474 | msg_set_bearer_id(msg, b_ptr->identity); |
457 | strcpy((char *)msg_data(msg), if_name); | 475 | strcpy((char *)msg_data(msg), if_name); |
458 | 476 | ||
@@ -693,10 +711,10 @@ void tipc_link_reset(struct link *l_ptr) | |||
693 | u32 checkpoint = l_ptr->next_in_no; | 711 | u32 checkpoint = l_ptr->next_in_no; |
694 | int was_active_link = tipc_link_is_active(l_ptr); | 712 | int was_active_link = tipc_link_is_active(l_ptr); |
695 | 713 | ||
696 | msg_set_session(l_ptr->pmsg, msg_session(l_ptr->pmsg) + 1); | 714 | msg_set_session(l_ptr->pmsg, ((msg_session(l_ptr->pmsg) + 1) & 0xffff)); |
697 | 715 | ||
698 | /* Link is down, accept any session: */ | 716 | /* Link is down, accept any session */ |
699 | l_ptr->peer_session = 0; | 717 | l_ptr->peer_session = INVALID_SESSION; |
700 | 718 | ||
701 | /* Prepare for max packet size negotiation */ | 719 | /* Prepare for max packet size negotiation */ |
702 | link_init_max_pkt(l_ptr); | 720 | link_init_max_pkt(l_ptr); |
@@ -1110,7 +1128,7 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf) | |||
1110 | 1128 | ||
1111 | if (bundler) { | 1129 | if (bundler) { |
1112 | msg_init(&bundler_hdr, MSG_BUNDLER, OPEN_MSG, | 1130 | msg_init(&bundler_hdr, MSG_BUNDLER, OPEN_MSG, |
1113 | TIPC_OK, INT_H_SIZE, l_ptr->addr); | 1131 | INT_H_SIZE, l_ptr->addr); |
1114 | skb_copy_to_linear_data(bundler, &bundler_hdr, | 1132 | skb_copy_to_linear_data(bundler, &bundler_hdr, |
1115 | INT_H_SIZE); | 1133 | INT_H_SIZE); |
1116 | skb_trim(bundler, INT_H_SIZE); | 1134 | skb_trim(bundler, INT_H_SIZE); |
@@ -1374,7 +1392,7 @@ again: | |||
1374 | 1392 | ||
1375 | msg_dbg(hdr, ">FRAGMENTING>"); | 1393 | msg_dbg(hdr, ">FRAGMENTING>"); |
1376 | msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, | 1394 | msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, |
1377 | TIPC_OK, INT_H_SIZE, msg_destnode(hdr)); | 1395 | INT_H_SIZE, msg_destnode(hdr)); |
1378 | msg_set_link_selector(&fragm_hdr, sender->publ.ref); | 1396 | msg_set_link_selector(&fragm_hdr, sender->publ.ref); |
1379 | msg_set_size(&fragm_hdr, max_pkt); | 1397 | msg_set_size(&fragm_hdr, max_pkt); |
1380 | msg_set_fragm_no(&fragm_hdr, 1); | 1398 | msg_set_fragm_no(&fragm_hdr, 1); |
@@ -1543,7 +1561,7 @@ u32 tipc_link_push_packet(struct link *l_ptr) | |||
1543 | l_ptr->retransm_queue_head = mod(++r_q_head); | 1561 | l_ptr->retransm_queue_head = mod(++r_q_head); |
1544 | l_ptr->retransm_queue_size = --r_q_size; | 1562 | l_ptr->retransm_queue_size = --r_q_size; |
1545 | l_ptr->stats.retransmitted++; | 1563 | l_ptr->stats.retransmitted++; |
1546 | return TIPC_OK; | 1564 | return 0; |
1547 | } else { | 1565 | } else { |
1548 | l_ptr->stats.bearer_congs++; | 1566 | l_ptr->stats.bearer_congs++; |
1549 | msg_dbg(buf_msg(buf), "|>DEF-RETR>"); | 1567 | msg_dbg(buf_msg(buf), "|>DEF-RETR>"); |
@@ -1562,7 +1580,7 @@ u32 tipc_link_push_packet(struct link *l_ptr) | |||
1562 | l_ptr->unacked_window = 0; | 1580 | l_ptr->unacked_window = 0; |
1563 | buf_discard(buf); | 1581 | buf_discard(buf); |
1564 | l_ptr->proto_msg_queue = NULL; | 1582 | l_ptr->proto_msg_queue = NULL; |
1565 | return TIPC_OK; | 1583 | return 0; |
1566 | } else { | 1584 | } else { |
1567 | msg_dbg(buf_msg(buf), "|>DEF-PROT>"); | 1585 | msg_dbg(buf_msg(buf), "|>DEF-PROT>"); |
1568 | l_ptr->stats.bearer_congs++; | 1586 | l_ptr->stats.bearer_congs++; |
@@ -1586,7 +1604,7 @@ u32 tipc_link_push_packet(struct link *l_ptr) | |||
1586 | msg_set_type(msg, CLOSED_MSG); | 1604 | msg_set_type(msg, CLOSED_MSG); |
1587 | msg_dbg(msg, ">PUSH-DATA>"); | 1605 | msg_dbg(msg, ">PUSH-DATA>"); |
1588 | l_ptr->next_out = buf->next; | 1606 | l_ptr->next_out = buf->next; |
1589 | return TIPC_OK; | 1607 | return 0; |
1590 | } else { | 1608 | } else { |
1591 | msg_dbg(msg, "|PUSH-DATA|"); | 1609 | msg_dbg(msg, "|PUSH-DATA|"); |
1592 | l_ptr->stats.bearer_congs++; | 1610 | l_ptr->stats.bearer_congs++; |
@@ -1610,8 +1628,8 @@ void tipc_link_push_queue(struct link *l_ptr) | |||
1610 | 1628 | ||
1611 | do { | 1629 | do { |
1612 | res = tipc_link_push_packet(l_ptr); | 1630 | res = tipc_link_push_packet(l_ptr); |
1613 | } | 1631 | } while (!res); |
1614 | while (res == TIPC_OK); | 1632 | |
1615 | if (res == PUSH_FAILED) | 1633 | if (res == PUSH_FAILED) |
1616 | tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); | 1634 | tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); |
1617 | } | 1635 | } |
@@ -1651,7 +1669,7 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf) | |||
1651 | struct tipc_msg *msg = buf_msg(buf); | 1669 | struct tipc_msg *msg = buf_msg(buf); |
1652 | 1670 | ||
1653 | warn("Retransmission failure on link <%s>\n", l_ptr->name); | 1671 | warn("Retransmission failure on link <%s>\n", l_ptr->name); |
1654 | tipc_msg_print(TIPC_OUTPUT, msg, ">RETR-FAIL>"); | 1672 | tipc_msg_dbg(TIPC_OUTPUT, msg, ">RETR-FAIL>"); |
1655 | 1673 | ||
1656 | if (l_ptr->addr) { | 1674 | if (l_ptr->addr) { |
1657 | 1675 | ||
@@ -1748,21 +1766,6 @@ void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf, | |||
1748 | l_ptr->retransm_queue_head = l_ptr->retransm_queue_size = 0; | 1766 | l_ptr->retransm_queue_head = l_ptr->retransm_queue_size = 0; |
1749 | } | 1767 | } |
1750 | 1768 | ||
1751 | /* | ||
1752 | * link_recv_non_seq: Receive packets which are outside | ||
1753 | * the link sequence flow | ||
1754 | */ | ||
1755 | |||
1756 | static void link_recv_non_seq(struct sk_buff *buf) | ||
1757 | { | ||
1758 | struct tipc_msg *msg = buf_msg(buf); | ||
1759 | |||
1760 | if (msg_user(msg) == LINK_CONFIG) | ||
1761 | tipc_disc_recv_msg(buf); | ||
1762 | else | ||
1763 | tipc_bclink_recv_pkt(buf); | ||
1764 | } | ||
1765 | |||
1766 | /** | 1769 | /** |
1767 | * link_insert_deferred_queue - insert deferred messages back into receive chain | 1770 | * link_insert_deferred_queue - insert deferred messages back into receive chain |
1768 | */ | 1771 | */ |
@@ -1839,7 +1842,7 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) | |||
1839 | { | 1842 | { |
1840 | read_lock_bh(&tipc_net_lock); | 1843 | read_lock_bh(&tipc_net_lock); |
1841 | while (head) { | 1844 | while (head) { |
1842 | struct bearer *b_ptr; | 1845 | struct bearer *b_ptr = (struct bearer *)tb_ptr; |
1843 | struct node *n_ptr; | 1846 | struct node *n_ptr; |
1844 | struct link *l_ptr; | 1847 | struct link *l_ptr; |
1845 | struct sk_buff *crs; | 1848 | struct sk_buff *crs; |
@@ -1850,9 +1853,6 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) | |||
1850 | u32 released = 0; | 1853 | u32 released = 0; |
1851 | int type; | 1854 | int type; |
1852 | 1855 | ||
1853 | b_ptr = (struct bearer *)tb_ptr; | ||
1854 | TIPC_SKB_CB(buf)->handle = b_ptr; | ||
1855 | |||
1856 | head = head->next; | 1856 | head = head->next; |
1857 | 1857 | ||
1858 | /* Ensure message is well-formed */ | 1858 | /* Ensure message is well-formed */ |
@@ -1871,7 +1871,10 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) | |||
1871 | msg = buf_msg(buf); | 1871 | msg = buf_msg(buf); |
1872 | 1872 | ||
1873 | if (unlikely(msg_non_seq(msg))) { | 1873 | if (unlikely(msg_non_seq(msg))) { |
1874 | link_recv_non_seq(buf); | 1874 | if (msg_user(msg) == LINK_CONFIG) |
1875 | tipc_disc_recv_msg(buf, b_ptr); | ||
1876 | else | ||
1877 | tipc_bclink_recv_pkt(buf); | ||
1875 | continue; | 1878 | continue; |
1876 | } | 1879 | } |
1877 | 1880 | ||
@@ -1978,8 +1981,6 @@ deliver: | |||
1978 | if (link_recv_changeover_msg(&l_ptr, &buf)) { | 1981 | if (link_recv_changeover_msg(&l_ptr, &buf)) { |
1979 | msg = buf_msg(buf); | 1982 | msg = buf_msg(buf); |
1980 | seq_no = msg_seqno(msg); | 1983 | seq_no = msg_seqno(msg); |
1981 | TIPC_SKB_CB(buf)->handle | ||
1982 | = b_ptr; | ||
1983 | if (type == ORIGINAL_MSG) | 1984 | if (type == ORIGINAL_MSG) |
1984 | goto deliver; | 1985 | goto deliver; |
1985 | goto protocol_check; | 1986 | goto protocol_check; |
@@ -2263,7 +2264,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) | |||
2263 | switch (msg_type(msg)) { | 2264 | switch (msg_type(msg)) { |
2264 | 2265 | ||
2265 | case RESET_MSG: | 2266 | case RESET_MSG: |
2266 | if (!link_working_unknown(l_ptr) && l_ptr->peer_session) { | 2267 | if (!link_working_unknown(l_ptr) && |
2268 | (l_ptr->peer_session != INVALID_SESSION)) { | ||
2267 | if (msg_session(msg) == l_ptr->peer_session) { | 2269 | if (msg_session(msg) == l_ptr->peer_session) { |
2268 | dbg("Duplicate RESET: %u<->%u\n", | 2270 | dbg("Duplicate RESET: %u<->%u\n", |
2269 | msg_session(msg), l_ptr->peer_session); | 2271 | msg_session(msg), l_ptr->peer_session); |
@@ -2424,7 +2426,7 @@ void tipc_link_changeover(struct link *l_ptr) | |||
2424 | } | 2426 | } |
2425 | 2427 | ||
2426 | msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL, | 2428 | msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL, |
2427 | ORIGINAL_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr); | 2429 | ORIGINAL_MSG, INT_H_SIZE, l_ptr->addr); |
2428 | msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); | 2430 | msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); |
2429 | msg_set_msgcnt(&tunnel_hdr, msgcount); | 2431 | msg_set_msgcnt(&tunnel_hdr, msgcount); |
2430 | dbg("Link changeover requires %u tunnel messages\n", msgcount); | 2432 | dbg("Link changeover requires %u tunnel messages\n", msgcount); |
@@ -2479,7 +2481,7 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel) | |||
2479 | struct tipc_msg tunnel_hdr; | 2481 | struct tipc_msg tunnel_hdr; |
2480 | 2482 | ||
2481 | msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL, | 2483 | msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL, |
2482 | DUPLICATE_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr); | 2484 | DUPLICATE_MSG, INT_H_SIZE, l_ptr->addr); |
2483 | msg_set_msgcnt(&tunnel_hdr, l_ptr->out_queue_size); | 2485 | msg_set_msgcnt(&tunnel_hdr, l_ptr->out_queue_size); |
2484 | msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); | 2486 | msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); |
2485 | iter = l_ptr->first_out; | 2487 | iter = l_ptr->first_out; |
@@ -2672,10 +2674,12 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) | |||
2672 | u32 pack_sz = link_max_pkt(l_ptr); | 2674 | u32 pack_sz = link_max_pkt(l_ptr); |
2673 | u32 fragm_sz = pack_sz - INT_H_SIZE; | 2675 | u32 fragm_sz = pack_sz - INT_H_SIZE; |
2674 | u32 fragm_no = 1; | 2676 | u32 fragm_no = 1; |
2675 | u32 destaddr = msg_destnode(inmsg); | 2677 | u32 destaddr; |
2676 | 2678 | ||
2677 | if (msg_short(inmsg)) | 2679 | if (msg_short(inmsg)) |
2678 | destaddr = l_ptr->addr; | 2680 | destaddr = l_ptr->addr; |
2681 | else | ||
2682 | destaddr = msg_destnode(inmsg); | ||
2679 | 2683 | ||
2680 | if (msg_routed(inmsg)) | 2684 | if (msg_routed(inmsg)) |
2681 | msg_set_prevnode(inmsg, tipc_own_addr); | 2685 | msg_set_prevnode(inmsg, tipc_own_addr); |
@@ -2683,7 +2687,7 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) | |||
2683 | /* Prepare reusable fragment header: */ | 2687 | /* Prepare reusable fragment header: */ |
2684 | 2688 | ||
2685 | msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, | 2689 | msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, |
2686 | TIPC_OK, INT_H_SIZE, destaddr); | 2690 | INT_H_SIZE, destaddr); |
2687 | msg_set_link_selector(&fragm_hdr, msg_link_selector(inmsg)); | 2691 | msg_set_link_selector(&fragm_hdr, msg_link_selector(inmsg)); |
2688 | msg_set_long_msgno(&fragm_hdr, mod(l_ptr->long_msg_seq_no++)); | 2692 | msg_set_long_msgno(&fragm_hdr, mod(l_ptr->long_msg_seq_no++)); |
2689 | msg_set_fragm_no(&fragm_hdr, fragm_no); | 2693 | msg_set_fragm_no(&fragm_hdr, fragm_no); |
@@ -2994,7 +2998,7 @@ struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space | |||
2994 | link_set_supervision_props(l_ptr, new_value); | 2998 | link_set_supervision_props(l_ptr, new_value); |
2995 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, | 2999 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, |
2996 | 0, 0, new_value, 0, 0); | 3000 | 0, 0, new_value, 0, 0); |
2997 | res = TIPC_OK; | 3001 | res = 0; |
2998 | } | 3002 | } |
2999 | break; | 3003 | break; |
3000 | case TIPC_CMD_SET_LINK_PRI: | 3004 | case TIPC_CMD_SET_LINK_PRI: |
@@ -3003,14 +3007,14 @@ struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space | |||
3003 | l_ptr->priority = new_value; | 3007 | l_ptr->priority = new_value; |
3004 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, | 3008 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, |
3005 | 0, 0, 0, new_value, 0); | 3009 | 0, 0, 0, new_value, 0); |
3006 | res = TIPC_OK; | 3010 | res = 0; |
3007 | } | 3011 | } |
3008 | break; | 3012 | break; |
3009 | case TIPC_CMD_SET_LINK_WINDOW: | 3013 | case TIPC_CMD_SET_LINK_WINDOW: |
3010 | if ((new_value >= TIPC_MIN_LINK_WIN) && | 3014 | if ((new_value >= TIPC_MIN_LINK_WIN) && |
3011 | (new_value <= TIPC_MAX_LINK_WIN)) { | 3015 | (new_value <= TIPC_MAX_LINK_WIN)) { |
3012 | tipc_link_set_queue_limits(l_ptr, new_value); | 3016 | tipc_link_set_queue_limits(l_ptr, new_value); |
3013 | res = TIPC_OK; | 3017 | res = 0; |
3014 | } | 3018 | } |
3015 | break; | 3019 | break; |
3016 | } | 3020 | } |
@@ -3226,7 +3230,7 @@ int link_control(const char *name, u32 op, u32 val) | |||
3226 | if (op == TIPC_CMD_UNBLOCK_LINK) { | 3230 | if (op == TIPC_CMD_UNBLOCK_LINK) { |
3227 | l_ptr->blocked = 0; | 3231 | l_ptr->blocked = 0; |
3228 | } | 3232 | } |
3229 | res = TIPC_OK; | 3233 | res = 0; |
3230 | } | 3234 | } |
3231 | tipc_node_unlock(node); | 3235 | tipc_node_unlock(node); |
3232 | } | 3236 | } |
diff --git a/net/tipc/msg.c b/net/tipc/msg.c index 696a8633df75..73dcd00d674e 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c | |||
@@ -41,7 +41,9 @@ | |||
41 | #include "bearer.h" | 41 | #include "bearer.h" |
42 | 42 | ||
43 | 43 | ||
44 | void tipc_msg_print(struct print_buf *buf, struct tipc_msg *msg, const char *str) | 44 | #ifdef CONFIG_TIPC_DEBUG |
45 | |||
46 | void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) | ||
45 | { | 47 | { |
46 | u32 usr = msg_user(msg); | 48 | u32 usr = msg_user(msg); |
47 | tipc_printf(buf, str); | 49 | tipc_printf(buf, str); |
@@ -228,13 +230,10 @@ void tipc_msg_print(struct print_buf *buf, struct tipc_msg *msg, const char *str | |||
228 | 230 | ||
229 | switch (usr) { | 231 | switch (usr) { |
230 | case CONN_MANAGER: | 232 | case CONN_MANAGER: |
231 | case NAME_DISTRIBUTOR: | ||
232 | case TIPC_LOW_IMPORTANCE: | 233 | case TIPC_LOW_IMPORTANCE: |
233 | case TIPC_MEDIUM_IMPORTANCE: | 234 | case TIPC_MEDIUM_IMPORTANCE: |
234 | case TIPC_HIGH_IMPORTANCE: | 235 | case TIPC_HIGH_IMPORTANCE: |
235 | case TIPC_CRITICAL_IMPORTANCE: | 236 | case TIPC_CRITICAL_IMPORTANCE: |
236 | if (msg_short(msg)) | ||
237 | break; /* No error */ | ||
238 | switch (msg_errcode(msg)) { | 237 | switch (msg_errcode(msg)) { |
239 | case TIPC_OK: | 238 | case TIPC_OK: |
240 | break; | 239 | break; |
@@ -315,9 +314,11 @@ void tipc_msg_print(struct print_buf *buf, struct tipc_msg *msg, const char *str | |||
315 | } | 314 | } |
316 | tipc_printf(buf, "\n"); | 315 | tipc_printf(buf, "\n"); |
317 | if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg))) { | 316 | if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg))) { |
318 | tipc_msg_print(buf,msg_get_wrapped(msg)," /"); | 317 | tipc_msg_dbg(buf, msg_get_wrapped(msg), " /"); |
319 | } | 318 | } |
320 | if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT)) { | 319 | if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT)) { |
321 | tipc_msg_print(buf,msg_get_wrapped(msg)," /"); | 320 | tipc_msg_dbg(buf, msg_get_wrapped(msg), " /"); |
322 | } | 321 | } |
323 | } | 322 | } |
323 | |||
324 | #endif | ||
diff --git a/net/tipc/msg.h b/net/tipc/msg.h index ad487e8abcc2..7ee6ae238147 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h | |||
@@ -2,7 +2,7 @@ | |||
2 | * net/tipc/msg.h: Include file for TIPC message header routines | 2 | * net/tipc/msg.h: Include file for TIPC message header routines |
3 | * | 3 | * |
4 | * Copyright (c) 2000-2007, Ericsson AB | 4 | * Copyright (c) 2000-2007, Ericsson AB |
5 | * Copyright (c) 2005-2007, Wind River Systems | 5 | * Copyright (c) 2005-2008, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -75,6 +75,14 @@ static inline void msg_set_bits(struct tipc_msg *m, u32 w, | |||
75 | m->hdr[w] |= htonl(val); | 75 | m->hdr[w] |= htonl(val); |
76 | } | 76 | } |
77 | 77 | ||
78 | static inline void msg_swap_words(struct tipc_msg *msg, u32 a, u32 b) | ||
79 | { | ||
80 | u32 temp = msg->hdr[a]; | ||
81 | |||
82 | msg->hdr[a] = msg->hdr[b]; | ||
83 | msg->hdr[b] = temp; | ||
84 | } | ||
85 | |||
78 | /* | 86 | /* |
79 | * Word 0 | 87 | * Word 0 |
80 | */ | 88 | */ |
@@ -119,9 +127,9 @@ static inline int msg_non_seq(struct tipc_msg *m) | |||
119 | return msg_bits(m, 0, 20, 1); | 127 | return msg_bits(m, 0, 20, 1); |
120 | } | 128 | } |
121 | 129 | ||
122 | static inline void msg_set_non_seq(struct tipc_msg *m) | 130 | static inline void msg_set_non_seq(struct tipc_msg *m, u32 n) |
123 | { | 131 | { |
124 | msg_set_bits(m, 0, 20, 1, 1); | 132 | msg_set_bits(m, 0, 20, 1, n); |
125 | } | 133 | } |
126 | 134 | ||
127 | static inline int msg_dest_droppable(struct tipc_msg *m) | 135 | static inline int msg_dest_droppable(struct tipc_msg *m) |
@@ -224,6 +232,25 @@ static inline void msg_set_seqno(struct tipc_msg *m, u32 n) | |||
224 | msg_set_bits(m, 2, 0, 0xffff, n); | 232 | msg_set_bits(m, 2, 0, 0xffff, n); |
225 | } | 233 | } |
226 | 234 | ||
235 | /* | ||
236 | * TIPC may utilize the "link ack #" and "link seq #" fields of a short | ||
237 | * message header to hold the destination node for the message, since the | ||
238 | * normal "dest node" field isn't present. This cache is only referenced | ||
239 | * when required, so populating the cache of a longer message header is | ||
240 | * harmless (as long as the header has the two link sequence fields present). | ||
241 | * | ||
242 | * Note: Host byte order is OK here, since the info never goes off-card. | ||
243 | */ | ||
244 | |||
245 | static inline u32 msg_destnode_cache(struct tipc_msg *m) | ||
246 | { | ||
247 | return m->hdr[2]; | ||
248 | } | ||
249 | |||
250 | static inline void msg_set_destnode_cache(struct tipc_msg *m, u32 dnode) | ||
251 | { | ||
252 | m->hdr[2] = dnode; | ||
253 | } | ||
227 | 254 | ||
228 | /* | 255 | /* |
229 | * Words 3-10 | 256 | * Words 3-10 |
@@ -325,7 +352,7 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m) | |||
325 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 352 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
326 | w0:|vers |msg usr|hdr sz |n|resrv| packet size | | 353 | w0:|vers |msg usr|hdr sz |n|resrv| packet size | |
327 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 354 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
328 | w1:|m typ|rsv=0| sequence gap | broadcast ack no | | 355 | w1:|m typ| sequence gap | broadcast ack no | |
329 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 356 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
330 | w2:| link level ack no/bc_gap_from | seq no / bcast_gap_to | | 357 | w2:| link level ack no/bc_gap_from | seq no / bcast_gap_to | |
331 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 358 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
@@ -388,12 +415,12 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m) | |||
388 | 415 | ||
389 | static inline u32 msg_seq_gap(struct tipc_msg *m) | 416 | static inline u32 msg_seq_gap(struct tipc_msg *m) |
390 | { | 417 | { |
391 | return msg_bits(m, 1, 16, 0xff); | 418 | return msg_bits(m, 1, 16, 0x1fff); |
392 | } | 419 | } |
393 | 420 | ||
394 | static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n) | 421 | static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n) |
395 | { | 422 | { |
396 | msg_set_bits(m, 1, 16, 0xff, n); | 423 | msg_set_bits(m, 1, 16, 0x1fff, n); |
397 | } | 424 | } |
398 | 425 | ||
399 | static inline u32 msg_req_links(struct tipc_msg *m) | 426 | static inline u32 msg_req_links(struct tipc_msg *m) |
@@ -696,7 +723,7 @@ static inline u32 msg_tot_importance(struct tipc_msg *m) | |||
696 | 723 | ||
697 | 724 | ||
698 | static inline void msg_init(struct tipc_msg *m, u32 user, u32 type, | 725 | static inline void msg_init(struct tipc_msg *m, u32 user, u32 type, |
699 | u32 err, u32 hsize, u32 destnode) | 726 | u32 hsize, u32 destnode) |
700 | { | 727 | { |
701 | memset(m, 0, hsize); | 728 | memset(m, 0, hsize); |
702 | msg_set_version(m); | 729 | msg_set_version(m); |
@@ -705,7 +732,6 @@ static inline void msg_init(struct tipc_msg *m, u32 user, u32 type, | |||
705 | msg_set_size(m, hsize); | 732 | msg_set_size(m, hsize); |
706 | msg_set_prevnode(m, tipc_own_addr); | 733 | msg_set_prevnode(m, tipc_own_addr); |
707 | msg_set_type(m, type); | 734 | msg_set_type(m, type); |
708 | msg_set_errcode(m, err); | ||
709 | if (!msg_short(m)) { | 735 | if (!msg_short(m)) { |
710 | msg_set_orignode(m, tipc_own_addr); | 736 | msg_set_orignode(m, tipc_own_addr); |
711 | msg_set_destnode(m, destnode); | 737 | msg_set_destnode(m, destnode); |
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index 39fd1619febf..10a69894e2fd 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c | |||
@@ -41,9 +41,6 @@ | |||
41 | #include "msg.h" | 41 | #include "msg.h" |
42 | #include "name_distr.h" | 42 | #include "name_distr.h" |
43 | 43 | ||
44 | #undef DBG_OUTPUT | ||
45 | #define DBG_OUTPUT NULL | ||
46 | |||
47 | #define ITEM_SIZE sizeof(struct distr_item) | 44 | #define ITEM_SIZE sizeof(struct distr_item) |
48 | 45 | ||
49 | /** | 46 | /** |
@@ -106,8 +103,7 @@ static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest) | |||
106 | 103 | ||
107 | if (buf != NULL) { | 104 | if (buf != NULL) { |
108 | msg = buf_msg(buf); | 105 | msg = buf_msg(buf); |
109 | msg_init(msg, NAME_DISTRIBUTOR, type, TIPC_OK, | 106 | msg_init(msg, NAME_DISTRIBUTOR, type, LONG_H_SIZE, dest); |
110 | LONG_H_SIZE, dest); | ||
111 | msg_set_size(msg, LONG_H_SIZE + size); | 107 | msg_set_size(msg, LONG_H_SIZE + size); |
112 | } | 108 | } |
113 | return buf; | 109 | return buf; |
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index ac7dfdda7973..cd72e22b132b 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * net/tipc/name_table.c: TIPC name table code | 2 | * net/tipc/name_table.c: TIPC name table code |
3 | * | 3 | * |
4 | * Copyright (c) 2000-2006, Ericsson AB | 4 | * Copyright (c) 2000-2006, Ericsson AB |
5 | * Copyright (c) 2004-2005, Wind River Systems | 5 | * Copyright (c) 2004-2008, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -52,9 +52,16 @@ static int tipc_nametbl_size = 1024; /* must be a power of 2 */ | |||
52 | * struct sub_seq - container for all published instances of a name sequence | 52 | * struct sub_seq - container for all published instances of a name sequence |
53 | * @lower: name sequence lower bound | 53 | * @lower: name sequence lower bound |
54 | * @upper: name sequence upper bound | 54 | * @upper: name sequence upper bound |
55 | * @node_list: circular list of matching publications with >= node scope | 55 | * @node_list: circular list of publications made by own node |
56 | * @cluster_list: circular list of matching publications with >= cluster scope | 56 | * @cluster_list: circular list of publications made by own cluster |
57 | * @zone_list: circular list of matching publications with >= zone scope | 57 | * @zone_list: circular list of publications made by own zone |
58 | * @node_list_size: number of entries in "node_list" | ||
59 | * @cluster_list_size: number of entries in "cluster_list" | ||
60 | * @zone_list_size: number of entries in "zone_list" | ||
61 | * | ||
62 | * Note: The zone list always contains at least one entry, since all | ||
63 | * publications of the associated name sequence belong to it. | ||
64 | * (The cluster and node lists may be empty.) | ||
58 | */ | 65 | */ |
59 | 66 | ||
60 | struct sub_seq { | 67 | struct sub_seq { |
@@ -63,6 +70,9 @@ struct sub_seq { | |||
63 | struct publication *node_list; | 70 | struct publication *node_list; |
64 | struct publication *cluster_list; | 71 | struct publication *cluster_list; |
65 | struct publication *zone_list; | 72 | struct publication *zone_list; |
73 | u32 node_list_size; | ||
74 | u32 cluster_list_size; | ||
75 | u32 zone_list_size; | ||
66 | }; | 76 | }; |
67 | 77 | ||
68 | /** | 78 | /** |
@@ -74,7 +84,7 @@ struct sub_seq { | |||
74 | * @first_free: array index of first unused sub-sequence entry | 84 | * @first_free: array index of first unused sub-sequence entry |
75 | * @ns_list: links to adjacent name sequences in hash chain | 85 | * @ns_list: links to adjacent name sequences in hash chain |
76 | * @subscriptions: list of subscriptions for this 'type' | 86 | * @subscriptions: list of subscriptions for this 'type' |
77 | * @lock: spinlock controlling access to name sequence structure | 87 | * @lock: spinlock controlling access to publication lists of all sub-sequences |
78 | */ | 88 | */ |
79 | 89 | ||
80 | struct name_seq { | 90 | struct name_seq { |
@@ -317,6 +327,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
317 | dbg("inserting publ %p, node=0x%x publ->node=0x%x, subscr->node=%p\n", | 327 | dbg("inserting publ %p, node=0x%x publ->node=0x%x, subscr->node=%p\n", |
318 | publ, node, publ->node, publ->subscr.node); | 328 | publ, node, publ->node, publ->subscr.node); |
319 | 329 | ||
330 | sseq->zone_list_size++; | ||
320 | if (!sseq->zone_list) | 331 | if (!sseq->zone_list) |
321 | sseq->zone_list = publ->zone_list_next = publ; | 332 | sseq->zone_list = publ->zone_list_next = publ; |
322 | else { | 333 | else { |
@@ -325,6 +336,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
325 | } | 336 | } |
326 | 337 | ||
327 | if (in_own_cluster(node)) { | 338 | if (in_own_cluster(node)) { |
339 | sseq->cluster_list_size++; | ||
328 | if (!sseq->cluster_list) | 340 | if (!sseq->cluster_list) |
329 | sseq->cluster_list = publ->cluster_list_next = publ; | 341 | sseq->cluster_list = publ->cluster_list_next = publ; |
330 | else { | 342 | else { |
@@ -335,6 +347,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
335 | } | 347 | } |
336 | 348 | ||
337 | if (node == tipc_own_addr) { | 349 | if (node == tipc_own_addr) { |
350 | sseq->node_list_size++; | ||
338 | if (!sseq->node_list) | 351 | if (!sseq->node_list) |
339 | sseq->node_list = publ->node_list_next = publ; | 352 | sseq->node_list = publ->node_list_next = publ; |
340 | else { | 353 | else { |
@@ -411,6 +424,7 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i | |||
411 | } else { | 424 | } else { |
412 | sseq->zone_list = NULL; | 425 | sseq->zone_list = NULL; |
413 | } | 426 | } |
427 | sseq->zone_list_size--; | ||
414 | 428 | ||
415 | /* Remove publication from cluster scope list, if present */ | 429 | /* Remove publication from cluster scope list, if present */ |
416 | 430 | ||
@@ -439,6 +453,7 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i | |||
439 | } else { | 453 | } else { |
440 | sseq->cluster_list = NULL; | 454 | sseq->cluster_list = NULL; |
441 | } | 455 | } |
456 | sseq->cluster_list_size--; | ||
442 | } | 457 | } |
443 | end_cluster: | 458 | end_cluster: |
444 | 459 | ||
@@ -469,6 +484,7 @@ end_cluster: | |||
469 | } else { | 484 | } else { |
470 | sseq->node_list = NULL; | 485 | sseq->node_list = NULL; |
471 | } | 486 | } |
487 | sseq->node_list_size--; | ||
472 | } | 488 | } |
473 | end_node: | 489 | end_node: |
474 | 490 | ||
@@ -709,15 +725,18 @@ int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit, | |||
709 | 725 | ||
710 | if (sseq->lower > upper) | 726 | if (sseq->lower > upper) |
711 | break; | 727 | break; |
712 | publ = sseq->cluster_list; | 728 | |
713 | if (publ && (publ->scope <= limit)) | 729 | publ = sseq->node_list; |
730 | if (publ) { | ||
714 | do { | 731 | do { |
715 | if (publ->node == tipc_own_addr) | 732 | if (publ->scope <= limit) |
716 | tipc_port_list_add(dports, publ->ref); | 733 | tipc_port_list_add(dports, publ->ref); |
717 | else | 734 | publ = publ->node_list_next; |
718 | res = 1; | 735 | } while (publ != sseq->node_list); |
719 | publ = publ->cluster_list_next; | 736 | } |
720 | } while (publ != sseq->cluster_list); | 737 | |
738 | if (sseq->cluster_list_size != sseq->node_list_size) | ||
739 | res = 1; | ||
721 | } | 740 | } |
722 | 741 | ||
723 | spin_unlock_bh(&seq->lock); | 742 | spin_unlock_bh(&seq->lock); |
@@ -905,6 +924,9 @@ static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth, | |||
905 | struct sub_seq *sseq; | 924 | struct sub_seq *sseq; |
906 | char typearea[11]; | 925 | char typearea[11]; |
907 | 926 | ||
927 | if (seq->first_free == 0) | ||
928 | return; | ||
929 | |||
908 | sprintf(typearea, "%-10u", seq->type); | 930 | sprintf(typearea, "%-10u", seq->type); |
909 | 931 | ||
910 | if (depth == 1) { | 932 | if (depth == 1) { |
@@ -915,7 +937,9 @@ static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth, | |||
915 | for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) { | 937 | for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) { |
916 | if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) { | 938 | if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) { |
917 | tipc_printf(buf, "%s ", typearea); | 939 | tipc_printf(buf, "%s ", typearea); |
940 | spin_lock_bh(&seq->lock); | ||
918 | subseq_list(sseq, buf, depth, index); | 941 | subseq_list(sseq, buf, depth, index); |
942 | spin_unlock_bh(&seq->lock); | ||
919 | sprintf(typearea, "%10s", " "); | 943 | sprintf(typearea, "%10s", " "); |
920 | } | 944 | } |
921 | } | 945 | } |
@@ -1050,15 +1074,12 @@ void tipc_nametbl_dump(void) | |||
1050 | 1074 | ||
1051 | int tipc_nametbl_init(void) | 1075 | int tipc_nametbl_init(void) |
1052 | { | 1076 | { |
1053 | int array_size = sizeof(struct hlist_head) * tipc_nametbl_size; | 1077 | table.types = kcalloc(tipc_nametbl_size, sizeof(struct hlist_head), |
1054 | 1078 | GFP_ATOMIC); | |
1055 | table.types = kzalloc(array_size, GFP_ATOMIC); | ||
1056 | if (!table.types) | 1079 | if (!table.types) |
1057 | return -ENOMEM; | 1080 | return -ENOMEM; |
1058 | 1081 | ||
1059 | write_lock_bh(&tipc_nametbl_lock); | ||
1060 | table.local_publ_count = 0; | 1082 | table.local_publ_count = 0; |
1061 | write_unlock_bh(&tipc_nametbl_lock); | ||
1062 | return 0; | 1083 | return 0; |
1063 | } | 1084 | } |
1064 | 1085 | ||
diff --git a/net/tipc/net.c b/net/tipc/net.c index c39c76201e8e..ec7b04fbdc43 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c | |||
@@ -165,7 +165,7 @@ static int net_init(void) | |||
165 | if (!tipc_net.zones) { | 165 | if (!tipc_net.zones) { |
166 | return -ENOMEM; | 166 | return -ENOMEM; |
167 | } | 167 | } |
168 | return TIPC_OK; | 168 | return 0; |
169 | } | 169 | } |
170 | 170 | ||
171 | static void net_stop(void) | 171 | static void net_stop(void) |
@@ -266,7 +266,7 @@ void tipc_net_route_msg(struct sk_buff *buf) | |||
266 | tipc_link_send(buf, dnode, msg_link_selector(msg)); | 266 | tipc_link_send(buf, dnode, msg_link_selector(msg)); |
267 | } | 267 | } |
268 | 268 | ||
269 | int tipc_net_start(void) | 269 | int tipc_net_start(u32 addr) |
270 | { | 270 | { |
271 | char addr_string[16]; | 271 | char addr_string[16]; |
272 | int res; | 272 | int res; |
@@ -274,6 +274,10 @@ int tipc_net_start(void) | |||
274 | if (tipc_mode != TIPC_NODE_MODE) | 274 | if (tipc_mode != TIPC_NODE_MODE) |
275 | return -ENOPROTOOPT; | 275 | return -ENOPROTOOPT; |
276 | 276 | ||
277 | tipc_subscr_stop(); | ||
278 | tipc_cfg_stop(); | ||
279 | |||
280 | tipc_own_addr = addr; | ||
277 | tipc_mode = TIPC_NET_MODE; | 281 | tipc_mode = TIPC_NET_MODE; |
278 | tipc_named_reinit(); | 282 | tipc_named_reinit(); |
279 | tipc_port_reinit(); | 283 | tipc_port_reinit(); |
@@ -284,14 +288,14 @@ int tipc_net_start(void) | |||
284 | (res = tipc_bclink_init())) { | 288 | (res = tipc_bclink_init())) { |
285 | return res; | 289 | return res; |
286 | } | 290 | } |
287 | tipc_subscr_stop(); | 291 | |
288 | tipc_cfg_stop(); | ||
289 | tipc_k_signal((Handler)tipc_subscr_start, 0); | 292 | tipc_k_signal((Handler)tipc_subscr_start, 0); |
290 | tipc_k_signal((Handler)tipc_cfg_init, 0); | 293 | tipc_k_signal((Handler)tipc_cfg_init, 0); |
294 | |||
291 | info("Started in network mode\n"); | 295 | info("Started in network mode\n"); |
292 | info("Own node address %s, network identity %u\n", | 296 | info("Own node address %s, network identity %u\n", |
293 | addr_string_fill(addr_string, tipc_own_addr), tipc_net_id); | 297 | addr_string_fill(addr_string, tipc_own_addr), tipc_net_id); |
294 | return TIPC_OK; | 298 | return 0; |
295 | } | 299 | } |
296 | 300 | ||
297 | void tipc_net_stop(void) | 301 | void tipc_net_stop(void) |
diff --git a/net/tipc/net.h b/net/tipc/net.h index a6a0e9976ac9..d154ac2bda9a 100644 --- a/net/tipc/net.h +++ b/net/tipc/net.h | |||
@@ -58,7 +58,7 @@ void tipc_net_route_msg(struct sk_buff *buf); | |||
58 | struct node *tipc_net_select_remote_node(u32 addr, u32 ref); | 58 | struct node *tipc_net_select_remote_node(u32 addr, u32 ref); |
59 | u32 tipc_net_select_router(u32 addr, u32 ref); | 59 | u32 tipc_net_select_router(u32 addr, u32 ref); |
60 | 60 | ||
61 | int tipc_net_start(void); | 61 | int tipc_net_start(u32 addr); |
62 | void tipc_net_stop(void); | 62 | void tipc_net_stop(void); |
63 | 63 | ||
64 | #endif | 64 | #endif |
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index 6a7f7b4c2595..c387217bb230 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * net/tipc/netlink.c: TIPC configuration handling | 2 | * net/tipc/netlink.c: TIPC configuration handling |
3 | * | 3 | * |
4 | * Copyright (c) 2005-2006, Ericsson AB | 4 | * Copyright (c) 2005-2006, Ericsson AB |
5 | * Copyright (c) 2005, Wind River Systems | 5 | * Copyright (c) 2005-2007, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -45,15 +45,17 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info) | |||
45 | struct nlmsghdr *req_nlh = info->nlhdr; | 45 | struct nlmsghdr *req_nlh = info->nlhdr; |
46 | struct tipc_genlmsghdr *req_userhdr = info->userhdr; | 46 | struct tipc_genlmsghdr *req_userhdr = info->userhdr; |
47 | int hdr_space = NLMSG_SPACE(GENL_HDRLEN + TIPC_GENL_HDRLEN); | 47 | int hdr_space = NLMSG_SPACE(GENL_HDRLEN + TIPC_GENL_HDRLEN); |
48 | u16 cmd; | ||
48 | 49 | ||
49 | if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN))) | 50 | if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN))) |
50 | rep_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN); | 51 | cmd = TIPC_CMD_NOT_NET_ADMIN; |
51 | else | 52 | else |
52 | rep_buf = tipc_cfg_do_cmd(req_userhdr->dest, | 53 | cmd = req_userhdr->cmd; |
53 | req_userhdr->cmd, | 54 | |
54 | NLMSG_DATA(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN, | 55 | rep_buf = tipc_cfg_do_cmd(req_userhdr->dest, cmd, |
55 | NLMSG_PAYLOAD(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN), | 56 | NLMSG_DATA(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN, |
56 | hdr_space); | 57 | NLMSG_PAYLOAD(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN), |
58 | hdr_space); | ||
57 | 59 | ||
58 | if (rep_buf) { | 60 | if (rep_buf) { |
59 | skb_push(rep_buf, hdr_space); | 61 | skb_push(rep_buf, hdr_space); |
diff --git a/net/tipc/node.c b/net/tipc/node.c index 598f4d3a0098..ee952ad60218 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -52,16 +52,40 @@ static void node_established_contact(struct node *n_ptr); | |||
52 | 52 | ||
53 | struct node *tipc_nodes = NULL; /* sorted list of nodes within cluster */ | 53 | struct node *tipc_nodes = NULL; /* sorted list of nodes within cluster */ |
54 | 54 | ||
55 | static DEFINE_SPINLOCK(node_create_lock); | ||
56 | |||
55 | u32 tipc_own_tag = 0; | 57 | u32 tipc_own_tag = 0; |
56 | 58 | ||
59 | /** | ||
60 | * tipc_node_create - create neighboring node | ||
61 | * | ||
62 | * Currently, this routine is called by neighbor discovery code, which holds | ||
63 | * net_lock for reading only. We must take node_create_lock to ensure a node | ||
64 | * isn't created twice if two different bearers discover the node at the same | ||
65 | * time. (It would be preferable to switch to holding net_lock in write mode, | ||
66 | * but this is a non-trivial change.) | ||
67 | */ | ||
68 | |||
57 | struct node *tipc_node_create(u32 addr) | 69 | struct node *tipc_node_create(u32 addr) |
58 | { | 70 | { |
59 | struct cluster *c_ptr; | 71 | struct cluster *c_ptr; |
60 | struct node *n_ptr; | 72 | struct node *n_ptr; |
61 | struct node **curr_node; | 73 | struct node **curr_node; |
62 | 74 | ||
75 | spin_lock_bh(&node_create_lock); | ||
76 | |||
77 | for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { | ||
78 | if (addr < n_ptr->addr) | ||
79 | break; | ||
80 | if (addr == n_ptr->addr) { | ||
81 | spin_unlock_bh(&node_create_lock); | ||
82 | return n_ptr; | ||
83 | } | ||
84 | } | ||
85 | |||
63 | n_ptr = kzalloc(sizeof(*n_ptr),GFP_ATOMIC); | 86 | n_ptr = kzalloc(sizeof(*n_ptr),GFP_ATOMIC); |
64 | if (!n_ptr) { | 87 | if (!n_ptr) { |
88 | spin_unlock_bh(&node_create_lock); | ||
65 | warn("Node creation failed, no memory\n"); | 89 | warn("Node creation failed, no memory\n"); |
66 | return NULL; | 90 | return NULL; |
67 | } | 91 | } |
@@ -71,6 +95,7 @@ struct node *tipc_node_create(u32 addr) | |||
71 | c_ptr = tipc_cltr_create(addr); | 95 | c_ptr = tipc_cltr_create(addr); |
72 | } | 96 | } |
73 | if (!c_ptr) { | 97 | if (!c_ptr) { |
98 | spin_unlock_bh(&node_create_lock); | ||
74 | kfree(n_ptr); | 99 | kfree(n_ptr); |
75 | return NULL; | 100 | return NULL; |
76 | } | 101 | } |
@@ -91,6 +116,7 @@ struct node *tipc_node_create(u32 addr) | |||
91 | } | 116 | } |
92 | } | 117 | } |
93 | (*curr_node) = n_ptr; | 118 | (*curr_node) = n_ptr; |
119 | spin_unlock_bh(&node_create_lock); | ||
94 | return n_ptr; | 120 | return n_ptr; |
95 | } | 121 | } |
96 | 122 | ||
@@ -574,12 +600,14 @@ u32 tipc_available_nodes(const u32 domain) | |||
574 | struct node *n_ptr; | 600 | struct node *n_ptr; |
575 | u32 cnt = 0; | 601 | u32 cnt = 0; |
576 | 602 | ||
603 | read_lock_bh(&tipc_net_lock); | ||
577 | for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { | 604 | for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { |
578 | if (!in_scope(domain, n_ptr->addr)) | 605 | if (!in_scope(domain, n_ptr->addr)) |
579 | continue; | 606 | continue; |
580 | if (tipc_node_is_up(n_ptr)) | 607 | if (tipc_node_is_up(n_ptr)) |
581 | cnt++; | 608 | cnt++; |
582 | } | 609 | } |
610 | read_unlock_bh(&tipc_net_lock); | ||
583 | return cnt; | 611 | return cnt; |
584 | } | 612 | } |
585 | 613 | ||
@@ -599,19 +627,26 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) | |||
599 | return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE | 627 | return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE |
600 | " (network address)"); | 628 | " (network address)"); |
601 | 629 | ||
602 | if (!tipc_nodes) | 630 | read_lock_bh(&tipc_net_lock); |
631 | if (!tipc_nodes) { | ||
632 | read_unlock_bh(&tipc_net_lock); | ||
603 | return tipc_cfg_reply_none(); | 633 | return tipc_cfg_reply_none(); |
634 | } | ||
604 | 635 | ||
605 | /* For now, get space for all other nodes | 636 | /* For now, get space for all other nodes |
606 | (will need to modify this when slave nodes are supported */ | 637 | (will need to modify this when slave nodes are supported */ |
607 | 638 | ||
608 | payload_size = TLV_SPACE(sizeof(node_info)) * (tipc_max_nodes - 1); | 639 | payload_size = TLV_SPACE(sizeof(node_info)) * (tipc_max_nodes - 1); |
609 | if (payload_size > 32768u) | 640 | if (payload_size > 32768u) { |
641 | read_unlock_bh(&tipc_net_lock); | ||
610 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | 642 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED |
611 | " (too many nodes)"); | 643 | " (too many nodes)"); |
644 | } | ||
612 | buf = tipc_cfg_reply_alloc(payload_size); | 645 | buf = tipc_cfg_reply_alloc(payload_size); |
613 | if (!buf) | 646 | if (!buf) { |
647 | read_unlock_bh(&tipc_net_lock); | ||
614 | return NULL; | 648 | return NULL; |
649 | } | ||
615 | 650 | ||
616 | /* Add TLVs for all nodes in scope */ | 651 | /* Add TLVs for all nodes in scope */ |
617 | 652 | ||
@@ -624,6 +659,7 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) | |||
624 | &node_info, sizeof(node_info)); | 659 | &node_info, sizeof(node_info)); |
625 | } | 660 | } |
626 | 661 | ||
662 | read_unlock_bh(&tipc_net_lock); | ||
627 | return buf; | 663 | return buf; |
628 | } | 664 | } |
629 | 665 | ||
@@ -646,16 +682,22 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space) | |||
646 | if (tipc_mode != TIPC_NET_MODE) | 682 | if (tipc_mode != TIPC_NET_MODE) |
647 | return tipc_cfg_reply_none(); | 683 | return tipc_cfg_reply_none(); |
648 | 684 | ||
685 | read_lock_bh(&tipc_net_lock); | ||
686 | |||
649 | /* Get space for all unicast links + multicast link */ | 687 | /* Get space for all unicast links + multicast link */ |
650 | 688 | ||
651 | payload_size = TLV_SPACE(sizeof(link_info)) * | 689 | payload_size = TLV_SPACE(sizeof(link_info)) * |
652 | (tipc_net.zones[tipc_zone(tipc_own_addr)]->links + 1); | 690 | (tipc_net.zones[tipc_zone(tipc_own_addr)]->links + 1); |
653 | if (payload_size > 32768u) | 691 | if (payload_size > 32768u) { |
692 | read_unlock_bh(&tipc_net_lock); | ||
654 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | 693 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED |
655 | " (too many links)"); | 694 | " (too many links)"); |
695 | } | ||
656 | buf = tipc_cfg_reply_alloc(payload_size); | 696 | buf = tipc_cfg_reply_alloc(payload_size); |
657 | if (!buf) | 697 | if (!buf) { |
698 | read_unlock_bh(&tipc_net_lock); | ||
658 | return NULL; | 699 | return NULL; |
700 | } | ||
659 | 701 | ||
660 | /* Add TLV for broadcast link */ | 702 | /* Add TLV for broadcast link */ |
661 | 703 | ||
@@ -671,6 +713,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space) | |||
671 | 713 | ||
672 | if (!in_scope(domain, n_ptr->addr)) | 714 | if (!in_scope(domain, n_ptr->addr)) |
673 | continue; | 715 | continue; |
716 | tipc_node_lock(n_ptr); | ||
674 | for (i = 0; i < MAX_BEARERS; i++) { | 717 | for (i = 0; i < MAX_BEARERS; i++) { |
675 | if (!n_ptr->links[i]) | 718 | if (!n_ptr->links[i]) |
676 | continue; | 719 | continue; |
@@ -680,7 +723,9 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space) | |||
680 | tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, | 723 | tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, |
681 | &link_info, sizeof(link_info)); | 724 | &link_info, sizeof(link_info)); |
682 | } | 725 | } |
726 | tipc_node_unlock(n_ptr); | ||
683 | } | 727 | } |
684 | 728 | ||
729 | read_unlock_bh(&tipc_net_lock); | ||
685 | return buf; | 730 | return buf; |
686 | } | 731 | } |
diff --git a/net/tipc/port.c b/net/tipc/port.c index 2f5806410c64..e70d27ea6578 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * net/tipc/port.c: TIPC port code | 2 | * net/tipc/port.c: TIPC port code |
3 | * | 3 | * |
4 | * Copyright (c) 1992-2007, Ericsson AB | 4 | * Copyright (c) 1992-2007, Ericsson AB |
5 | * Copyright (c) 2004-2007, Wind River Systems | 5 | * Copyright (c) 2004-2008, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -211,12 +211,12 @@ exit: | |||
211 | } | 211 | } |
212 | 212 | ||
213 | /** | 213 | /** |
214 | * tipc_createport_raw - create a native TIPC port | 214 | * tipc_createport_raw - create a generic TIPC port |
215 | * | 215 | * |
216 | * Returns local port reference | 216 | * Returns pointer to (locked) TIPC port, or NULL if unable to create it |
217 | */ | 217 | */ |
218 | 218 | ||
219 | u32 tipc_createport_raw(void *usr_handle, | 219 | struct tipc_port *tipc_createport_raw(void *usr_handle, |
220 | u32 (*dispatcher)(struct tipc_port *, struct sk_buff *), | 220 | u32 (*dispatcher)(struct tipc_port *, struct sk_buff *), |
221 | void (*wakeup)(struct tipc_port *), | 221 | void (*wakeup)(struct tipc_port *), |
222 | const u32 importance) | 222 | const u32 importance) |
@@ -228,26 +228,21 @@ u32 tipc_createport_raw(void *usr_handle, | |||
228 | p_ptr = kzalloc(sizeof(*p_ptr), GFP_ATOMIC); | 228 | p_ptr = kzalloc(sizeof(*p_ptr), GFP_ATOMIC); |
229 | if (!p_ptr) { | 229 | if (!p_ptr) { |
230 | warn("Port creation failed, no memory\n"); | 230 | warn("Port creation failed, no memory\n"); |
231 | return 0; | 231 | return NULL; |
232 | } | 232 | } |
233 | ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock); | 233 | ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock); |
234 | if (!ref) { | 234 | if (!ref) { |
235 | warn("Port creation failed, reference table exhausted\n"); | 235 | warn("Port creation failed, reference table exhausted\n"); |
236 | kfree(p_ptr); | 236 | kfree(p_ptr); |
237 | return 0; | 237 | return NULL; |
238 | } | 238 | } |
239 | 239 | ||
240 | tipc_port_lock(ref); | ||
241 | p_ptr->publ.usr_handle = usr_handle; | 240 | p_ptr->publ.usr_handle = usr_handle; |
242 | p_ptr->publ.max_pkt = MAX_PKT_DEFAULT; | 241 | p_ptr->publ.max_pkt = MAX_PKT_DEFAULT; |
243 | p_ptr->publ.ref = ref; | 242 | p_ptr->publ.ref = ref; |
244 | msg = &p_ptr->publ.phdr; | 243 | msg = &p_ptr->publ.phdr; |
245 | msg_init(msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG, TIPC_OK, LONG_H_SIZE, | 244 | msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0); |
246 | 0); | ||
247 | msg_set_orignode(msg, tipc_own_addr); | ||
248 | msg_set_prevnode(msg, tipc_own_addr); | ||
249 | msg_set_origport(msg, ref); | 245 | msg_set_origport(msg, ref); |
250 | msg_set_importance(msg,importance); | ||
251 | p_ptr->last_in_seqno = 41; | 246 | p_ptr->last_in_seqno = 41; |
252 | p_ptr->sent = 1; | 247 | p_ptr->sent = 1; |
253 | INIT_LIST_HEAD(&p_ptr->wait_list); | 248 | INIT_LIST_HEAD(&p_ptr->wait_list); |
@@ -262,8 +257,7 @@ u32 tipc_createport_raw(void *usr_handle, | |||
262 | INIT_LIST_HEAD(&p_ptr->port_list); | 257 | INIT_LIST_HEAD(&p_ptr->port_list); |
263 | list_add_tail(&p_ptr->port_list, &ports); | 258 | list_add_tail(&p_ptr->port_list, &ports); |
264 | spin_unlock_bh(&tipc_port_list_lock); | 259 | spin_unlock_bh(&tipc_port_list_lock); |
265 | tipc_port_unlock(p_ptr); | 260 | return &(p_ptr->publ); |
266 | return ref; | ||
267 | } | 261 | } |
268 | 262 | ||
269 | int tipc_deleteport(u32 ref) | 263 | int tipc_deleteport(u32 ref) |
@@ -297,7 +291,7 @@ int tipc_deleteport(u32 ref) | |||
297 | kfree(p_ptr); | 291 | kfree(p_ptr); |
298 | dbg("Deleted port %u\n", ref); | 292 | dbg("Deleted port %u\n", ref); |
299 | tipc_net_route_msg(buf); | 293 | tipc_net_route_msg(buf); |
300 | return TIPC_OK; | 294 | return 0; |
301 | } | 295 | } |
302 | 296 | ||
303 | /** | 297 | /** |
@@ -342,7 +336,7 @@ int tipc_portunreliable(u32 ref, unsigned int *isunreliable) | |||
342 | return -EINVAL; | 336 | return -EINVAL; |
343 | *isunreliable = port_unreliable(p_ptr); | 337 | *isunreliable = port_unreliable(p_ptr); |
344 | tipc_port_unlock(p_ptr); | 338 | tipc_port_unlock(p_ptr); |
345 | return TIPC_OK; | 339 | return 0; |
346 | } | 340 | } |
347 | 341 | ||
348 | int tipc_set_portunreliable(u32 ref, unsigned int isunreliable) | 342 | int tipc_set_portunreliable(u32 ref, unsigned int isunreliable) |
@@ -354,7 +348,7 @@ int tipc_set_portunreliable(u32 ref, unsigned int isunreliable) | |||
354 | return -EINVAL; | 348 | return -EINVAL; |
355 | msg_set_src_droppable(&p_ptr->publ.phdr, (isunreliable != 0)); | 349 | msg_set_src_droppable(&p_ptr->publ.phdr, (isunreliable != 0)); |
356 | tipc_port_unlock(p_ptr); | 350 | tipc_port_unlock(p_ptr); |
357 | return TIPC_OK; | 351 | return 0; |
358 | } | 352 | } |
359 | 353 | ||
360 | static int port_unreturnable(struct port *p_ptr) | 354 | static int port_unreturnable(struct port *p_ptr) |
@@ -371,7 +365,7 @@ int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable) | |||
371 | return -EINVAL; | 365 | return -EINVAL; |
372 | *isunrejectable = port_unreturnable(p_ptr); | 366 | *isunrejectable = port_unreturnable(p_ptr); |
373 | tipc_port_unlock(p_ptr); | 367 | tipc_port_unlock(p_ptr); |
374 | return TIPC_OK; | 368 | return 0; |
375 | } | 369 | } |
376 | 370 | ||
377 | int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable) | 371 | int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable) |
@@ -383,7 +377,7 @@ int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable) | |||
383 | return -EINVAL; | 377 | return -EINVAL; |
384 | msg_set_dest_droppable(&p_ptr->publ.phdr, (isunrejectable != 0)); | 378 | msg_set_dest_droppable(&p_ptr->publ.phdr, (isunrejectable != 0)); |
385 | tipc_port_unlock(p_ptr); | 379 | tipc_port_unlock(p_ptr); |
386 | return TIPC_OK; | 380 | return 0; |
387 | } | 381 | } |
388 | 382 | ||
389 | /* | 383 | /* |
@@ -402,10 +396,10 @@ static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode, | |||
402 | buf = buf_acquire(LONG_H_SIZE); | 396 | buf = buf_acquire(LONG_H_SIZE); |
403 | if (buf) { | 397 | if (buf) { |
404 | msg = buf_msg(buf); | 398 | msg = buf_msg(buf); |
405 | msg_init(msg, usr, type, err, LONG_H_SIZE, destnode); | 399 | msg_init(msg, usr, type, LONG_H_SIZE, destnode); |
400 | msg_set_errcode(msg, err); | ||
406 | msg_set_destport(msg, destport); | 401 | msg_set_destport(msg, destport); |
407 | msg_set_origport(msg, origport); | 402 | msg_set_origport(msg, origport); |
408 | msg_set_destnode(msg, destnode); | ||
409 | msg_set_orignode(msg, orignode); | 403 | msg_set_orignode(msg, orignode); |
410 | msg_set_transp_seqno(msg, seqno); | 404 | msg_set_transp_seqno(msg, seqno); |
411 | msg_set_msgcnt(msg, ack); | 405 | msg_set_msgcnt(msg, ack); |
@@ -446,17 +440,19 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err) | |||
446 | return data_sz; | 440 | return data_sz; |
447 | } | 441 | } |
448 | rmsg = buf_msg(rbuf); | 442 | rmsg = buf_msg(rbuf); |
449 | msg_init(rmsg, imp, msg_type(msg), err, hdr_sz, msg_orignode(msg)); | 443 | msg_init(rmsg, imp, msg_type(msg), hdr_sz, msg_orignode(msg)); |
444 | msg_set_errcode(rmsg, err); | ||
450 | msg_set_destport(rmsg, msg_origport(msg)); | 445 | msg_set_destport(rmsg, msg_origport(msg)); |
451 | msg_set_prevnode(rmsg, tipc_own_addr); | ||
452 | msg_set_origport(rmsg, msg_destport(msg)); | 446 | msg_set_origport(rmsg, msg_destport(msg)); |
453 | if (msg_short(msg)) | 447 | if (msg_short(msg)) { |
454 | msg_set_orignode(rmsg, tipc_own_addr); | 448 | msg_set_orignode(rmsg, tipc_own_addr); |
455 | else | 449 | /* leave name type & instance as zeroes */ |
450 | } else { | ||
456 | msg_set_orignode(rmsg, msg_destnode(msg)); | 451 | msg_set_orignode(rmsg, msg_destnode(msg)); |
452 | msg_set_nametype(rmsg, msg_nametype(msg)); | ||
453 | msg_set_nameinst(rmsg, msg_nameinst(msg)); | ||
454 | } | ||
457 | msg_set_size(rmsg, data_sz + hdr_sz); | 455 | msg_set_size(rmsg, data_sz + hdr_sz); |
458 | msg_set_nametype(rmsg, msg_nametype(msg)); | ||
459 | msg_set_nameinst(rmsg, msg_nameinst(msg)); | ||
460 | skb_copy_to_linear_data_offset(rbuf, hdr_sz, msg_data(msg), data_sz); | 456 | skb_copy_to_linear_data_offset(rbuf, hdr_sz, msg_data(msg), data_sz); |
461 | 457 | ||
462 | /* send self-abort message when rejecting on a connected port */ | 458 | /* send self-abort message when rejecting on a connected port */ |
@@ -778,6 +774,7 @@ void tipc_port_reinit(void) | |||
778 | msg = &p_ptr->publ.phdr; | 774 | msg = &p_ptr->publ.phdr; |
779 | if (msg_orignode(msg) == tipc_own_addr) | 775 | if (msg_orignode(msg) == tipc_own_addr) |
780 | break; | 776 | break; |
777 | msg_set_prevnode(msg, tipc_own_addr); | ||
781 | msg_set_orignode(msg, tipc_own_addr); | 778 | msg_set_orignode(msg, tipc_own_addr); |
782 | } | 779 | } |
783 | spin_unlock_bh(&tipc_port_list_lock); | 780 | spin_unlock_bh(&tipc_port_list_lock); |
@@ -838,16 +835,13 @@ static void port_dispatcher_sigh(void *dummy) | |||
838 | u32 peer_node = port_peernode(p_ptr); | 835 | u32 peer_node = port_peernode(p_ptr); |
839 | 836 | ||
840 | tipc_port_unlock(p_ptr); | 837 | tipc_port_unlock(p_ptr); |
838 | if (unlikely(!cb)) | ||
839 | goto reject; | ||
841 | if (unlikely(!connected)) { | 840 | if (unlikely(!connected)) { |
842 | if (unlikely(published)) | 841 | if (tipc_connect2port(dref, &orig)) |
843 | goto reject; | 842 | goto reject; |
844 | tipc_connect2port(dref,&orig); | 843 | } else if ((msg_origport(msg) != peer_port) || |
845 | } | 844 | (msg_orignode(msg) != peer_node)) |
846 | if (unlikely(msg_origport(msg) != peer_port)) | ||
847 | goto reject; | ||
848 | if (unlikely(msg_orignode(msg) != peer_node)) | ||
849 | goto reject; | ||
850 | if (unlikely(!cb)) | ||
851 | goto reject; | 845 | goto reject; |
852 | if (unlikely(++p_ptr->publ.conn_unacked >= | 846 | if (unlikely(++p_ptr->publ.conn_unacked >= |
853 | TIPC_FLOW_CONTROL_WIN)) | 847 | TIPC_FLOW_CONTROL_WIN)) |
@@ -862,9 +856,7 @@ static void port_dispatcher_sigh(void *dummy) | |||
862 | tipc_msg_event cb = up_ptr->msg_cb; | 856 | tipc_msg_event cb = up_ptr->msg_cb; |
863 | 857 | ||
864 | tipc_port_unlock(p_ptr); | 858 | tipc_port_unlock(p_ptr); |
865 | if (unlikely(connected)) | 859 | if (unlikely(!cb || connected)) |
866 | goto reject; | ||
867 | if (unlikely(!cb)) | ||
868 | goto reject; | 860 | goto reject; |
869 | skb_pull(buf, msg_hdr_sz(msg)); | 861 | skb_pull(buf, msg_hdr_sz(msg)); |
870 | cb(usr_handle, dref, &buf, msg_data(msg), | 862 | cb(usr_handle, dref, &buf, msg_data(msg), |
@@ -877,11 +869,7 @@ static void port_dispatcher_sigh(void *dummy) | |||
877 | tipc_named_msg_event cb = up_ptr->named_msg_cb; | 869 | tipc_named_msg_event cb = up_ptr->named_msg_cb; |
878 | 870 | ||
879 | tipc_port_unlock(p_ptr); | 871 | tipc_port_unlock(p_ptr); |
880 | if (unlikely(connected)) | 872 | if (unlikely(!cb || connected || !published)) |
881 | goto reject; | ||
882 | if (unlikely(!cb)) | ||
883 | goto reject; | ||
884 | if (unlikely(!published)) | ||
885 | goto reject; | 873 | goto reject; |
886 | dseq.type = msg_nametype(msg); | 874 | dseq.type = msg_nametype(msg); |
887 | dseq.lower = msg_nameinst(msg); | 875 | dseq.lower = msg_nameinst(msg); |
@@ -908,11 +896,10 @@ err: | |||
908 | u32 peer_node = port_peernode(p_ptr); | 896 | u32 peer_node = port_peernode(p_ptr); |
909 | 897 | ||
910 | tipc_port_unlock(p_ptr); | 898 | tipc_port_unlock(p_ptr); |
911 | if (!connected || !cb) | 899 | if (!cb || !connected) |
912 | break; | ||
913 | if (msg_origport(msg) != peer_port) | ||
914 | break; | 900 | break; |
915 | if (msg_orignode(msg) != peer_node) | 901 | if ((msg_origport(msg) != peer_port) || |
902 | (msg_orignode(msg) != peer_node)) | ||
916 | break; | 903 | break; |
917 | tipc_disconnect(dref); | 904 | tipc_disconnect(dref); |
918 | skb_pull(buf, msg_hdr_sz(msg)); | 905 | skb_pull(buf, msg_hdr_sz(msg)); |
@@ -924,7 +911,7 @@ err: | |||
924 | tipc_msg_err_event cb = up_ptr->err_cb; | 911 | tipc_msg_err_event cb = up_ptr->err_cb; |
925 | 912 | ||
926 | tipc_port_unlock(p_ptr); | 913 | tipc_port_unlock(p_ptr); |
927 | if (connected || !cb) | 914 | if (!cb || connected) |
928 | break; | 915 | break; |
929 | skb_pull(buf, msg_hdr_sz(msg)); | 916 | skb_pull(buf, msg_hdr_sz(msg)); |
930 | cb(usr_handle, dref, &buf, msg_data(msg), | 917 | cb(usr_handle, dref, &buf, msg_data(msg), |
@@ -937,7 +924,7 @@ err: | |||
937 | up_ptr->named_err_cb; | 924 | up_ptr->named_err_cb; |
938 | 925 | ||
939 | tipc_port_unlock(p_ptr); | 926 | tipc_port_unlock(p_ptr); |
940 | if (connected || !cb) | 927 | if (!cb || connected) |
941 | break; | 928 | break; |
942 | dseq.type = msg_nametype(msg); | 929 | dseq.type = msg_nametype(msg); |
943 | dseq.lower = msg_nameinst(msg); | 930 | dseq.lower = msg_nameinst(msg); |
@@ -976,7 +963,7 @@ static u32 port_dispatcher(struct tipc_port *dummy, struct sk_buff *buf) | |||
976 | tipc_k_signal((Handler)port_dispatcher_sigh, 0); | 963 | tipc_k_signal((Handler)port_dispatcher_sigh, 0); |
977 | } | 964 | } |
978 | spin_unlock_bh(&queue_lock); | 965 | spin_unlock_bh(&queue_lock); |
979 | return TIPC_OK; | 966 | return 0; |
980 | } | 967 | } |
981 | 968 | ||
982 | /* | 969 | /* |
@@ -1053,15 +1040,14 @@ int tipc_createport(u32 user_ref, | |||
1053 | { | 1040 | { |
1054 | struct user_port *up_ptr; | 1041 | struct user_port *up_ptr; |
1055 | struct port *p_ptr; | 1042 | struct port *p_ptr; |
1056 | u32 ref; | ||
1057 | 1043 | ||
1058 | up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC); | 1044 | up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC); |
1059 | if (!up_ptr) { | 1045 | if (!up_ptr) { |
1060 | warn("Port creation failed, no memory\n"); | 1046 | warn("Port creation failed, no memory\n"); |
1061 | return -ENOMEM; | 1047 | return -ENOMEM; |
1062 | } | 1048 | } |
1063 | ref = tipc_createport_raw(NULL, port_dispatcher, port_wakeup, importance); | 1049 | p_ptr = (struct port *)tipc_createport_raw(NULL, port_dispatcher, |
1064 | p_ptr = tipc_port_lock(ref); | 1050 | port_wakeup, importance); |
1065 | if (!p_ptr) { | 1051 | if (!p_ptr) { |
1066 | kfree(up_ptr); | 1052 | kfree(up_ptr); |
1067 | return -ENOMEM; | 1053 | return -ENOMEM; |
@@ -1081,16 +1067,15 @@ int tipc_createport(u32 user_ref, | |||
1081 | INIT_LIST_HEAD(&up_ptr->uport_list); | 1067 | INIT_LIST_HEAD(&up_ptr->uport_list); |
1082 | tipc_reg_add_port(up_ptr); | 1068 | tipc_reg_add_port(up_ptr); |
1083 | *portref = p_ptr->publ.ref; | 1069 | *portref = p_ptr->publ.ref; |
1084 | dbg(" tipc_createport: %x with ref %u\n", p_ptr, p_ptr->publ.ref); | ||
1085 | tipc_port_unlock(p_ptr); | 1070 | tipc_port_unlock(p_ptr); |
1086 | return TIPC_OK; | 1071 | return 0; |
1087 | } | 1072 | } |
1088 | 1073 | ||
1089 | int tipc_ownidentity(u32 ref, struct tipc_portid *id) | 1074 | int tipc_ownidentity(u32 ref, struct tipc_portid *id) |
1090 | { | 1075 | { |
1091 | id->ref = ref; | 1076 | id->ref = ref; |
1092 | id->node = tipc_own_addr; | 1077 | id->node = tipc_own_addr; |
1093 | return TIPC_OK; | 1078 | return 0; |
1094 | } | 1079 | } |
1095 | 1080 | ||
1096 | int tipc_portimportance(u32 ref, unsigned int *importance) | 1081 | int tipc_portimportance(u32 ref, unsigned int *importance) |
@@ -1102,7 +1087,7 @@ int tipc_portimportance(u32 ref, unsigned int *importance) | |||
1102 | return -EINVAL; | 1087 | return -EINVAL; |
1103 | *importance = (unsigned int)msg_importance(&p_ptr->publ.phdr); | 1088 | *importance = (unsigned int)msg_importance(&p_ptr->publ.phdr); |
1104 | tipc_port_unlock(p_ptr); | 1089 | tipc_port_unlock(p_ptr); |
1105 | return TIPC_OK; | 1090 | return 0; |
1106 | } | 1091 | } |
1107 | 1092 | ||
1108 | int tipc_set_portimportance(u32 ref, unsigned int imp) | 1093 | int tipc_set_portimportance(u32 ref, unsigned int imp) |
@@ -1117,7 +1102,7 @@ int tipc_set_portimportance(u32 ref, unsigned int imp) | |||
1117 | return -EINVAL; | 1102 | return -EINVAL; |
1118 | msg_set_importance(&p_ptr->publ.phdr, (u32)imp); | 1103 | msg_set_importance(&p_ptr->publ.phdr, (u32)imp); |
1119 | tipc_port_unlock(p_ptr); | 1104 | tipc_port_unlock(p_ptr); |
1120 | return TIPC_OK; | 1105 | return 0; |
1121 | } | 1106 | } |
1122 | 1107 | ||
1123 | 1108 | ||
@@ -1152,7 +1137,7 @@ int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) | |||
1152 | list_add(&publ->pport_list, &p_ptr->publications); | 1137 | list_add(&publ->pport_list, &p_ptr->publications); |
1153 | p_ptr->pub_count++; | 1138 | p_ptr->pub_count++; |
1154 | p_ptr->publ.published = 1; | 1139 | p_ptr->publ.published = 1; |
1155 | res = TIPC_OK; | 1140 | res = 0; |
1156 | } | 1141 | } |
1157 | exit: | 1142 | exit: |
1158 | tipc_port_unlock(p_ptr); | 1143 | tipc_port_unlock(p_ptr); |
@@ -1175,7 +1160,7 @@ int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) | |||
1175 | tipc_nametbl_withdraw(publ->type, publ->lower, | 1160 | tipc_nametbl_withdraw(publ->type, publ->lower, |
1176 | publ->ref, publ->key); | 1161 | publ->ref, publ->key); |
1177 | } | 1162 | } |
1178 | res = TIPC_OK; | 1163 | res = 0; |
1179 | } else { | 1164 | } else { |
1180 | list_for_each_entry_safe(publ, tpubl, | 1165 | list_for_each_entry_safe(publ, tpubl, |
1181 | &p_ptr->publications, pport_list) { | 1166 | &p_ptr->publications, pport_list) { |
@@ -1189,7 +1174,7 @@ int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) | |||
1189 | break; | 1174 | break; |
1190 | tipc_nametbl_withdraw(publ->type, publ->lower, | 1175 | tipc_nametbl_withdraw(publ->type, publ->lower, |
1191 | publ->ref, publ->key); | 1176 | publ->ref, publ->key); |
1192 | res = TIPC_OK; | 1177 | res = 0; |
1193 | break; | 1178 | break; |
1194 | } | 1179 | } |
1195 | } | 1180 | } |
@@ -1233,7 +1218,7 @@ int tipc_connect2port(u32 ref, struct tipc_portid const *peer) | |||
1233 | tipc_nodesub_subscribe(&p_ptr->subscription,peer->node, | 1218 | tipc_nodesub_subscribe(&p_ptr->subscription,peer->node, |
1234 | (void *)(unsigned long)ref, | 1219 | (void *)(unsigned long)ref, |
1235 | (net_ev_handler)port_handle_node_down); | 1220 | (net_ev_handler)port_handle_node_down); |
1236 | res = TIPC_OK; | 1221 | res = 0; |
1237 | exit: | 1222 | exit: |
1238 | tipc_port_unlock(p_ptr); | 1223 | tipc_port_unlock(p_ptr); |
1239 | p_ptr->publ.max_pkt = tipc_link_get_max_pkt(peer->node, ref); | 1224 | p_ptr->publ.max_pkt = tipc_link_get_max_pkt(peer->node, ref); |
@@ -1255,7 +1240,7 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr) | |||
1255 | /* let timer expire on it's own to avoid deadlock! */ | 1240 | /* let timer expire on it's own to avoid deadlock! */ |
1256 | tipc_nodesub_unsubscribe( | 1241 | tipc_nodesub_unsubscribe( |
1257 | &((struct port *)tp_ptr)->subscription); | 1242 | &((struct port *)tp_ptr)->subscription); |
1258 | res = TIPC_OK; | 1243 | res = 0; |
1259 | } else { | 1244 | } else { |
1260 | res = -ENOTCONN; | 1245 | res = -ENOTCONN; |
1261 | } | 1246 | } |
@@ -1320,7 +1305,7 @@ int tipc_isconnected(u32 ref, int *isconnected) | |||
1320 | return -EINVAL; | 1305 | return -EINVAL; |
1321 | *isconnected = p_ptr->publ.connected; | 1306 | *isconnected = p_ptr->publ.connected; |
1322 | tipc_port_unlock(p_ptr); | 1307 | tipc_port_unlock(p_ptr); |
1323 | return TIPC_OK; | 1308 | return 0; |
1324 | } | 1309 | } |
1325 | 1310 | ||
1326 | int tipc_peer(u32 ref, struct tipc_portid *peer) | 1311 | int tipc_peer(u32 ref, struct tipc_portid *peer) |
@@ -1334,7 +1319,7 @@ int tipc_peer(u32 ref, struct tipc_portid *peer) | |||
1334 | if (p_ptr->publ.connected) { | 1319 | if (p_ptr->publ.connected) { |
1335 | peer->ref = port_peerport(p_ptr); | 1320 | peer->ref = port_peerport(p_ptr); |
1336 | peer->node = port_peernode(p_ptr); | 1321 | peer->node = port_peernode(p_ptr); |
1337 | res = TIPC_OK; | 1322 | res = 0; |
1338 | } else | 1323 | } else |
1339 | res = -ENOTCONN; | 1324 | res = -ENOTCONN; |
1340 | tipc_port_unlock(p_ptr); | 1325 | tipc_port_unlock(p_ptr); |
diff --git a/net/tipc/ref.c b/net/tipc/ref.c index 89cbab24d08f..414fc34b8bea 100644 --- a/net/tipc/ref.c +++ b/net/tipc/ref.c | |||
@@ -123,7 +123,7 @@ int tipc_ref_table_init(u32 requested_size, u32 start) | |||
123 | tipc_ref_table.index_mask = actual_size - 1; | 123 | tipc_ref_table.index_mask = actual_size - 1; |
124 | tipc_ref_table.start_mask = start & ~tipc_ref_table.index_mask; | 124 | tipc_ref_table.start_mask = start & ~tipc_ref_table.index_mask; |
125 | 125 | ||
126 | return TIPC_OK; | 126 | return 0; |
127 | } | 127 | } |
128 | 128 | ||
129 | /** | 129 | /** |
@@ -142,9 +142,13 @@ void tipc_ref_table_stop(void) | |||
142 | /** | 142 | /** |
143 | * tipc_ref_acquire - create reference to an object | 143 | * tipc_ref_acquire - create reference to an object |
144 | * | 144 | * |
145 | * Return a unique reference value which can be translated back to the pointer | 145 | * Register an object pointer in reference table and lock the object. |
146 | * 'object' at a later time. Also, pass back a pointer to the lock protecting | 146 | * Returns a unique reference value that is used from then on to retrieve the |
147 | * the object, but without locking it. | 147 | * object pointer, or to determine that the object has been deregistered. |
148 | * | ||
149 | * Note: The object is returned in the locked state so that the caller can | ||
150 | * register a partially initialized object, without running the risk that | ||
151 | * the object will be accessed before initialization is complete. | ||
148 | */ | 152 | */ |
149 | 153 | ||
150 | u32 tipc_ref_acquire(void *object, spinlock_t **lock) | 154 | u32 tipc_ref_acquire(void *object, spinlock_t **lock) |
@@ -178,13 +182,13 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock) | |||
178 | ref = (next_plus_upper & ~index_mask) + index; | 182 | ref = (next_plus_upper & ~index_mask) + index; |
179 | entry->ref = ref; | 183 | entry->ref = ref; |
180 | entry->object = object; | 184 | entry->object = object; |
181 | spin_unlock_bh(&entry->lock); | ||
182 | *lock = &entry->lock; | 185 | *lock = &entry->lock; |
183 | } | 186 | } |
184 | else if (tipc_ref_table.init_point < tipc_ref_table.capacity) { | 187 | else if (tipc_ref_table.init_point < tipc_ref_table.capacity) { |
185 | index = tipc_ref_table.init_point++; | 188 | index = tipc_ref_table.init_point++; |
186 | entry = &(tipc_ref_table.entries[index]); | 189 | entry = &(tipc_ref_table.entries[index]); |
187 | spin_lock_init(&entry->lock); | 190 | spin_lock_init(&entry->lock); |
191 | spin_lock_bh(&entry->lock); | ||
188 | ref = tipc_ref_table.start_mask + index; | 192 | ref = tipc_ref_table.start_mask + index; |
189 | entry->ref = ref; | 193 | entry->ref = ref; |
190 | entry->object = object; | 194 | entry->object = object; |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 230f9ca2ad6b..1848693ebb82 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * net/tipc/socket.c: TIPC socket API | 2 | * net/tipc/socket.c: TIPC socket API |
3 | * | 3 | * |
4 | * Copyright (c) 2001-2007, Ericsson AB | 4 | * Copyright (c) 2001-2007, Ericsson AB |
5 | * Copyright (c) 2004-2007, Wind River Systems | 5 | * Copyright (c) 2004-2008, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -63,6 +63,7 @@ | |||
63 | struct tipc_sock { | 63 | struct tipc_sock { |
64 | struct sock sk; | 64 | struct sock sk; |
65 | struct tipc_port *p; | 65 | struct tipc_port *p; |
66 | struct tipc_portid peer_name; | ||
66 | }; | 67 | }; |
67 | 68 | ||
68 | #define tipc_sk(sk) ((struct tipc_sock *)(sk)) | 69 | #define tipc_sk(sk) ((struct tipc_sock *)(sk)) |
@@ -188,7 +189,7 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol) | |||
188 | const struct proto_ops *ops; | 189 | const struct proto_ops *ops; |
189 | socket_state state; | 190 | socket_state state; |
190 | struct sock *sk; | 191 | struct sock *sk; |
191 | u32 portref; | 192 | struct tipc_port *tp_ptr; |
192 | 193 | ||
193 | /* Validate arguments */ | 194 | /* Validate arguments */ |
194 | 195 | ||
@@ -224,9 +225,9 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol) | |||
224 | 225 | ||
225 | /* Allocate TIPC port for socket to use */ | 226 | /* Allocate TIPC port for socket to use */ |
226 | 227 | ||
227 | portref = tipc_createport_raw(sk, &dispatch, &wakeupdispatch, | 228 | tp_ptr = tipc_createport_raw(sk, &dispatch, &wakeupdispatch, |
228 | TIPC_LOW_IMPORTANCE); | 229 | TIPC_LOW_IMPORTANCE); |
229 | if (unlikely(portref == 0)) { | 230 | if (unlikely(!tp_ptr)) { |
230 | sk_free(sk); | 231 | sk_free(sk); |
231 | return -ENOMEM; | 232 | return -ENOMEM; |
232 | } | 233 | } |
@@ -239,12 +240,14 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol) | |||
239 | sock_init_data(sock, sk); | 240 | sock_init_data(sock, sk); |
240 | sk->sk_rcvtimeo = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT); | 241 | sk->sk_rcvtimeo = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT); |
241 | sk->sk_backlog_rcv = backlog_rcv; | 242 | sk->sk_backlog_rcv = backlog_rcv; |
242 | tipc_sk(sk)->p = tipc_get_port(portref); | 243 | tipc_sk(sk)->p = tp_ptr; |
244 | |||
245 | spin_unlock_bh(tp_ptr->lock); | ||
243 | 246 | ||
244 | if (sock->state == SS_READY) { | 247 | if (sock->state == SS_READY) { |
245 | tipc_set_portunreturnable(portref, 1); | 248 | tipc_set_portunreturnable(tp_ptr->ref, 1); |
246 | if (sock->type == SOCK_DGRAM) | 249 | if (sock->type == SOCK_DGRAM) |
247 | tipc_set_portunreliable(portref, 1); | 250 | tipc_set_portunreliable(tp_ptr->ref, 1); |
248 | } | 251 | } |
249 | 252 | ||
250 | atomic_inc(&tipc_user_count); | 253 | atomic_inc(&tipc_user_count); |
@@ -375,27 +378,29 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) | |||
375 | * @sock: socket structure | 378 | * @sock: socket structure |
376 | * @uaddr: area for returned socket address | 379 | * @uaddr: area for returned socket address |
377 | * @uaddr_len: area for returned length of socket address | 380 | * @uaddr_len: area for returned length of socket address |
378 | * @peer: 0 to obtain socket name, 1 to obtain peer socket name | 381 | * @peer: 0 = own ID, 1 = current peer ID, 2 = current/former peer ID |
379 | * | 382 | * |
380 | * Returns 0 on success, errno otherwise | 383 | * Returns 0 on success, errno otherwise |
381 | * | 384 | * |
382 | * NOTE: This routine doesn't need to take the socket lock since it doesn't | 385 | * NOTE: This routine doesn't need to take the socket lock since it only |
383 | * access any non-constant socket information. | 386 | * accesses socket information that is unchanging (or which changes in |
387 | * a completely predictable manner). | ||
384 | */ | 388 | */ |
385 | 389 | ||
386 | static int get_name(struct socket *sock, struct sockaddr *uaddr, | 390 | static int get_name(struct socket *sock, struct sockaddr *uaddr, |
387 | int *uaddr_len, int peer) | 391 | int *uaddr_len, int peer) |
388 | { | 392 | { |
389 | struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; | 393 | struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; |
390 | u32 portref = tipc_sk_port(sock->sk)->ref; | 394 | struct tipc_sock *tsock = tipc_sk(sock->sk); |
391 | u32 res; | ||
392 | 395 | ||
393 | if (peer) { | 396 | if (peer) { |
394 | res = tipc_peer(portref, &addr->addr.id); | 397 | if ((sock->state != SS_CONNECTED) && |
395 | if (res) | 398 | ((peer != 2) || (sock->state != SS_DISCONNECTING))) |
396 | return res; | 399 | return -ENOTCONN; |
400 | addr->addr.id.ref = tsock->peer_name.ref; | ||
401 | addr->addr.id.node = tsock->peer_name.node; | ||
397 | } else { | 402 | } else { |
398 | tipc_ownidentity(portref, &addr->addr.id); | 403 | tipc_ownidentity(tsock->p->ref, &addr->addr.id); |
399 | } | 404 | } |
400 | 405 | ||
401 | *uaddr_len = sizeof(*addr); | 406 | *uaddr_len = sizeof(*addr); |
@@ -764,18 +769,17 @@ exit: | |||
764 | 769 | ||
765 | static int auto_connect(struct socket *sock, struct tipc_msg *msg) | 770 | static int auto_connect(struct socket *sock, struct tipc_msg *msg) |
766 | { | 771 | { |
767 | struct tipc_port *tport = tipc_sk_port(sock->sk); | 772 | struct tipc_sock *tsock = tipc_sk(sock->sk); |
768 | struct tipc_portid peer; | ||
769 | 773 | ||
770 | if (msg_errcode(msg)) { | 774 | if (msg_errcode(msg)) { |
771 | sock->state = SS_DISCONNECTING; | 775 | sock->state = SS_DISCONNECTING; |
772 | return -ECONNREFUSED; | 776 | return -ECONNREFUSED; |
773 | } | 777 | } |
774 | 778 | ||
775 | peer.ref = msg_origport(msg); | 779 | tsock->peer_name.ref = msg_origport(msg); |
776 | peer.node = msg_orignode(msg); | 780 | tsock->peer_name.node = msg_orignode(msg); |
777 | tipc_connect2port(tport->ref, &peer); | 781 | tipc_connect2port(tsock->p->ref, &tsock->peer_name); |
778 | tipc_set_portimportance(tport->ref, msg_importance(msg)); | 782 | tipc_set_portimportance(tsock->p->ref, msg_importance(msg)); |
779 | sock->state = SS_CONNECTED; | 783 | sock->state = SS_CONNECTED; |
780 | return 0; | 784 | return 0; |
781 | } | 785 | } |
@@ -1131,7 +1135,7 @@ restart: | |||
1131 | /* Loop around if more data is required */ | 1135 | /* Loop around if more data is required */ |
1132 | 1136 | ||
1133 | if ((sz_copied < buf_len) /* didn't get all requested data */ | 1137 | if ((sz_copied < buf_len) /* didn't get all requested data */ |
1134 | && (!skb_queue_empty(&sock->sk->sk_receive_queue) || | 1138 | && (!skb_queue_empty(&sk->sk_receive_queue) || |
1135 | (flags & MSG_WAITALL)) | 1139 | (flags & MSG_WAITALL)) |
1136 | /* ... and more is ready or required */ | 1140 | /* ... and more is ready or required */ |
1137 | && (!(flags & MSG_PEEK)) /* ... and aren't just peeking at data */ | 1141 | && (!(flags & MSG_PEEK)) /* ... and aren't just peeking at data */ |
@@ -1527,9 +1531,9 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) | |||
1527 | res = tipc_create(sock_net(sock->sk), new_sock, 0); | 1531 | res = tipc_create(sock_net(sock->sk), new_sock, 0); |
1528 | if (!res) { | 1532 | if (!res) { |
1529 | struct sock *new_sk = new_sock->sk; | 1533 | struct sock *new_sk = new_sock->sk; |
1530 | struct tipc_port *new_tport = tipc_sk_port(new_sk); | 1534 | struct tipc_sock *new_tsock = tipc_sk(new_sk); |
1535 | struct tipc_port *new_tport = new_tsock->p; | ||
1531 | u32 new_ref = new_tport->ref; | 1536 | u32 new_ref = new_tport->ref; |
1532 | struct tipc_portid id; | ||
1533 | struct tipc_msg *msg = buf_msg(buf); | 1537 | struct tipc_msg *msg = buf_msg(buf); |
1534 | 1538 | ||
1535 | lock_sock(new_sk); | 1539 | lock_sock(new_sk); |
@@ -1543,9 +1547,9 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) | |||
1543 | 1547 | ||
1544 | /* Connect new socket to it's peer */ | 1548 | /* Connect new socket to it's peer */ |
1545 | 1549 | ||
1546 | id.ref = msg_origport(msg); | 1550 | new_tsock->peer_name.ref = msg_origport(msg); |
1547 | id.node = msg_orignode(msg); | 1551 | new_tsock->peer_name.node = msg_orignode(msg); |
1548 | tipc_connect2port(new_ref, &id); | 1552 | tipc_connect2port(new_ref, &new_tsock->peer_name); |
1549 | new_sock->state = SS_CONNECTED; | 1553 | new_sock->state = SS_CONNECTED; |
1550 | 1554 | ||
1551 | tipc_set_portimportance(new_ref, msg_importance(msg)); | 1555 | tipc_set_portimportance(new_ref, msg_importance(msg)); |
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index 8c01ccd3626c..0326d3060bc7 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * net/tipc/subscr.c: TIPC subscription service | 2 | * net/tipc/subscr.c: TIPC network topology service |
3 | * | 3 | * |
4 | * Copyright (c) 2000-2006, Ericsson AB | 4 | * Copyright (c) 2000-2006, Ericsson AB |
5 | * Copyright (c) 2005, Wind River Systems | 5 | * Copyright (c) 2005-2007, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -36,27 +36,24 @@ | |||
36 | 36 | ||
37 | #include "core.h" | 37 | #include "core.h" |
38 | #include "dbg.h" | 38 | #include "dbg.h" |
39 | #include "subscr.h" | ||
40 | #include "name_table.h" | 39 | #include "name_table.h" |
40 | #include "port.h" | ||
41 | #include "ref.h" | 41 | #include "ref.h" |
42 | #include "subscr.h" | ||
42 | 43 | ||
43 | /** | 44 | /** |
44 | * struct subscriber - TIPC network topology subscriber | 45 | * struct subscriber - TIPC network topology subscriber |
45 | * @ref: object reference to subscriber object itself | 46 | * @port_ref: object reference to server port connecting to subscriber |
46 | * @lock: pointer to spinlock controlling access to subscriber object | 47 | * @lock: pointer to spinlock controlling access to subscriber's server port |
47 | * @subscriber_list: adjacent subscribers in top. server's list of subscribers | 48 | * @subscriber_list: adjacent subscribers in top. server's list of subscribers |
48 | * @subscription_list: list of subscription objects for this subscriber | 49 | * @subscription_list: list of subscription objects for this subscriber |
49 | * @port_ref: object reference to port used to communicate with subscriber | ||
50 | * @swap: indicates if subscriber uses opposite endianness in its messages | ||
51 | */ | 50 | */ |
52 | 51 | ||
53 | struct subscriber { | 52 | struct subscriber { |
54 | u32 ref; | 53 | u32 port_ref; |
55 | spinlock_t *lock; | 54 | spinlock_t *lock; |
56 | struct list_head subscriber_list; | 55 | struct list_head subscriber_list; |
57 | struct list_head subscription_list; | 56 | struct list_head subscription_list; |
58 | u32 port_ref; | ||
59 | int swap; | ||
60 | }; | 57 | }; |
61 | 58 | ||
62 | /** | 59 | /** |
@@ -88,13 +85,14 @@ static struct top_srv topsrv = { 0 }; | |||
88 | 85 | ||
89 | static u32 htohl(u32 in, int swap) | 86 | static u32 htohl(u32 in, int swap) |
90 | { | 87 | { |
91 | char *c = (char *)∈ | 88 | return swap ? (u32)___constant_swab32(in) : in; |
92 | |||
93 | return swap ? ((c[3] << 3) + (c[2] << 2) + (c[1] << 1) + c[0]) : in; | ||
94 | } | 89 | } |
95 | 90 | ||
96 | /** | 91 | /** |
97 | * subscr_send_event - send a message containing a tipc_event to the subscriber | 92 | * subscr_send_event - send a message containing a tipc_event to the subscriber |
93 | * | ||
94 | * Note: Must not hold subscriber's server port lock, since tipc_send() will | ||
95 | * try to take the lock if the message is rejected and returned! | ||
98 | */ | 96 | */ |
99 | 97 | ||
100 | static void subscr_send_event(struct subscription *sub, | 98 | static void subscr_send_event(struct subscription *sub, |
@@ -109,12 +107,12 @@ static void subscr_send_event(struct subscription *sub, | |||
109 | msg_sect.iov_base = (void *)&sub->evt; | 107 | msg_sect.iov_base = (void *)&sub->evt; |
110 | msg_sect.iov_len = sizeof(struct tipc_event); | 108 | msg_sect.iov_len = sizeof(struct tipc_event); |
111 | 109 | ||
112 | sub->evt.event = htohl(event, sub->owner->swap); | 110 | sub->evt.event = htohl(event, sub->swap); |
113 | sub->evt.found_lower = htohl(found_lower, sub->owner->swap); | 111 | sub->evt.found_lower = htohl(found_lower, sub->swap); |
114 | sub->evt.found_upper = htohl(found_upper, sub->owner->swap); | 112 | sub->evt.found_upper = htohl(found_upper, sub->swap); |
115 | sub->evt.port.ref = htohl(port_ref, sub->owner->swap); | 113 | sub->evt.port.ref = htohl(port_ref, sub->swap); |
116 | sub->evt.port.node = htohl(node, sub->owner->swap); | 114 | sub->evt.port.node = htohl(node, sub->swap); |
117 | tipc_send(sub->owner->port_ref, 1, &msg_sect); | 115 | tipc_send(sub->server_ref, 1, &msg_sect); |
118 | } | 116 | } |
119 | 117 | ||
120 | /** | 118 | /** |
@@ -151,13 +149,12 @@ void tipc_subscr_report_overlap(struct subscription *sub, | |||
151 | u32 node, | 149 | u32 node, |
152 | int must) | 150 | int must) |
153 | { | 151 | { |
154 | dbg("Rep overlap %u:%u,%u<->%u,%u\n", sub->seq.type, sub->seq.lower, | ||
155 | sub->seq.upper, found_lower, found_upper); | ||
156 | if (!tipc_subscr_overlap(sub, found_lower, found_upper)) | 152 | if (!tipc_subscr_overlap(sub, found_lower, found_upper)) |
157 | return; | 153 | return; |
158 | if (!must && !(sub->filter & TIPC_SUB_PORTS)) | 154 | if (!must && !(sub->filter & TIPC_SUB_PORTS)) |
159 | return; | 155 | return; |
160 | subscr_send_event(sub, found_lower, found_upper, event, port_ref, node); | 156 | |
157 | sub->event_cb(sub, found_lower, found_upper, event, port_ref, node); | ||
161 | } | 158 | } |
162 | 159 | ||
163 | /** | 160 | /** |
@@ -166,20 +163,18 @@ void tipc_subscr_report_overlap(struct subscription *sub, | |||
166 | 163 | ||
167 | static void subscr_timeout(struct subscription *sub) | 164 | static void subscr_timeout(struct subscription *sub) |
168 | { | 165 | { |
169 | struct subscriber *subscriber; | 166 | struct port *server_port; |
170 | u32 subscriber_ref; | ||
171 | 167 | ||
172 | /* Validate subscriber reference (in case subscriber is terminating) */ | 168 | /* Validate server port reference (in case subscriber is terminating) */ |
173 | 169 | ||
174 | subscriber_ref = sub->owner->ref; | 170 | server_port = tipc_port_lock(sub->server_ref); |
175 | subscriber = (struct subscriber *)tipc_ref_lock(subscriber_ref); | 171 | if (server_port == NULL) |
176 | if (subscriber == NULL) | ||
177 | return; | 172 | return; |
178 | 173 | ||
179 | /* Validate timeout (in case subscription is being cancelled) */ | 174 | /* Validate timeout (in case subscription is being cancelled) */ |
180 | 175 | ||
181 | if (sub->timeout == TIPC_WAIT_FOREVER) { | 176 | if (sub->timeout == TIPC_WAIT_FOREVER) { |
182 | tipc_ref_unlock(subscriber_ref); | 177 | tipc_port_unlock(server_port); |
183 | return; | 178 | return; |
184 | } | 179 | } |
185 | 180 | ||
@@ -187,19 +182,21 @@ static void subscr_timeout(struct subscription *sub) | |||
187 | 182 | ||
188 | tipc_nametbl_unsubscribe(sub); | 183 | tipc_nametbl_unsubscribe(sub); |
189 | 184 | ||
190 | /* Notify subscriber of timeout, then unlink subscription */ | 185 | /* Unlink subscription from subscriber */ |
191 | 186 | ||
192 | subscr_send_event(sub, | ||
193 | sub->evt.s.seq.lower, | ||
194 | sub->evt.s.seq.upper, | ||
195 | TIPC_SUBSCR_TIMEOUT, | ||
196 | 0, | ||
197 | 0); | ||
198 | list_del(&sub->subscription_list); | 187 | list_del(&sub->subscription_list); |
199 | 188 | ||
189 | /* Release subscriber's server port */ | ||
190 | |||
191 | tipc_port_unlock(server_port); | ||
192 | |||
193 | /* Notify subscriber of timeout */ | ||
194 | |||
195 | subscr_send_event(sub, sub->evt.s.seq.lower, sub->evt.s.seq.upper, | ||
196 | TIPC_SUBSCR_TIMEOUT, 0, 0); | ||
197 | |||
200 | /* Now destroy subscription */ | 198 | /* Now destroy subscription */ |
201 | 199 | ||
202 | tipc_ref_unlock(subscriber_ref); | ||
203 | k_term_timer(&sub->timer); | 200 | k_term_timer(&sub->timer); |
204 | kfree(sub); | 201 | kfree(sub); |
205 | atomic_dec(&topsrv.subscription_count); | 202 | atomic_dec(&topsrv.subscription_count); |
@@ -208,7 +205,7 @@ static void subscr_timeout(struct subscription *sub) | |||
208 | /** | 205 | /** |
209 | * subscr_del - delete a subscription within a subscription list | 206 | * subscr_del - delete a subscription within a subscription list |
210 | * | 207 | * |
211 | * Called with subscriber locked. | 208 | * Called with subscriber port locked. |
212 | */ | 209 | */ |
213 | 210 | ||
214 | static void subscr_del(struct subscription *sub) | 211 | static void subscr_del(struct subscription *sub) |
@@ -222,7 +219,7 @@ static void subscr_del(struct subscription *sub) | |||
222 | /** | 219 | /** |
223 | * subscr_terminate - terminate communication with a subscriber | 220 | * subscr_terminate - terminate communication with a subscriber |
224 | * | 221 | * |
225 | * Called with subscriber locked. Routine must temporarily release this lock | 222 | * Called with subscriber port locked. Routine must temporarily release lock |
226 | * to enable subscription timeout routine(s) to finish without deadlocking; | 223 | * to enable subscription timeout routine(s) to finish without deadlocking; |
227 | * the lock is then reclaimed to allow caller to release it upon return. | 224 | * the lock is then reclaimed to allow caller to release it upon return. |
228 | * (This should work even in the unlikely event some other thread creates | 225 | * (This should work even in the unlikely event some other thread creates |
@@ -232,14 +229,21 @@ static void subscr_del(struct subscription *sub) | |||
232 | 229 | ||
233 | static void subscr_terminate(struct subscriber *subscriber) | 230 | static void subscr_terminate(struct subscriber *subscriber) |
234 | { | 231 | { |
232 | u32 port_ref; | ||
235 | struct subscription *sub; | 233 | struct subscription *sub; |
236 | struct subscription *sub_temp; | 234 | struct subscription *sub_temp; |
237 | 235 | ||
238 | /* Invalidate subscriber reference */ | 236 | /* Invalidate subscriber reference */ |
239 | 237 | ||
240 | tipc_ref_discard(subscriber->ref); | 238 | port_ref = subscriber->port_ref; |
239 | subscriber->port_ref = 0; | ||
241 | spin_unlock_bh(subscriber->lock); | 240 | spin_unlock_bh(subscriber->lock); |
242 | 241 | ||
242 | /* Sever connection to subscriber */ | ||
243 | |||
244 | tipc_shutdown(port_ref); | ||
245 | tipc_deleteport(port_ref); | ||
246 | |||
243 | /* Destroy any existing subscriptions for subscriber */ | 247 | /* Destroy any existing subscriptions for subscriber */ |
244 | 248 | ||
245 | list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, | 249 | list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, |
@@ -253,27 +257,25 @@ static void subscr_terminate(struct subscriber *subscriber) | |||
253 | subscr_del(sub); | 257 | subscr_del(sub); |
254 | } | 258 | } |
255 | 259 | ||
256 | /* Sever connection to subscriber */ | ||
257 | |||
258 | tipc_shutdown(subscriber->port_ref); | ||
259 | tipc_deleteport(subscriber->port_ref); | ||
260 | |||
261 | /* Remove subscriber from topology server's subscriber list */ | 260 | /* Remove subscriber from topology server's subscriber list */ |
262 | 261 | ||
263 | spin_lock_bh(&topsrv.lock); | 262 | spin_lock_bh(&topsrv.lock); |
264 | list_del(&subscriber->subscriber_list); | 263 | list_del(&subscriber->subscriber_list); |
265 | spin_unlock_bh(&topsrv.lock); | 264 | spin_unlock_bh(&topsrv.lock); |
266 | 265 | ||
267 | /* Now destroy subscriber */ | 266 | /* Reclaim subscriber lock */ |
268 | 267 | ||
269 | spin_lock_bh(subscriber->lock); | 268 | spin_lock_bh(subscriber->lock); |
269 | |||
270 | /* Now destroy subscriber */ | ||
271 | |||
270 | kfree(subscriber); | 272 | kfree(subscriber); |
271 | } | 273 | } |
272 | 274 | ||
273 | /** | 275 | /** |
274 | * subscr_cancel - handle subscription cancellation request | 276 | * subscr_cancel - handle subscription cancellation request |
275 | * | 277 | * |
276 | * Called with subscriber locked. Routine must temporarily release this lock | 278 | * Called with subscriber port locked. Routine must temporarily release lock |
277 | * to enable the subscription timeout routine to finish without deadlocking; | 279 | * to enable the subscription timeout routine to finish without deadlocking; |
278 | * the lock is then reclaimed to allow caller to release it upon return. | 280 | * the lock is then reclaimed to allow caller to release it upon return. |
279 | * | 281 | * |
@@ -316,27 +318,25 @@ static void subscr_cancel(struct tipc_subscr *s, | |||
316 | /** | 318 | /** |
317 | * subscr_subscribe - create subscription for subscriber | 319 | * subscr_subscribe - create subscription for subscriber |
318 | * | 320 | * |
319 | * Called with subscriber locked | 321 | * Called with subscriber port locked. |
320 | */ | 322 | */ |
321 | 323 | ||
322 | static void subscr_subscribe(struct tipc_subscr *s, | 324 | static struct subscription *subscr_subscribe(struct tipc_subscr *s, |
323 | struct subscriber *subscriber) | 325 | struct subscriber *subscriber) |
324 | { | 326 | { |
325 | struct subscription *sub; | 327 | struct subscription *sub; |
328 | int swap; | ||
326 | 329 | ||
327 | /* Determine/update subscriber's endianness */ | 330 | /* Determine subscriber's endianness */ |
328 | 331 | ||
329 | if (s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE)) | 332 | swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE)); |
330 | subscriber->swap = 0; | ||
331 | else | ||
332 | subscriber->swap = 1; | ||
333 | 333 | ||
334 | /* Detect & process a subscription cancellation request */ | 334 | /* Detect & process a subscription cancellation request */ |
335 | 335 | ||
336 | if (s->filter & htohl(TIPC_SUB_CANCEL, subscriber->swap)) { | 336 | if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) { |
337 | s->filter &= ~htohl(TIPC_SUB_CANCEL, subscriber->swap); | 337 | s->filter &= ~htohl(TIPC_SUB_CANCEL, swap); |
338 | subscr_cancel(s, subscriber); | 338 | subscr_cancel(s, subscriber); |
339 | return; | 339 | return NULL; |
340 | } | 340 | } |
341 | 341 | ||
342 | /* Refuse subscription if global limit exceeded */ | 342 | /* Refuse subscription if global limit exceeded */ |
@@ -345,63 +345,66 @@ static void subscr_subscribe(struct tipc_subscr *s, | |||
345 | warn("Subscription rejected, subscription limit reached (%u)\n", | 345 | warn("Subscription rejected, subscription limit reached (%u)\n", |
346 | tipc_max_subscriptions); | 346 | tipc_max_subscriptions); |
347 | subscr_terminate(subscriber); | 347 | subscr_terminate(subscriber); |
348 | return; | 348 | return NULL; |
349 | } | 349 | } |
350 | 350 | ||
351 | /* Allocate subscription object */ | 351 | /* Allocate subscription object */ |
352 | 352 | ||
353 | sub = kzalloc(sizeof(*sub), GFP_ATOMIC); | 353 | sub = kmalloc(sizeof(*sub), GFP_ATOMIC); |
354 | if (!sub) { | 354 | if (!sub) { |
355 | warn("Subscription rejected, no memory\n"); | 355 | warn("Subscription rejected, no memory\n"); |
356 | subscr_terminate(subscriber); | 356 | subscr_terminate(subscriber); |
357 | return; | 357 | return NULL; |
358 | } | 358 | } |
359 | 359 | ||
360 | /* Initialize subscription object */ | 360 | /* Initialize subscription object */ |
361 | 361 | ||
362 | sub->seq.type = htohl(s->seq.type, subscriber->swap); | 362 | sub->seq.type = htohl(s->seq.type, swap); |
363 | sub->seq.lower = htohl(s->seq.lower, subscriber->swap); | 363 | sub->seq.lower = htohl(s->seq.lower, swap); |
364 | sub->seq.upper = htohl(s->seq.upper, subscriber->swap); | 364 | sub->seq.upper = htohl(s->seq.upper, swap); |
365 | sub->timeout = htohl(s->timeout, subscriber->swap); | 365 | sub->timeout = htohl(s->timeout, swap); |
366 | sub->filter = htohl(s->filter, subscriber->swap); | 366 | sub->filter = htohl(s->filter, swap); |
367 | if ((!(sub->filter & TIPC_SUB_PORTS) | 367 | if ((!(sub->filter & TIPC_SUB_PORTS) |
368 | == !(sub->filter & TIPC_SUB_SERVICE)) | 368 | == !(sub->filter & TIPC_SUB_SERVICE)) |
369 | || (sub->seq.lower > sub->seq.upper)) { | 369 | || (sub->seq.lower > sub->seq.upper)) { |
370 | warn("Subscription rejected, illegal request\n"); | 370 | warn("Subscription rejected, illegal request\n"); |
371 | kfree(sub); | 371 | kfree(sub); |
372 | subscr_terminate(subscriber); | 372 | subscr_terminate(subscriber); |
373 | return; | 373 | return NULL; |
374 | } | 374 | } |
375 | memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr)); | 375 | sub->event_cb = subscr_send_event; |
376 | INIT_LIST_HEAD(&sub->subscription_list); | ||
377 | INIT_LIST_HEAD(&sub->nameseq_list); | 376 | INIT_LIST_HEAD(&sub->nameseq_list); |
378 | list_add(&sub->subscription_list, &subscriber->subscription_list); | 377 | list_add(&sub->subscription_list, &subscriber->subscription_list); |
378 | sub->server_ref = subscriber->port_ref; | ||
379 | sub->swap = swap; | ||
380 | memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr)); | ||
379 | atomic_inc(&topsrv.subscription_count); | 381 | atomic_inc(&topsrv.subscription_count); |
380 | if (sub->timeout != TIPC_WAIT_FOREVER) { | 382 | if (sub->timeout != TIPC_WAIT_FOREVER) { |
381 | k_init_timer(&sub->timer, | 383 | k_init_timer(&sub->timer, |
382 | (Handler)subscr_timeout, (unsigned long)sub); | 384 | (Handler)subscr_timeout, (unsigned long)sub); |
383 | k_start_timer(&sub->timer, sub->timeout); | 385 | k_start_timer(&sub->timer, sub->timeout); |
384 | } | 386 | } |
385 | sub->owner = subscriber; | 387 | |
386 | tipc_nametbl_subscribe(sub); | 388 | return sub; |
387 | } | 389 | } |
388 | 390 | ||
389 | /** | 391 | /** |
390 | * subscr_conn_shutdown_event - handle termination request from subscriber | 392 | * subscr_conn_shutdown_event - handle termination request from subscriber |
393 | * | ||
394 | * Called with subscriber's server port unlocked. | ||
391 | */ | 395 | */ |
392 | 396 | ||
393 | static void subscr_conn_shutdown_event(void *usr_handle, | 397 | static void subscr_conn_shutdown_event(void *usr_handle, |
394 | u32 portref, | 398 | u32 port_ref, |
395 | struct sk_buff **buf, | 399 | struct sk_buff **buf, |
396 | unsigned char const *data, | 400 | unsigned char const *data, |
397 | unsigned int size, | 401 | unsigned int size, |
398 | int reason) | 402 | int reason) |
399 | { | 403 | { |
400 | struct subscriber *subscriber; | 404 | struct subscriber *subscriber = usr_handle; |
401 | spinlock_t *subscriber_lock; | 405 | spinlock_t *subscriber_lock; |
402 | 406 | ||
403 | subscriber = tipc_ref_lock((u32)(unsigned long)usr_handle); | 407 | if (tipc_port_lock(port_ref) == NULL) |
404 | if (subscriber == NULL) | ||
405 | return; | 408 | return; |
406 | 409 | ||
407 | subscriber_lock = subscriber->lock; | 410 | subscriber_lock = subscriber->lock; |
@@ -411,6 +414,8 @@ static void subscr_conn_shutdown_event(void *usr_handle, | |||
411 | 414 | ||
412 | /** | 415 | /** |
413 | * subscr_conn_msg_event - handle new subscription request from subscriber | 416 | * subscr_conn_msg_event - handle new subscription request from subscriber |
417 | * | ||
418 | * Called with subscriber's server port unlocked. | ||
414 | */ | 419 | */ |
415 | 420 | ||
416 | static void subscr_conn_msg_event(void *usr_handle, | 421 | static void subscr_conn_msg_event(void *usr_handle, |
@@ -419,20 +424,46 @@ static void subscr_conn_msg_event(void *usr_handle, | |||
419 | const unchar *data, | 424 | const unchar *data, |
420 | u32 size) | 425 | u32 size) |
421 | { | 426 | { |
422 | struct subscriber *subscriber; | 427 | struct subscriber *subscriber = usr_handle; |
423 | spinlock_t *subscriber_lock; | 428 | spinlock_t *subscriber_lock; |
429 | struct subscription *sub; | ||
430 | |||
431 | /* | ||
432 | * Lock subscriber's server port (& make a local copy of lock pointer, | ||
433 | * in case subscriber is deleted while processing subscription request) | ||
434 | */ | ||
424 | 435 | ||
425 | subscriber = tipc_ref_lock((u32)(unsigned long)usr_handle); | 436 | if (tipc_port_lock(port_ref) == NULL) |
426 | if (subscriber == NULL) | ||
427 | return; | 437 | return; |
428 | 438 | ||
429 | subscriber_lock = subscriber->lock; | 439 | subscriber_lock = subscriber->lock; |
430 | if (size != sizeof(struct tipc_subscr)) | ||
431 | subscr_terminate(subscriber); | ||
432 | else | ||
433 | subscr_subscribe((struct tipc_subscr *)data, subscriber); | ||
434 | 440 | ||
435 | spin_unlock_bh(subscriber_lock); | 441 | if (size != sizeof(struct tipc_subscr)) { |
442 | subscr_terminate(subscriber); | ||
443 | spin_unlock_bh(subscriber_lock); | ||
444 | } else { | ||
445 | sub = subscr_subscribe((struct tipc_subscr *)data, subscriber); | ||
446 | spin_unlock_bh(subscriber_lock); | ||
447 | if (sub != NULL) { | ||
448 | |||
449 | /* | ||
450 | * We must release the server port lock before adding a | ||
451 | * subscription to the name table since TIPC needs to be | ||
452 | * able to (re)acquire the port lock if an event message | ||
453 | * issued by the subscription process is rejected and | ||
454 | * returned. The subscription cannot be deleted while | ||
455 | * it is being added to the name table because: | ||
456 | * a) the single-threading of the native API port code | ||
457 | * ensures the subscription cannot be cancelled and | ||
458 | * the subscriber connection cannot be broken, and | ||
459 | * b) the name table lock ensures the subscription | ||
460 | * timeout code cannot delete the subscription, | ||
461 | * so the subscription object is still protected. | ||
462 | */ | ||
463 | |||
464 | tipc_nametbl_subscribe(sub); | ||
465 | } | ||
466 | } | ||
436 | } | 467 | } |
437 | 468 | ||
438 | /** | 469 | /** |
@@ -448,16 +479,10 @@ static void subscr_named_msg_event(void *usr_handle, | |||
448 | struct tipc_portid const *orig, | 479 | struct tipc_portid const *orig, |
449 | struct tipc_name_seq const *dest) | 480 | struct tipc_name_seq const *dest) |
450 | { | 481 | { |
451 | struct subscriber *subscriber; | 482 | static struct iovec msg_sect = {NULL, 0}; |
452 | struct iovec msg_sect = {NULL, 0}; | ||
453 | spinlock_t *subscriber_lock; | ||
454 | 483 | ||
455 | dbg("subscr_named_msg_event: orig = %x own = %x,\n", | 484 | struct subscriber *subscriber; |
456 | orig->node, tipc_own_addr); | 485 | u32 server_port_ref; |
457 | if (size && (size != sizeof(struct tipc_subscr))) { | ||
458 | warn("Subscriber rejected, invalid subscription size\n"); | ||
459 | return; | ||
460 | } | ||
461 | 486 | ||
462 | /* Create subscriber object */ | 487 | /* Create subscriber object */ |
463 | 488 | ||
@@ -468,17 +493,11 @@ static void subscr_named_msg_event(void *usr_handle, | |||
468 | } | 493 | } |
469 | INIT_LIST_HEAD(&subscriber->subscription_list); | 494 | INIT_LIST_HEAD(&subscriber->subscription_list); |
470 | INIT_LIST_HEAD(&subscriber->subscriber_list); | 495 | INIT_LIST_HEAD(&subscriber->subscriber_list); |
471 | subscriber->ref = tipc_ref_acquire(subscriber, &subscriber->lock); | ||
472 | if (subscriber->ref == 0) { | ||
473 | warn("Subscriber rejected, reference table exhausted\n"); | ||
474 | kfree(subscriber); | ||
475 | return; | ||
476 | } | ||
477 | 496 | ||
478 | /* Establish a connection to subscriber */ | 497 | /* Create server port & establish connection to subscriber */ |
479 | 498 | ||
480 | tipc_createport(topsrv.user_ref, | 499 | tipc_createport(topsrv.user_ref, |
481 | (void *)(unsigned long)subscriber->ref, | 500 | subscriber, |
482 | importance, | 501 | importance, |
483 | NULL, | 502 | NULL, |
484 | NULL, | 503 | NULL, |
@@ -490,32 +509,36 @@ static void subscr_named_msg_event(void *usr_handle, | |||
490 | &subscriber->port_ref); | 509 | &subscriber->port_ref); |
491 | if (subscriber->port_ref == 0) { | 510 | if (subscriber->port_ref == 0) { |
492 | warn("Subscriber rejected, unable to create port\n"); | 511 | warn("Subscriber rejected, unable to create port\n"); |
493 | tipc_ref_discard(subscriber->ref); | ||
494 | kfree(subscriber); | 512 | kfree(subscriber); |
495 | return; | 513 | return; |
496 | } | 514 | } |
497 | tipc_connect2port(subscriber->port_ref, orig); | 515 | tipc_connect2port(subscriber->port_ref, orig); |
498 | 516 | ||
517 | /* Lock server port (& save lock address for future use) */ | ||
518 | |||
519 | subscriber->lock = tipc_port_lock(subscriber->port_ref)->publ.lock; | ||
499 | 520 | ||
500 | /* Add subscriber to topology server's subscriber list */ | 521 | /* Add subscriber to topology server's subscriber list */ |
501 | 522 | ||
502 | tipc_ref_lock(subscriber->ref); | ||
503 | spin_lock_bh(&topsrv.lock); | 523 | spin_lock_bh(&topsrv.lock); |
504 | list_add(&subscriber->subscriber_list, &topsrv.subscriber_list); | 524 | list_add(&subscriber->subscriber_list, &topsrv.subscriber_list); |
505 | spin_unlock_bh(&topsrv.lock); | 525 | spin_unlock_bh(&topsrv.lock); |
506 | 526 | ||
507 | /* | 527 | /* Unlock server port */ |
508 | * Subscribe now if message contains a subscription, | ||
509 | * otherwise send an empty response to complete connection handshaking | ||
510 | */ | ||
511 | 528 | ||
512 | subscriber_lock = subscriber->lock; | 529 | server_port_ref = subscriber->port_ref; |
513 | if (size) | 530 | spin_unlock_bh(subscriber->lock); |
514 | subscr_subscribe((struct tipc_subscr *)data, subscriber); | ||
515 | else | ||
516 | tipc_send(subscriber->port_ref, 1, &msg_sect); | ||
517 | 531 | ||
518 | spin_unlock_bh(subscriber_lock); | 532 | /* Send an ACK- to complete connection handshaking */ |
533 | |||
534 | tipc_send(server_port_ref, 1, &msg_sect); | ||
535 | |||
536 | /* Handle optional subscription request */ | ||
537 | |||
538 | if (size != 0) { | ||
539 | subscr_conn_msg_event(subscriber, server_port_ref, | ||
540 | buf, data, size); | ||
541 | } | ||
519 | } | 542 | } |
520 | 543 | ||
521 | int tipc_subscr_start(void) | 544 | int tipc_subscr_start(void) |
@@ -574,8 +597,8 @@ void tipc_subscr_stop(void) | |||
574 | list_for_each_entry_safe(subscriber, subscriber_temp, | 597 | list_for_each_entry_safe(subscriber, subscriber_temp, |
575 | &topsrv.subscriber_list, | 598 | &topsrv.subscriber_list, |
576 | subscriber_list) { | 599 | subscriber_list) { |
577 | tipc_ref_lock(subscriber->ref); | ||
578 | subscriber_lock = subscriber->lock; | 600 | subscriber_lock = subscriber->lock; |
601 | spin_lock_bh(subscriber_lock); | ||
579 | subscr_terminate(subscriber); | 602 | subscr_terminate(subscriber); |
580 | spin_unlock_bh(subscriber_lock); | 603 | spin_unlock_bh(subscriber_lock); |
581 | } | 604 | } |
diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h index 93a8e674fac1..45d89bf4d202 100644 --- a/net/tipc/subscr.h +++ b/net/tipc/subscr.h | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * net/tipc/subscr.h: Include file for TIPC subscription service | 2 | * net/tipc/subscr.h: Include file for TIPC network topology service |
3 | * | 3 | * |
4 | * Copyright (c) 2003-2006, Ericsson AB | 4 | * Copyright (c) 2003-2006, Ericsson AB |
5 | * Copyright (c) 2005, Wind River Systems | 5 | * Copyright (c) 2005-2007, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -37,34 +37,44 @@ | |||
37 | #ifndef _TIPC_SUBSCR_H | 37 | #ifndef _TIPC_SUBSCR_H |
38 | #define _TIPC_SUBSCR_H | 38 | #define _TIPC_SUBSCR_H |
39 | 39 | ||
40 | struct subscription; | ||
41 | |||
42 | typedef void (*tipc_subscr_event) (struct subscription *sub, | ||
43 | u32 found_lower, u32 found_upper, | ||
44 | u32 event, u32 port_ref, u32 node); | ||
45 | |||
40 | /** | 46 | /** |
41 | * struct subscription - TIPC network topology subscription object | 47 | * struct subscription - TIPC network topology subscription object |
42 | * @seq: name sequence associated with subscription | 48 | * @seq: name sequence associated with subscription |
43 | * @timeout: duration of subscription (in ms) | 49 | * @timeout: duration of subscription (in ms) |
44 | * @filter: event filtering to be done for subscription | 50 | * @filter: event filtering to be done for subscription |
45 | * @evt: template for events generated by subscription | 51 | * @event_cb: routine invoked when a subscription event is detected |
46 | * @subscription_list: adjacent subscriptions in subscriber's subscription list | 52 | * @timer: timer governing subscription duration (optional) |
47 | * @nameseq_list: adjacent subscriptions in name sequence's subscription list | 53 | * @nameseq_list: adjacent subscriptions in name sequence's subscription list |
48 | * @timer_ref: reference to timer governing subscription duration (may be NULL) | 54 | * @subscription_list: adjacent subscriptions in subscriber's subscription list |
49 | * @owner: pointer to subscriber object associated with this subscription | 55 | * @server_ref: object reference of server port associated with subscription |
56 | * @swap: indicates if subscriber uses opposite endianness in its messages | ||
57 | * @evt: template for events generated by subscription | ||
50 | */ | 58 | */ |
51 | 59 | ||
52 | struct subscription { | 60 | struct subscription { |
53 | struct tipc_name_seq seq; | 61 | struct tipc_name_seq seq; |
54 | u32 timeout; | 62 | u32 timeout; |
55 | u32 filter; | 63 | u32 filter; |
56 | struct tipc_event evt; | 64 | tipc_subscr_event event_cb; |
57 | struct list_head subscription_list; | ||
58 | struct list_head nameseq_list; | ||
59 | struct timer_list timer; | 65 | struct timer_list timer; |
60 | struct subscriber *owner; | 66 | struct list_head nameseq_list; |
67 | struct list_head subscription_list; | ||
68 | u32 server_ref; | ||
69 | int swap; | ||
70 | struct tipc_event evt; | ||
61 | }; | 71 | }; |
62 | 72 | ||
63 | int tipc_subscr_overlap(struct subscription * sub, | 73 | int tipc_subscr_overlap(struct subscription *sub, |
64 | u32 found_lower, | 74 | u32 found_lower, |
65 | u32 found_upper); | 75 | u32 found_upper); |
66 | 76 | ||
67 | void tipc_subscr_report_overlap(struct subscription * sub, | 77 | void tipc_subscr_report_overlap(struct subscription *sub, |
68 | u32 found_lower, | 78 | u32 found_lower, |
69 | u32 found_upper, | 79 | u32 found_upper, |
70 | u32 event, | 80 | u32 event, |
diff --git a/net/tipc/user_reg.c b/net/tipc/user_reg.c index 4146c40cd20b..506928803162 100644 --- a/net/tipc/user_reg.c +++ b/net/tipc/user_reg.c | |||
@@ -91,7 +91,7 @@ static int reg_init(void) | |||
91 | } | 91 | } |
92 | } | 92 | } |
93 | spin_unlock_bh(®_lock); | 93 | spin_unlock_bh(®_lock); |
94 | return users ? TIPC_OK : -ENOMEM; | 94 | return users ? 0 : -ENOMEM; |
95 | } | 95 | } |
96 | 96 | ||
97 | /** | 97 | /** |
@@ -129,7 +129,7 @@ int tipc_reg_start(void) | |||
129 | tipc_k_signal((Handler)reg_callback, | 129 | tipc_k_signal((Handler)reg_callback, |
130 | (unsigned long)&users[u]); | 130 | (unsigned long)&users[u]); |
131 | } | 131 | } |
132 | return TIPC_OK; | 132 | return 0; |
133 | } | 133 | } |
134 | 134 | ||
135 | /** | 135 | /** |
@@ -184,7 +184,7 @@ int tipc_attach(u32 *userid, tipc_mode_event cb, void *usr_handle) | |||
184 | 184 | ||
185 | if (cb && (tipc_mode != TIPC_NOT_RUNNING)) | 185 | if (cb && (tipc_mode != TIPC_NOT_RUNNING)) |
186 | tipc_k_signal((Handler)reg_callback, (unsigned long)user_ptr); | 186 | tipc_k_signal((Handler)reg_callback, (unsigned long)user_ptr); |
187 | return TIPC_OK; | 187 | return 0; |
188 | } | 188 | } |
189 | 189 | ||
190 | /** | 190 | /** |
@@ -230,7 +230,7 @@ int tipc_reg_add_port(struct user_port *up_ptr) | |||
230 | struct tipc_user *user_ptr; | 230 | struct tipc_user *user_ptr; |
231 | 231 | ||
232 | if (up_ptr->user_ref == 0) | 232 | if (up_ptr->user_ref == 0) |
233 | return TIPC_OK; | 233 | return 0; |
234 | if (up_ptr->user_ref > MAX_USERID) | 234 | if (up_ptr->user_ref > MAX_USERID) |
235 | return -EINVAL; | 235 | return -EINVAL; |
236 | if ((tipc_mode == TIPC_NOT_RUNNING) || !users ) | 236 | if ((tipc_mode == TIPC_NOT_RUNNING) || !users ) |
@@ -240,7 +240,7 @@ int tipc_reg_add_port(struct user_port *up_ptr) | |||
240 | user_ptr = &users[up_ptr->user_ref]; | 240 | user_ptr = &users[up_ptr->user_ref]; |
241 | list_add(&up_ptr->uport_list, &user_ptr->ports); | 241 | list_add(&up_ptr->uport_list, &user_ptr->ports); |
242 | spin_unlock_bh(®_lock); | 242 | spin_unlock_bh(®_lock); |
243 | return TIPC_OK; | 243 | return 0; |
244 | } | 244 | } |
245 | 245 | ||
246 | /** | 246 | /** |
@@ -250,7 +250,7 @@ int tipc_reg_add_port(struct user_port *up_ptr) | |||
250 | int tipc_reg_remove_port(struct user_port *up_ptr) | 250 | int tipc_reg_remove_port(struct user_port *up_ptr) |
251 | { | 251 | { |
252 | if (up_ptr->user_ref == 0) | 252 | if (up_ptr->user_ref == 0) |
253 | return TIPC_OK; | 253 | return 0; |
254 | if (up_ptr->user_ref > MAX_USERID) | 254 | if (up_ptr->user_ref > MAX_USERID) |
255 | return -EINVAL; | 255 | return -EINVAL; |
256 | if (!users ) | 256 | if (!users ) |
@@ -259,6 +259,6 @@ int tipc_reg_remove_port(struct user_port *up_ptr) | |||
259 | spin_lock_bh(®_lock); | 259 | spin_lock_bh(®_lock); |
260 | list_del_init(&up_ptr->uport_list); | 260 | list_del_init(&up_ptr->uport_list); |
261 | spin_unlock_bh(®_lock); | 261 | spin_unlock_bh(®_lock); |
262 | return TIPC_OK; | 262 | return 0; |
263 | } | 263 | } |
264 | 264 | ||