Commit 169bf912 authored by Jon Paul Maloy's avatar Jon Paul Maloy Committed by David S. Miller

tipc: ensure that idle links are deleted when a bearer is disabled

commit afaa3f65
(tipc: purge links when bearer is disabled) was an attempt to resolve
a problem that turned out to have a more profound reason.

When we disable a bearer, we delete all its pertaining links if
there is no other bearer to perform failover to, or if the module
is shutting down. In case there are dual bearers, we wait with
deleting links until the failover procedure is finished.

However, this misses the case when a link on the removed bearer
was already down, so that there will be no failover procedure to
finish the link delete. This causes confusion if a new bearer is
added to replace the removed one, and also entails a small memory
leak.

This commit takes the current state of the link into account when
deciding when to delete it, and also reverses the above-mentioned
commit.
Reviewed-by: default avatarErik Hugne <erik.hugne@ericsson.com>
Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ddb4b9a1
...@@ -747,7 +747,7 @@ int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info) ...@@ -747,7 +747,7 @@ int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info)
return -EINVAL; return -EINVAL;
} }
bearer_disable(net, bearer, true); bearer_disable(net, bearer, false);
rtnl_unlock(); rtnl_unlock();
return 0; return 0;
......
...@@ -344,6 +344,7 @@ void tipc_link_delete_list(struct net *net, unsigned int bearer_id, ...@@ -344,6 +344,7 @@ void tipc_link_delete_list(struct net *net, unsigned int bearer_id,
struct tipc_net *tn = net_generic(net, tipc_net_id); struct tipc_net *tn = net_generic(net, tipc_net_id);
struct tipc_link *link; struct tipc_link *link;
struct tipc_node *node; struct tipc_node *node;
bool del_link;
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(node, &tn->node_list, list) { list_for_each_entry_rcu(node, &tn->node_list, list) {
...@@ -353,12 +354,13 @@ void tipc_link_delete_list(struct net *net, unsigned int bearer_id, ...@@ -353,12 +354,13 @@ void tipc_link_delete_list(struct net *net, unsigned int bearer_id,
tipc_node_unlock(node); tipc_node_unlock(node);
continue; continue;
} }
del_link = !tipc_link_is_up(link) && !link->exp_msg_count;
tipc_link_reset(link); tipc_link_reset(link);
if (del_timer(&link->timer)) if (del_timer(&link->timer))
tipc_link_put(link); tipc_link_put(link);
link->flags |= LINK_STOPPED; link->flags |= LINK_STOPPED;
/* Delete link now, or when failover is finished: */ /* Delete link now, or when failover is finished: */
if (shutting_down || !tipc_node_is_up(node)) if (shutting_down || !tipc_node_is_up(node) || del_link)
tipc_link_delete(link); tipc_link_delete(link);
tipc_node_unlock(node); tipc_node_unlock(node);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment