diff options
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r-- | net/tipc/node.c | 70 |
1 files changed, 43 insertions, 27 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c index 64976f2e3c66..22aeb2b7ad00 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -44,9 +44,31 @@ static void node_established_contact(struct tipc_node *n_ptr); | |||
44 | 44 | ||
45 | static DEFINE_SPINLOCK(node_create_lock); | 45 | static DEFINE_SPINLOCK(node_create_lock); |
46 | 46 | ||
47 | static struct hlist_head node_htable[NODE_HTABLE_SIZE]; | ||
48 | LIST_HEAD(tipc_node_list); | ||
49 | static u32 tipc_num_nodes; | ||
47 | u32 tipc_own_tag; | 50 | u32 tipc_own_tag; |
48 | 51 | ||
49 | /** | 52 | /** |
53 | * tipc_node_find - locate specified node object, if it exists | ||
54 | */ | ||
55 | |||
56 | struct tipc_node *tipc_node_find(u32 addr) | ||
57 | { | ||
58 | struct tipc_node *node; | ||
59 | struct hlist_node *pos; | ||
60 | |||
61 | if (unlikely(!in_own_cluster(addr))) | ||
62 | return NULL; | ||
63 | |||
64 | hlist_for_each_entry(node, pos, &node_htable[tipc_hashfn(addr)], hash) { | ||
65 | if (node->addr == addr) | ||
66 | return node; | ||
67 | } | ||
68 | return NULL; | ||
69 | } | ||
70 | |||
71 | /** | ||
50 | * tipc_node_create - create neighboring node | 72 | * tipc_node_create - create neighboring node |
51 | * | 73 | * |
52 | * Currently, this routine is called by neighbor discovery code, which holds | 74 | * Currently, this routine is called by neighbor discovery code, which holds |
@@ -58,8 +80,7 @@ u32 tipc_own_tag; | |||
58 | 80 | ||
59 | struct tipc_node *tipc_node_create(u32 addr) | 81 | struct tipc_node *tipc_node_create(u32 addr) |
60 | { | 82 | { |
61 | struct tipc_node *n_ptr; | 83 | struct tipc_node *n_ptr, *temp_node; |
62 | u32 n_num; | ||
63 | 84 | ||
64 | spin_lock_bh(&node_create_lock); | 85 | spin_lock_bh(&node_create_lock); |
65 | 86 | ||
@@ -78,12 +99,19 @@ struct tipc_node *tipc_node_create(u32 addr) | |||
78 | 99 | ||
79 | n_ptr->addr = addr; | 100 | n_ptr->addr = addr; |
80 | spin_lock_init(&n_ptr->lock); | 101 | spin_lock_init(&n_ptr->lock); |
102 | INIT_HLIST_NODE(&n_ptr->hash); | ||
103 | INIT_LIST_HEAD(&n_ptr->list); | ||
81 | INIT_LIST_HEAD(&n_ptr->nsub); | 104 | INIT_LIST_HEAD(&n_ptr->nsub); |
82 | 105 | ||
83 | n_num = tipc_node(addr); | 106 | hlist_add_head(&n_ptr->hash, &node_htable[tipc_hashfn(addr)]); |
84 | tipc_nodes[n_num] = n_ptr; | 107 | |
85 | if (n_num > tipc_highest_node) | 108 | list_for_each_entry(temp_node, &tipc_node_list, list) { |
86 | tipc_highest_node = n_num; | 109 | if (n_ptr->addr < temp_node->addr) |
110 | break; | ||
111 | } | ||
112 | list_add_tail(&n_ptr->list, &temp_node->list); | ||
113 | |||
114 | tipc_num_nodes++; | ||
87 | 115 | ||
88 | spin_unlock_bh(&node_create_lock); | 116 | spin_unlock_bh(&node_create_lock); |
89 | return n_ptr; | 117 | return n_ptr; |
@@ -91,18 +119,11 @@ struct tipc_node *tipc_node_create(u32 addr) | |||
91 | 119 | ||
92 | void tipc_node_delete(struct tipc_node *n_ptr) | 120 | void tipc_node_delete(struct tipc_node *n_ptr) |
93 | { | 121 | { |
94 | u32 n_num; | 122 | list_del(&n_ptr->list); |
95 | 123 | hlist_del(&n_ptr->hash); | |
96 | if (!n_ptr) | ||
97 | return; | ||
98 | |||
99 | n_num = tipc_node(n_ptr->addr); | ||
100 | tipc_nodes[n_num] = NULL; | ||
101 | kfree(n_ptr); | 124 | kfree(n_ptr); |
102 | 125 | ||
103 | while (!tipc_nodes[tipc_highest_node]) | 126 | tipc_num_nodes--; |
104 | if (--tipc_highest_node == 0) | ||
105 | break; | ||
106 | } | 127 | } |
107 | 128 | ||
108 | 129 | ||
@@ -379,7 +400,6 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) | |||
379 | struct tipc_node *n_ptr; | 400 | struct tipc_node *n_ptr; |
380 | struct tipc_node_info node_info; | 401 | struct tipc_node_info node_info; |
381 | u32 payload_size; | 402 | u32 payload_size; |
382 | u32 n_num; | ||
383 | 403 | ||
384 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) | 404 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) |
385 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); | 405 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); |
@@ -390,15 +410,14 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) | |||
390 | " (network address)"); | 410 | " (network address)"); |
391 | 411 | ||
392 | read_lock_bh(&tipc_net_lock); | 412 | read_lock_bh(&tipc_net_lock); |
393 | if (!tipc_nodes) { | 413 | if (!tipc_num_nodes) { |
394 | read_unlock_bh(&tipc_net_lock); | 414 | read_unlock_bh(&tipc_net_lock); |
395 | return tipc_cfg_reply_none(); | 415 | return tipc_cfg_reply_none(); |
396 | } | 416 | } |
397 | 417 | ||
398 | /* For now, get space for all other nodes */ | 418 | /* For now, get space for all other nodes */ |
399 | 419 | ||
400 | payload_size = TLV_SPACE(sizeof(node_info)) * | 420 | payload_size = TLV_SPACE(sizeof(node_info)) * tipc_num_nodes; |
401 | (tipc_highest_node - 1); | ||
402 | if (payload_size > 32768u) { | 421 | if (payload_size > 32768u) { |
403 | read_unlock_bh(&tipc_net_lock); | 422 | read_unlock_bh(&tipc_net_lock); |
404 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | 423 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED |
@@ -412,9 +431,8 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) | |||
412 | 431 | ||
413 | /* Add TLVs for all nodes in scope */ | 432 | /* Add TLVs for all nodes in scope */ |
414 | 433 | ||
415 | for (n_num = 1; n_num <= tipc_highest_node; n_num++) { | 434 | list_for_each_entry(n_ptr, &tipc_node_list, list) { |
416 | n_ptr = tipc_nodes[n_num]; | 435 | if (!tipc_in_scope(domain, n_ptr->addr)) |
417 | if (!n_ptr || !tipc_in_scope(domain, n_ptr->addr)) | ||
418 | continue; | 436 | continue; |
419 | node_info.addr = htonl(n_ptr->addr); | 437 | node_info.addr = htonl(n_ptr->addr); |
420 | node_info.up = htonl(tipc_node_is_up(n_ptr)); | 438 | node_info.up = htonl(tipc_node_is_up(n_ptr)); |
@@ -433,7 +451,6 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space) | |||
433 | struct tipc_node *n_ptr; | 451 | struct tipc_node *n_ptr; |
434 | struct tipc_link_info link_info; | 452 | struct tipc_link_info link_info; |
435 | u32 payload_size; | 453 | u32 payload_size; |
436 | u32 n_num; | ||
437 | 454 | ||
438 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) | 455 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) |
439 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); | 456 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); |
@@ -472,11 +489,10 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space) | |||
472 | 489 | ||
473 | /* Add TLVs for any other links in scope */ | 490 | /* Add TLVs for any other links in scope */ |
474 | 491 | ||
475 | for (n_num = 1; n_num <= tipc_highest_node; n_num++) { | 492 | list_for_each_entry(n_ptr, &tipc_node_list, list) { |
476 | u32 i; | 493 | u32 i; |
477 | 494 | ||
478 | n_ptr = tipc_nodes[n_num]; | 495 | if (!tipc_in_scope(domain, n_ptr->addr)) |
479 | if (!n_ptr || !tipc_in_scope(domain, n_ptr->addr)) | ||
480 | continue; | 496 | continue; |
481 | tipc_node_lock(n_ptr); | 497 | tipc_node_lock(n_ptr); |
482 | for (i = 0; i < MAX_BEARERS; i++) { | 498 | for (i = 0; i < MAX_BEARERS; i++) { |