This patch ensures that TIPC configuration commands that display info
about neighboring nodes and their links take the spinlocks that
protect the node list and link lists from changing while the lists
are being traversed.
Signed-off-by: Allan Stephens <allan.stephens@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
struct node *n_ptr;
u32 cnt = 0;
struct node *n_ptr;
u32 cnt = 0;
+ read_lock_bh(&tipc_net_lock);
for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) {
if (!in_scope(domain, n_ptr->addr))
continue;
if (tipc_node_is_up(n_ptr))
cnt++;
}
for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) {
if (!in_scope(domain, n_ptr->addr))
continue;
if (tipc_node_is_up(n_ptr))
cnt++;
}
+ read_unlock_bh(&tipc_net_lock);
return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
" (network address)");
return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
" (network address)");
+ read_lock_bh(&tipc_net_lock);
+ if (!tipc_nodes) {
+ read_unlock_bh(&tipc_net_lock);
return tipc_cfg_reply_none();
return tipc_cfg_reply_none();
/* For now, get space for all other nodes
(will need to modify this when slave nodes are supported */
payload_size = TLV_SPACE(sizeof(node_info)) * (tipc_max_nodes - 1);
/* For now, get space for all other nodes
(will need to modify this when slave nodes are supported */
payload_size = TLV_SPACE(sizeof(node_info)) * (tipc_max_nodes - 1);
- if (payload_size > 32768u)
+ if (payload_size > 32768u) {
+ read_unlock_bh(&tipc_net_lock);
return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
" (too many nodes)");
return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
" (too many nodes)");
buf = tipc_cfg_reply_alloc(payload_size);
buf = tipc_cfg_reply_alloc(payload_size);
+ if (!buf) {
+ read_unlock_bh(&tipc_net_lock);
/* Add TLVs for all nodes in scope */
/* Add TLVs for all nodes in scope */
&node_info, sizeof(node_info));
}
&node_info, sizeof(node_info));
}
+ read_unlock_bh(&tipc_net_lock);
if (tipc_mode != TIPC_NET_MODE)
return tipc_cfg_reply_none();
if (tipc_mode != TIPC_NET_MODE)
return tipc_cfg_reply_none();
+ read_lock_bh(&tipc_net_lock);
+
/* Get space for all unicast links + multicast link */
payload_size = TLV_SPACE(sizeof(link_info)) *
(tipc_net.zones[tipc_zone(tipc_own_addr)]->links + 1);
/* Get space for all unicast links + multicast link */
payload_size = TLV_SPACE(sizeof(link_info)) *
(tipc_net.zones[tipc_zone(tipc_own_addr)]->links + 1);
- if (payload_size > 32768u)
+ if (payload_size > 32768u) {
+ read_unlock_bh(&tipc_net_lock);
return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
" (too many links)");
return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
" (too many links)");
buf = tipc_cfg_reply_alloc(payload_size);
buf = tipc_cfg_reply_alloc(payload_size);
+ if (!buf) {
+ read_unlock_bh(&tipc_net_lock);
/* Add TLV for broadcast link */
/* Add TLV for broadcast link */
if (!in_scope(domain, n_ptr->addr))
continue;
if (!in_scope(domain, n_ptr->addr))
continue;
for (i = 0; i < MAX_BEARERS; i++) {
if (!n_ptr->links[i])
continue;
for (i = 0; i < MAX_BEARERS; i++) {
if (!n_ptr->links[i])
continue;
tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO,
&link_info, sizeof(link_info));
}
tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO,
&link_info, sizeof(link_info));
}
+ tipc_node_unlock(n_ptr);
+ read_unlock_bh(&tipc_net_lock);