aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/name_table.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 4068eaad61a6..dd1c4fa2eb78 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -241,7 +241,8 @@ err:
241static struct publication *tipc_service_remove_publ(struct net *net, 241static struct publication *tipc_service_remove_publ(struct net *net,
242 struct tipc_service *sc, 242 struct tipc_service *sc,
243 u32 lower, u32 upper, 243 u32 lower, u32 upper,
244 u32 node, u32 key) 244 u32 node, u32 key,
245 struct service_range **rng)
245{ 246{
246 struct tipc_subscription *sub, *tmp; 247 struct tipc_subscription *sub, *tmp;
247 struct service_range *sr; 248 struct service_range *sr;
@@ -275,19 +276,15 @@ static struct publication *tipc_service_remove_publ(struct net *net,
275 276
276 list_del(&p->all_publ); 277 list_del(&p->all_publ);
277 list_del(&p->local_publ); 278 list_del(&p->local_publ);
278 279 if (list_empty(&sr->all_publ))
279 /* Remove service range item if this was its last publication */
280 if (list_empty(&sr->all_publ)) {
281 last = true; 280 last = true;
282 rb_erase(&sr->tree_node, &sc->ranges);
283 kfree(sr);
284 }
285 281
286 /* Notify any waiting subscriptions */ 282 /* Notify any waiting subscriptions */
287 list_for_each_entry_safe(sub, tmp, &sc->subscriptions, service_list) { 283 list_for_each_entry_safe(sub, tmp, &sc->subscriptions, service_list) {
288 tipc_sub_report_overlap(sub, p->lower, p->upper, TIPC_WITHDRAWN, 284 tipc_sub_report_overlap(sub, p->lower, p->upper, TIPC_WITHDRAWN,
289 p->port, p->node, p->scope, last); 285 p->port, p->node, p->scope, last);
290 } 286 }
287 *rng = sr;
291 return p; 288 return p;
292} 289}
293 290
@@ -379,13 +376,20 @@ struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type,
379 u32 node, u32 key) 376 u32 node, u32 key)
380{ 377{
381 struct tipc_service *sc = tipc_service_find(net, type); 378 struct tipc_service *sc = tipc_service_find(net, type);
379 struct service_range *sr = NULL;
382 struct publication *p = NULL; 380 struct publication *p = NULL;
383 381
384 if (!sc) 382 if (!sc)
385 return NULL; 383 return NULL;
386 384
387 spin_lock_bh(&sc->lock); 385 spin_lock_bh(&sc->lock);
388 p = tipc_service_remove_publ(net, sc, lower, upper, node, key); 386 p = tipc_service_remove_publ(net, sc, lower, upper, node, key, &sr);
387
388 /* Remove service range item if this was its last publication */
389 if (sr && list_empty(&sr->all_publ)) {
390 rb_erase(&sr->tree_node, &sc->ranges);
391 kfree(sr);
392 }
389 393
390 /* Delete service item if this no more publications and subscriptions */ 394 /* Delete service item if this no more publications and subscriptions */
391 if (RB_EMPTY_ROOT(&sc->ranges) && list_empty(&sc->subscriptions)) { 395 if (RB_EMPTY_ROOT(&sc->ranges) && list_empty(&sc->subscriptions)) {
@@ -747,16 +751,17 @@ int tipc_nametbl_init(struct net *net)
747static void tipc_service_delete(struct net *net, struct tipc_service *sc) 751static void tipc_service_delete(struct net *net, struct tipc_service *sc)
748{ 752{
749 struct service_range *sr, *tmpr; 753 struct service_range *sr, *tmpr;
750 struct publication *p, *tmpb; 754 struct publication *p, *tmp;
751 755
752 spin_lock_bh(&sc->lock); 756 spin_lock_bh(&sc->lock);
753 rbtree_postorder_for_each_entry_safe(sr, tmpr, &sc->ranges, tree_node) { 757 rbtree_postorder_for_each_entry_safe(sr, tmpr, &sc->ranges, tree_node) {
754 list_for_each_entry_safe(p, tmpb, 758 list_for_each_entry_safe(p, tmp, &sr->all_publ, all_publ) {
755 &sr->all_publ, all_publ) {
756 tipc_service_remove_publ(net, sc, p->lower, p->upper, 759 tipc_service_remove_publ(net, sc, p->lower, p->upper,
757 p->node, p->key); 760 p->node, p->key, &sr);
758 kfree_rcu(p, rcu); 761 kfree_rcu(p, rcu);
759 } 762 }
763 rb_erase(&sr->tree_node, &sc->ranges);
764 kfree(sr);
760 } 765 }
761 hlist_del_init_rcu(&sc->service_list); 766 hlist_del_init_rcu(&sc->service_list);
762 spin_unlock_bh(&sc->lock); 767 spin_unlock_bh(&sc->lock);