diff options
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r-- | net/tipc/node.c | 12 |
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) | |||
474 | void tipc_node_unlock(struct tipc_node *node) | 476 | void 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 | } |