diff options
Diffstat (limited to 'net/tipc/name_distr.c')
-rw-r--r-- | net/tipc/name_distr.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index ebe9d0ff6e9e..6b626a64b517 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c | |||
@@ -40,11 +40,6 @@ | |||
40 | 40 | ||
41 | int sysctl_tipc_named_timeout __read_mostly = 2000; | 41 | int sysctl_tipc_named_timeout __read_mostly = 2000; |
42 | 42 | ||
43 | /** | ||
44 | * struct tipc_dist_queue - queue holding deferred name table updates | ||
45 | */ | ||
46 | static struct list_head tipc_dist_queue = LIST_HEAD_INIT(tipc_dist_queue); | ||
47 | |||
48 | struct distr_queue_item { | 43 | struct distr_queue_item { |
49 | struct distr_item i; | 44 | struct distr_item i; |
50 | u32 dtype; | 45 | u32 dtype; |
@@ -229,12 +224,31 @@ static void tipc_publ_purge(struct net *net, struct publication *publ, u32 addr) | |||
229 | kfree_rcu(p, rcu); | 224 | kfree_rcu(p, rcu); |
230 | } | 225 | } |
231 | 226 | ||
227 | /** | ||
228 | * tipc_dist_queue_purge - remove deferred updates from a node that went down | ||
229 | */ | ||
230 | static void tipc_dist_queue_purge(struct net *net, u32 addr) | ||
231 | { | ||
232 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
233 | struct distr_queue_item *e, *tmp; | ||
234 | |||
235 | spin_lock_bh(&tn->nametbl_lock); | ||
236 | list_for_each_entry_safe(e, tmp, &tn->dist_queue, next) { | ||
237 | if (e->node != addr) | ||
238 | continue; | ||
239 | list_del(&e->next); | ||
240 | kfree(e); | ||
241 | } | ||
242 | spin_unlock_bh(&tn->nametbl_lock); | ||
243 | } | ||
244 | |||
232 | void tipc_publ_notify(struct net *net, struct list_head *nsub_list, u32 addr) | 245 | void tipc_publ_notify(struct net *net, struct list_head *nsub_list, u32 addr) |
233 | { | 246 | { |
234 | struct publication *publ, *tmp; | 247 | struct publication *publ, *tmp; |
235 | 248 | ||
236 | list_for_each_entry_safe(publ, tmp, nsub_list, nodesub_list) | 249 | list_for_each_entry_safe(publ, tmp, nsub_list, nodesub_list) |
237 | tipc_publ_purge(net, publ, addr); | 250 | tipc_publ_purge(net, publ, addr); |
251 | tipc_dist_queue_purge(net, addr); | ||
238 | } | 252 | } |
239 | 253 | ||
240 | /** | 254 | /** |
@@ -279,9 +293,11 @@ static bool tipc_update_nametbl(struct net *net, struct distr_item *i, | |||
279 | * tipc_named_add_backlog - add a failed name table update to the backlog | 293 | * tipc_named_add_backlog - add a failed name table update to the backlog |
280 | * | 294 | * |
281 | */ | 295 | */ |
282 | static void tipc_named_add_backlog(struct distr_item *i, u32 type, u32 node) | 296 | static void tipc_named_add_backlog(struct net *net, struct distr_item *i, |
297 | u32 type, u32 node) | ||
283 | { | 298 | { |
284 | struct distr_queue_item *e; | 299 | struct distr_queue_item *e; |
300 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
285 | unsigned long now = get_jiffies_64(); | 301 | unsigned long now = get_jiffies_64(); |
286 | 302 | ||
287 | e = kzalloc(sizeof(*e), GFP_ATOMIC); | 303 | e = kzalloc(sizeof(*e), GFP_ATOMIC); |
@@ -291,7 +307,7 @@ static void tipc_named_add_backlog(struct distr_item *i, u32 type, u32 node) | |||
291 | e->node = node; | 307 | e->node = node; |
292 | e->expires = now + msecs_to_jiffies(sysctl_tipc_named_timeout); | 308 | e->expires = now + msecs_to_jiffies(sysctl_tipc_named_timeout); |
293 | memcpy(e, i, sizeof(*i)); | 309 | memcpy(e, i, sizeof(*i)); |
294 | list_add_tail(&e->next, &tipc_dist_queue); | 310 | list_add_tail(&e->next, &tn->dist_queue); |
295 | } | 311 | } |
296 | 312 | ||
297 | /** | 313 | /** |
@@ -301,10 +317,11 @@ static void tipc_named_add_backlog(struct distr_item *i, u32 type, u32 node) | |||
301 | void tipc_named_process_backlog(struct net *net) | 317 | void tipc_named_process_backlog(struct net *net) |
302 | { | 318 | { |
303 | struct distr_queue_item *e, *tmp; | 319 | struct distr_queue_item *e, *tmp; |
320 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
304 | char addr[16]; | 321 | char addr[16]; |
305 | unsigned long now = get_jiffies_64(); | 322 | unsigned long now = get_jiffies_64(); |
306 | 323 | ||
307 | list_for_each_entry_safe(e, tmp, &tipc_dist_queue, next) { | 324 | list_for_each_entry_safe(e, tmp, &tn->dist_queue, next) { |
308 | if (time_after(e->expires, now)) { | 325 | if (time_after(e->expires, now)) { |
309 | if (!tipc_update_nametbl(net, &e->i, e->node, e->dtype)) | 326 | if (!tipc_update_nametbl(net, &e->i, e->node, e->dtype)) |
310 | continue; | 327 | continue; |
@@ -344,7 +361,7 @@ void tipc_named_rcv(struct net *net, struct sk_buff_head *inputq) | |||
344 | node = msg_orignode(msg); | 361 | node = msg_orignode(msg); |
345 | while (count--) { | 362 | while (count--) { |
346 | if (!tipc_update_nametbl(net, item, node, mtype)) | 363 | if (!tipc_update_nametbl(net, item, node, mtype)) |
347 | tipc_named_add_backlog(item, mtype, node); | 364 | tipc_named_add_backlog(net, item, mtype, node); |
348 | item++; | 365 | item++; |
349 | } | 366 | } |
350 | kfree_skb(skb); | 367 | kfree_skb(skb); |