aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2014-01-12 08:12:44 -0500
committerIngo Molnar <mingo@kernel.org>2014-01-12 08:12:44 -0500
commitdba861461f88c12249ac78fb877866c04f99deb3 (patch)
tree5812b143581bcc66c7c542f01ba0cb22e489b8e5 /net/tipc
parent0e6601eee039893a3f6420596ae4588d90d13cbe (diff)
parent228fdc083b017eaf90e578fa86fb1ecfd5ffae87 (diff)
Merge branch 'linus' into timers/core
Pick up the latest fixes and refresh the branch. Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/core.c7
-rw-r--r--net/tipc/handler.c11
-rw-r--r--net/tipc/link.c1
-rw-r--r--net/tipc/port.c45
-rw-r--r--net/tipc/port.h6
-rw-r--r--net/tipc/socket.c46
6 files changed, 62 insertions, 54 deletions
diff --git a/net/tipc/core.c b/net/tipc/core.c
index fd4eeeaa972a..c6d3f75a9e1b 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -113,7 +113,6 @@ err:
113static void tipc_core_stop(void) 113static void tipc_core_stop(void)
114{ 114{
115 tipc_netlink_stop(); 115 tipc_netlink_stop();
116 tipc_handler_stop();
117 tipc_cfg_stop(); 116 tipc_cfg_stop();
118 tipc_subscr_stop(); 117 tipc_subscr_stop();
119 tipc_nametbl_stop(); 118 tipc_nametbl_stop();
@@ -146,9 +145,10 @@ static int tipc_core_start(void)
146 res = tipc_subscr_start(); 145 res = tipc_subscr_start();
147 if (!res) 146 if (!res)
148 res = tipc_cfg_init(); 147 res = tipc_cfg_init();
149 if (res) 148 if (res) {
149 tipc_handler_stop();
150 tipc_core_stop(); 150 tipc_core_stop();
151 151 }
152 return res; 152 return res;
153} 153}
154 154
@@ -178,6 +178,7 @@ static int __init tipc_init(void)
178 178
179static void __exit tipc_exit(void) 179static void __exit tipc_exit(void)
180{ 180{
181 tipc_handler_stop();
181 tipc_core_stop_net(); 182 tipc_core_stop_net();
182 tipc_core_stop(); 183 tipc_core_stop();
183 pr_info("Deactivated\n"); 184 pr_info("Deactivated\n");
diff --git a/net/tipc/handler.c b/net/tipc/handler.c
index b36f0fcd9bdf..e4bc8a296744 100644
--- a/net/tipc/handler.c
+++ b/net/tipc/handler.c
@@ -56,12 +56,13 @@ unsigned int tipc_k_signal(Handler routine, unsigned long argument)
56{ 56{
57 struct queue_item *item; 57 struct queue_item *item;
58 58
59 spin_lock_bh(&qitem_lock);
59 if (!handler_enabled) { 60 if (!handler_enabled) {
60 pr_err("Signal request ignored by handler\n"); 61 pr_err("Signal request ignored by handler\n");
62 spin_unlock_bh(&qitem_lock);
61 return -ENOPROTOOPT; 63 return -ENOPROTOOPT;
62 } 64 }
63 65
64 spin_lock_bh(&qitem_lock);
65 item = kmem_cache_alloc(tipc_queue_item_cache, GFP_ATOMIC); 66 item = kmem_cache_alloc(tipc_queue_item_cache, GFP_ATOMIC);
66 if (!item) { 67 if (!item) {
67 pr_err("Signal queue out of memory\n"); 68 pr_err("Signal queue out of memory\n");
@@ -112,10 +113,14 @@ void tipc_handler_stop(void)
112 struct list_head *l, *n; 113 struct list_head *l, *n;
113 struct queue_item *item; 114 struct queue_item *item;
114 115
115 if (!handler_enabled) 116 spin_lock_bh(&qitem_lock);
117 if (!handler_enabled) {
118 spin_unlock_bh(&qitem_lock);
116 return; 119 return;
117 120 }
118 handler_enabled = 0; 121 handler_enabled = 0;
122 spin_unlock_bh(&qitem_lock);
123
119 tasklet_kill(&tipc_tasklet); 124 tasklet_kill(&tipc_tasklet);
120 125
121 spin_lock_bh(&qitem_lock); 126 spin_lock_bh(&qitem_lock);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 69cd9bf3f561..13b987745820 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1498,6 +1498,7 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1498 int type; 1498 int type;
1499 1499
1500 head = head->next; 1500 head = head->next;
1501 buf->next = NULL;
1501 1502
1502 /* Ensure bearer is still enabled */ 1503 /* Ensure bearer is still enabled */
1503 if (unlikely(!b_ptr->active)) 1504 if (unlikely(!b_ptr->active))
diff --git a/net/tipc/port.c b/net/tipc/port.c
index c081a7632302..d43f3182b1d4 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -251,18 +251,15 @@ struct tipc_port *tipc_createport(struct sock *sk,
251 return p_ptr; 251 return p_ptr;
252} 252}
253 253
254int tipc_deleteport(u32 ref) 254int tipc_deleteport(struct tipc_port *p_ptr)
255{ 255{
256 struct tipc_port *p_ptr;
257 struct sk_buff *buf = NULL; 256 struct sk_buff *buf = NULL;
258 257
259 tipc_withdraw(ref, 0, NULL); 258 tipc_withdraw(p_ptr, 0, NULL);
260 p_ptr = tipc_port_lock(ref);
261 if (!p_ptr)
262 return -EINVAL;
263 259
264 tipc_ref_discard(ref); 260 spin_lock_bh(p_ptr->lock);
265 tipc_port_unlock(p_ptr); 261 tipc_ref_discard(p_ptr->ref);
262 spin_unlock_bh(p_ptr->lock);
266 263
267 k_cancel_timer(&p_ptr->timer); 264 k_cancel_timer(&p_ptr->timer);
268 if (p_ptr->connected) { 265 if (p_ptr->connected) {
@@ -704,47 +701,36 @@ int tipc_set_portimportance(u32 ref, unsigned int imp)
704} 701}
705 702
706 703
707int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) 704int tipc_publish(struct tipc_port *p_ptr, unsigned int scope,
705 struct tipc_name_seq const *seq)
708{ 706{
709 struct tipc_port *p_ptr;
710 struct publication *publ; 707 struct publication *publ;
711 u32 key; 708 u32 key;
712 int res = -EINVAL;
713 709
714 p_ptr = tipc_port_lock(ref); 710 if (p_ptr->connected)
715 if (!p_ptr)
716 return -EINVAL; 711 return -EINVAL;
712 key = p_ptr->ref + p_ptr->pub_count + 1;
713 if (key == p_ptr->ref)
714 return -EADDRINUSE;
717 715
718 if (p_ptr->connected)
719 goto exit;
720 key = ref + p_ptr->pub_count + 1;
721 if (key == ref) {
722 res = -EADDRINUSE;
723 goto exit;
724 }
725 publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper, 716 publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper,
726 scope, p_ptr->ref, key); 717 scope, p_ptr->ref, key);
727 if (publ) { 718 if (publ) {
728 list_add(&publ->pport_list, &p_ptr->publications); 719 list_add(&publ->pport_list, &p_ptr->publications);
729 p_ptr->pub_count++; 720 p_ptr->pub_count++;
730 p_ptr->published = 1; 721 p_ptr->published = 1;
731 res = 0; 722 return 0;
732 } 723 }
733exit: 724 return -EINVAL;
734 tipc_port_unlock(p_ptr);
735 return res;
736} 725}
737 726
738int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) 727int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope,
728 struct tipc_name_seq const *seq)
739{ 729{
740 struct tipc_port *p_ptr;
741 struct publication *publ; 730 struct publication *publ;
742 struct publication *tpubl; 731 struct publication *tpubl;
743 int res = -EINVAL; 732 int res = -EINVAL;
744 733
745 p_ptr = tipc_port_lock(ref);
746 if (!p_ptr)
747 return -EINVAL;
748 if (!seq) { 734 if (!seq) {
749 list_for_each_entry_safe(publ, tpubl, 735 list_for_each_entry_safe(publ, tpubl,
750 &p_ptr->publications, pport_list) { 736 &p_ptr->publications, pport_list) {
@@ -771,7 +757,6 @@ int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
771 } 757 }
772 if (list_empty(&p_ptr->publications)) 758 if (list_empty(&p_ptr->publications))
773 p_ptr->published = 0; 759 p_ptr->published = 0;
774 tipc_port_unlock(p_ptr);
775 return res; 760 return res;
776} 761}
777 762
diff --git a/net/tipc/port.h b/net/tipc/port.h
index 912253597343..34f12bd4074e 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -116,7 +116,7 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err);
116 116
117void tipc_acknowledge(u32 port_ref, u32 ack); 117void tipc_acknowledge(u32 port_ref, u32 ack);
118 118
119int tipc_deleteport(u32 portref); 119int tipc_deleteport(struct tipc_port *p_ptr);
120 120
121int tipc_portimportance(u32 portref, unsigned int *importance); 121int tipc_portimportance(u32 portref, unsigned int *importance);
122int tipc_set_portimportance(u32 portref, unsigned int importance); 122int tipc_set_portimportance(u32 portref, unsigned int importance);
@@ -127,9 +127,9 @@ int tipc_set_portunreliable(u32 portref, unsigned int isunreliable);
127int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable); 127int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable);
128int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable); 128int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable);
129 129
130int tipc_publish(u32 portref, unsigned int scope, 130int tipc_publish(struct tipc_port *p_ptr, unsigned int scope,
131 struct tipc_name_seq const *name_seq); 131 struct tipc_name_seq const *name_seq);
132int tipc_withdraw(u32 portref, unsigned int scope, 132int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope,
133 struct tipc_name_seq const *name_seq); 133 struct tipc_name_seq const *name_seq);
134 134
135int tipc_connect(u32 portref, struct tipc_portid const *port); 135int tipc_connect(u32 portref, struct tipc_portid const *port);
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 3b61851bb927..e741416d1d24 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -354,7 +354,7 @@ static int release(struct socket *sock)
354 * Delete TIPC port; this ensures no more messages are queued 354 * Delete TIPC port; this ensures no more messages are queued
355 * (also disconnects an active connection & sends a 'FIN-' to peer) 355 * (also disconnects an active connection & sends a 'FIN-' to peer)
356 */ 356 */
357 res = tipc_deleteport(tport->ref); 357 res = tipc_deleteport(tport);
358 358
359 /* Discard any remaining (connection-based) messages in receive queue */ 359 /* Discard any remaining (connection-based) messages in receive queue */
360 __skb_queue_purge(&sk->sk_receive_queue); 360 __skb_queue_purge(&sk->sk_receive_queue);
@@ -386,30 +386,46 @@ static int release(struct socket *sock)
386 */ 386 */
387static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) 387static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len)
388{ 388{
389 struct sock *sk = sock->sk;
389 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; 390 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
390 u32 portref = tipc_sk_port(sock->sk)->ref; 391 struct tipc_port *tport = tipc_sk_port(sock->sk);
392 int res = -EINVAL;
391 393
392 if (unlikely(!uaddr_len)) 394 lock_sock(sk);
393 return tipc_withdraw(portref, 0, NULL); 395 if (unlikely(!uaddr_len)) {
396 res = tipc_withdraw(tport, 0, NULL);
397 goto exit;
398 }
394 399
395 if (uaddr_len < sizeof(struct sockaddr_tipc)) 400 if (uaddr_len < sizeof(struct sockaddr_tipc)) {
396 return -EINVAL; 401 res = -EINVAL;
397 if (addr->family != AF_TIPC) 402 goto exit;
398 return -EAFNOSUPPORT; 403 }
404 if (addr->family != AF_TIPC) {
405 res = -EAFNOSUPPORT;
406 goto exit;
407 }
399 408
400 if (addr->addrtype == TIPC_ADDR_NAME) 409 if (addr->addrtype == TIPC_ADDR_NAME)
401 addr->addr.nameseq.upper = addr->addr.nameseq.lower; 410 addr->addr.nameseq.upper = addr->addr.nameseq.lower;
402 else if (addr->addrtype != TIPC_ADDR_NAMESEQ) 411 else if (addr->addrtype != TIPC_ADDR_NAMESEQ) {
403 return -EAFNOSUPPORT; 412 res = -EAFNOSUPPORT;
413 goto exit;
414 }
404 415
405 if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) && 416 if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) &&
406 (addr->addr.nameseq.type != TIPC_TOP_SRV) && 417 (addr->addr.nameseq.type != TIPC_TOP_SRV) &&
407 (addr->addr.nameseq.type != TIPC_CFG_SRV)) 418 (addr->addr.nameseq.type != TIPC_CFG_SRV)) {
408 return -EACCES; 419 res = -EACCES;
420 goto exit;
421 }
409 422
410 return (addr->scope > 0) ? 423 res = (addr->scope > 0) ?
411 tipc_publish(portref, addr->scope, &addr->addr.nameseq) : 424 tipc_publish(tport, addr->scope, &addr->addr.nameseq) :
412 tipc_withdraw(portref, -addr->scope, &addr->addr.nameseq); 425 tipc_withdraw(tport, -addr->scope, &addr->addr.nameseq);
426exit:
427 release_sock(sk);
428 return res;
413} 429}
414 430
415/** 431/**