aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/link.c
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-03-10 12:23:34 -0400
committerDavid S. Miller <davem@davemloft.net>2015-03-10 18:37:36 -0400
commit169bf9121b19dd6029e0a354d33513f61bfbe3d3 (patch)
treec4b4461c37a3657dfae2353f85e06f25333b0e3f /net/tipc/link.c
parentddb4b9a1328ea89733133e86cf1972d23891abfc (diff)
tipc: ensure that idle links are deleted when a bearer is disabled
commit afaa3f65f65fda2e7b190aac7e2a75d9a2a77cb6 (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: Erik Hugne <erik.hugne@ericsson.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r--net/tipc/link.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 14f09b3cb87c..98609fdfb06a 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -344,6 +344,7 @@ void tipc_link_delete_list(struct net *net, unsigned int bearer_id,
344 struct tipc_net *tn = net_generic(net, tipc_net_id); 344 struct tipc_net *tn = net_generic(net, tipc_net_id);
345 struct tipc_link *link; 345 struct tipc_link *link;
346 struct tipc_node *node; 346 struct tipc_node *node;
347 bool del_link;
347 348
348 rcu_read_lock(); 349 rcu_read_lock();
349 list_for_each_entry_rcu(node, &tn->node_list, list) { 350 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 tipc_node_unlock(node); 354 tipc_node_unlock(node);
354 continue; 355 continue;
355 } 356 }
357 del_link = !tipc_link_is_up(link) && !link->exp_msg_count;
356 tipc_link_reset(link); 358 tipc_link_reset(link);
357 if (del_timer(&link->timer)) 359 if (del_timer(&link->timer))
358 tipc_link_put(link); 360 tipc_link_put(link);
359 link->flags |= LINK_STOPPED; 361 link->flags |= LINK_STOPPED;
360 /* Delete link now, or when failover is finished: */ 362 /* Delete link now, or when failover is finished: */
361 if (shutting_down || !tipc_node_is_up(node)) 363 if (shutting_down || !tipc_node_is_up(node) || del_link)
362 tipc_link_delete(link); 364 tipc_link_delete(link);
363 tipc_node_unlock(node); 365 tipc_node_unlock(node);
364 } 366 }