aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/node.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r--net/tipc/node.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c
index f7069299943f..6ea2c15cfc88 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -38,6 +38,7 @@
38#include "config.h" 38#include "config.h"
39#include "node.h" 39#include "node.h"
40#include "name_distr.h" 40#include "name_distr.h"
41#include "socket.h"
41 42
42#define NODE_HTABLE_SIZE 512 43#define NODE_HTABLE_SIZE 512
43 44
@@ -100,6 +101,7 @@ struct tipc_node *tipc_node_create(u32 addr)
100 INIT_HLIST_NODE(&n_ptr->hash); 101 INIT_HLIST_NODE(&n_ptr->hash);
101 INIT_LIST_HEAD(&n_ptr->list); 102 INIT_LIST_HEAD(&n_ptr->list);
102 INIT_LIST_HEAD(&n_ptr->nsub); 103 INIT_LIST_HEAD(&n_ptr->nsub);
104 __skb_queue_head_init(&n_ptr->waiting_sks);
103 105
104 hlist_add_head_rcu(&n_ptr->hash, &node_htable[tipc_hashfn(addr)]); 106 hlist_add_head_rcu(&n_ptr->hash, &node_htable[tipc_hashfn(addr)]);
105 107
@@ -474,6 +476,7 @@ int tipc_node_get_linkname(u32 bearer_id, u32 addr, char *linkname, size_t len)
474void tipc_node_unlock(struct tipc_node *node) 476void tipc_node_unlock(struct tipc_node *node)
475{ 477{
476 LIST_HEAD(nsub_list); 478 LIST_HEAD(nsub_list);
479 struct sk_buff_head waiting_sks;
477 u32 addr = 0; 480 u32 addr = 0;
478 481
479 if (likely(!node->action_flags)) { 482 if (likely(!node->action_flags)) {
@@ -481,6 +484,11 @@ void tipc_node_unlock(struct tipc_node *node)
481 return; 484 return;
482 } 485 }
483 486
487 __skb_queue_head_init(&waiting_sks);
488 if (node->action_flags & TIPC_WAKEUP_USERS) {
489 skb_queue_splice_init(&node->waiting_sks, &waiting_sks);
490 node->action_flags &= ~TIPC_WAKEUP_USERS;
491 }
484 if (node->action_flags & TIPC_NOTIFY_NODE_DOWN) { 492 if (node->action_flags & TIPC_NOTIFY_NODE_DOWN) {
485 list_replace_init(&node->nsub, &nsub_list); 493 list_replace_init(&node->nsub, &nsub_list);
486 node->action_flags &= ~TIPC_NOTIFY_NODE_DOWN; 494 node->action_flags &= ~TIPC_NOTIFY_NODE_DOWN;
@@ -491,8 +499,12 @@ void tipc_node_unlock(struct tipc_node *node)
491 } 499 }
492 spin_unlock_bh(&node->lock); 500 spin_unlock_bh(&node->lock);
493 501
502 while (!skb_queue_empty(&waiting_sks))
503 tipc_sk_rcv(__skb_dequeue(&waiting_sks));
504
494 if (!list_empty(&nsub_list)) 505 if (!list_empty(&nsub_list))
495 tipc_nodesub_notify(&nsub_list); 506 tipc_nodesub_notify(&nsub_list);
507
496 if (addr) 508 if (addr)
497 tipc_named_node_up(addr); 509 tipc_named_node_up(addr);
498} 510}