diff options
-rw-r--r-- | net/tipc/link.c | 13 | ||||
-rw-r--r-- | net/tipc/name_distr.c | 20 | ||||
-rw-r--r-- | net/tipc/name_table.c | 179 | ||||
-rw-r--r-- | net/tipc/node.c | 3 | ||||
-rw-r--r-- | net/tipc/node_subscr.c | 15 | ||||
-rw-r--r-- | net/tipc/port.c | 1 | ||||
-rw-r--r-- | net/tipc/ref.c | 31 |
7 files changed, 153 insertions, 109 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index ff40c9195fef..2efced5a673c 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -574,7 +574,6 @@ void tipc_link_wakeup_ports(struct link *l_ptr, int all) | |||
574 | break; | 574 | break; |
575 | list_del_init(&p_ptr->wait_list); | 575 | list_del_init(&p_ptr->wait_list); |
576 | p_ptr->congested_link = NULL; | 576 | p_ptr->congested_link = NULL; |
577 | assert(p_ptr->wakeup); | ||
578 | spin_lock_bh(p_ptr->publ.lock); | 577 | spin_lock_bh(p_ptr->publ.lock); |
579 | p_ptr->publ.congested = 0; | 578 | p_ptr->publ.congested = 0; |
580 | p_ptr->wakeup(&p_ptr->publ); | 579 | p_ptr->wakeup(&p_ptr->publ); |
@@ -1246,8 +1245,6 @@ int tipc_link_send_sections_fast(struct port *sender, | |||
1246 | int res; | 1245 | int res; |
1247 | u32 selector = msg_origport(hdr) & 1; | 1246 | u32 selector = msg_origport(hdr) & 1; |
1248 | 1247 | ||
1249 | assert(destaddr != tipc_own_addr); | ||
1250 | |||
1251 | again: | 1248 | again: |
1252 | /* | 1249 | /* |
1253 | * Try building message using port's max_pkt hint. | 1250 | * Try building message using port's max_pkt hint. |
@@ -2310,7 +2307,6 @@ void tipc_link_tunnel(struct link *l_ptr, | |||
2310 | memcpy(buf->data + INT_H_SIZE, (unchar *)msg, length); | 2307 | memcpy(buf->data + INT_H_SIZE, (unchar *)msg, length); |
2311 | dbg("%c->%c:", l_ptr->b_ptr->net_plane, tunnel->b_ptr->net_plane); | 2308 | dbg("%c->%c:", l_ptr->b_ptr->net_plane, tunnel->b_ptr->net_plane); |
2312 | msg_dbg(buf_msg(buf), ">SEND>"); | 2309 | msg_dbg(buf_msg(buf), ">SEND>"); |
2313 | assert(tunnel); | ||
2314 | tipc_link_send_buf(tunnel, buf); | 2310 | tipc_link_send_buf(tunnel, buf); |
2315 | } | 2311 | } |
2316 | 2312 | ||
@@ -2339,10 +2335,10 @@ void tipc_link_changeover(struct link *l_ptr) | |||
2339 | ORIGINAL_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr); | 2335 | ORIGINAL_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr); |
2340 | msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); | 2336 | msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); |
2341 | msg_set_msgcnt(&tunnel_hdr, msgcount); | 2337 | msg_set_msgcnt(&tunnel_hdr, msgcount); |
2338 | |||
2342 | if (!l_ptr->first_out) { | 2339 | if (!l_ptr->first_out) { |
2343 | struct sk_buff *buf; | 2340 | struct sk_buff *buf; |
2344 | 2341 | ||
2345 | assert(!msgcount); | ||
2346 | buf = buf_acquire(INT_H_SIZE); | 2342 | buf = buf_acquire(INT_H_SIZE); |
2347 | if (buf) { | 2343 | if (buf) { |
2348 | memcpy(buf->data, (unchar *)&tunnel_hdr, INT_H_SIZE); | 2344 | memcpy(buf->data, (unchar *)&tunnel_hdr, INT_H_SIZE); |
@@ -2356,6 +2352,7 @@ void tipc_link_changeover(struct link *l_ptr) | |||
2356 | } | 2352 | } |
2357 | return; | 2353 | return; |
2358 | } | 2354 | } |
2355 | |||
2359 | while (crs) { | 2356 | while (crs) { |
2360 | struct tipc_msg *msg = buf_msg(crs); | 2357 | struct tipc_msg *msg = buf_msg(crs); |
2361 | 2358 | ||
@@ -2455,11 +2452,15 @@ static int link_recv_changeover_msg(struct link **l_ptr, | |||
2455 | u32 msg_count = msg_msgcnt(tunnel_msg); | 2452 | u32 msg_count = msg_msgcnt(tunnel_msg); |
2456 | 2453 | ||
2457 | dest_link = (*l_ptr)->owner->links[msg_bearer_id(tunnel_msg)]; | 2454 | dest_link = (*l_ptr)->owner->links[msg_bearer_id(tunnel_msg)]; |
2458 | assert(dest_link != *l_ptr); | ||
2459 | if (!dest_link) { | 2455 | if (!dest_link) { |
2460 | msg_dbg(tunnel_msg, "NOLINK/<REC<"); | 2456 | msg_dbg(tunnel_msg, "NOLINK/<REC<"); |
2461 | goto exit; | 2457 | goto exit; |
2462 | } | 2458 | } |
2459 | if (dest_link == *l_ptr) { | ||
2460 | err("Unexpected changeover message on link <%s>\n", | ||
2461 | (*l_ptr)->name); | ||
2462 | goto exit; | ||
2463 | } | ||
2463 | dbg("%c<-%c:", dest_link->b_ptr->net_plane, | 2464 | dbg("%c<-%c:", dest_link->b_ptr->net_plane, |
2464 | (*l_ptr)->b_ptr->net_plane); | 2465 | (*l_ptr)->b_ptr->net_plane); |
2465 | *l_ptr = dest_link; | 2466 | *l_ptr = dest_link; |
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index a3bbc891f959..5718ecb91d33 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c | |||
@@ -174,7 +174,6 @@ void tipc_named_node_up(unsigned long node) | |||
174 | u32 rest; | 174 | u32 rest; |
175 | u32 max_item_buf; | 175 | u32 max_item_buf; |
176 | 176 | ||
177 | assert(in_own_cluster(node)); | ||
178 | read_lock_bh(&tipc_nametbl_lock); | 177 | read_lock_bh(&tipc_nametbl_lock); |
179 | max_item_buf = TIPC_MAX_USER_MSG_SIZE / ITEM_SIZE; | 178 | max_item_buf = TIPC_MAX_USER_MSG_SIZE / ITEM_SIZE; |
180 | max_item_buf *= ITEM_SIZE; | 179 | max_item_buf *= ITEM_SIZE; |
@@ -221,15 +220,24 @@ exit: | |||
221 | static void node_is_down(struct publication *publ) | 220 | static void node_is_down(struct publication *publ) |
222 | { | 221 | { |
223 | struct publication *p; | 222 | struct publication *p; |
223 | |||
224 | write_lock_bh(&tipc_nametbl_lock); | 224 | write_lock_bh(&tipc_nametbl_lock); |
225 | dbg("node_is_down: withdrawing %u, %u, %u\n", | 225 | dbg("node_is_down: withdrawing %u, %u, %u\n", |
226 | publ->type, publ->lower, publ->upper); | 226 | publ->type, publ->lower, publ->upper); |
227 | publ->key += 1222345; | 227 | publ->key += 1222345; |
228 | p = tipc_nametbl_remove_publ(publ->type, publ->lower, | 228 | p = tipc_nametbl_remove_publ(publ->type, publ->lower, |
229 | publ->node, publ->ref, publ->key); | 229 | publ->node, publ->ref, publ->key); |
230 | assert(p == publ); | ||
231 | write_unlock_bh(&tipc_nametbl_lock); | 230 | write_unlock_bh(&tipc_nametbl_lock); |
232 | kfree(publ); | 231 | |
232 | if (p != publ) { | ||
233 | err("Unable to remove publication from failed node\n" | ||
234 | "(type=%u, lower=%u, node=0x%x, ref=%u, key=%u)\n", | ||
235 | publ->type, publ->lower, publ->node, publ->ref, publ->key); | ||
236 | } | ||
237 | |||
238 | if (p) { | ||
239 | kfree(p); | ||
240 | } | ||
233 | } | 241 | } |
234 | 242 | ||
235 | /** | 243 | /** |
@@ -275,6 +283,12 @@ void tipc_named_recv(struct sk_buff *buf) | |||
275 | if (publ) { | 283 | if (publ) { |
276 | tipc_nodesub_unsubscribe(&publ->subscr); | 284 | tipc_nodesub_unsubscribe(&publ->subscr); |
277 | kfree(publ); | 285 | kfree(publ); |
286 | } else { | ||
287 | err("Unable to remove publication by node 0x%x\n" | ||
288 | "(type=%u, lower=%u, ref=%u, key=%u)\n", | ||
289 | msg_orignode(msg), | ||
290 | ntohl(item->type), ntohl(item->lower), | ||
291 | ntohl(item->ref), ntohl(item->key)); | ||
278 | } | 292 | } |
279 | } else { | 293 | } else { |
280 | warn("tipc_named_recv: unknown msg\n"); | 294 | warn("tipc_named_recv: unknown msg\n"); |
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 051143648edb..e90dc80cd74a 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c | |||
@@ -71,7 +71,7 @@ struct sub_seq { | |||
71 | * @sseq: pointer to dynamically-sized array of sub-sequences of this 'type'; | 71 | * @sseq: pointer to dynamically-sized array of sub-sequences of this 'type'; |
72 | * sub-sequences are sorted in ascending order | 72 | * sub-sequences are sorted in ascending order |
73 | * @alloc: number of sub-sequences currently in array | 73 | * @alloc: number of sub-sequences currently in array |
74 | * @first_free: upper bound of highest sub-sequence + 1 | 74 | * @first_free: array index of first unused sub-sequence entry |
75 | * @ns_list: links to adjacent name sequences in hash chain | 75 | * @ns_list: links to adjacent name sequences in hash chain |
76 | * @subscriptions: list of subscriptions for this 'type' | 76 | * @subscriptions: list of subscriptions for this 'type' |
77 | * @lock: spinlock controlling access to name sequence structure | 77 | * @lock: spinlock controlling access to name sequence structure |
@@ -175,7 +175,7 @@ static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_hea | |||
175 | nseq->lock = SPIN_LOCK_UNLOCKED; | 175 | nseq->lock = SPIN_LOCK_UNLOCKED; |
176 | nseq->type = type; | 176 | nseq->type = type; |
177 | nseq->sseqs = sseq; | 177 | nseq->sseqs = sseq; |
178 | dbg("tipc_nameseq_create() nseq = %x type %u, ssseqs %x, ff: %u\n", | 178 | dbg("tipc_nameseq_create(): nseq = %p, type %u, ssseqs %p, ff: %u\n", |
179 | nseq, type, nseq->sseqs, nseq->first_free); | 179 | nseq, type, nseq->sseqs, nseq->first_free); |
180 | nseq->alloc = 1; | 180 | nseq->alloc = 1; |
181 | INIT_HLIST_NODE(&nseq->ns_list); | 181 | INIT_HLIST_NODE(&nseq->ns_list); |
@@ -253,16 +253,16 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
253 | struct sub_seq *sseq; | 253 | struct sub_seq *sseq; |
254 | int created_subseq = 0; | 254 | int created_subseq = 0; |
255 | 255 | ||
256 | assert(nseq->first_free <= nseq->alloc); | ||
257 | sseq = nameseq_find_subseq(nseq, lower); | 256 | sseq = nameseq_find_subseq(nseq, lower); |
258 | dbg("nameseq_ins: for seq %x,<%u,%u>, found sseq %x\n", | 257 | dbg("nameseq_ins: for seq %p, {%u,%u}, found sseq %p\n", |
259 | nseq, type, lower, sseq); | 258 | nseq, type, lower, sseq); |
260 | if (sseq) { | 259 | if (sseq) { |
261 | 260 | ||
262 | /* Lower end overlaps existing entry => need an exact match */ | 261 | /* Lower end overlaps existing entry => need an exact match */ |
263 | 262 | ||
264 | if ((sseq->lower != lower) || (sseq->upper != upper)) { | 263 | if ((sseq->lower != lower) || (sseq->upper != upper)) { |
265 | warn("Overlapping publ <%u,%u,%u>\n", type, lower, upper); | 264 | warn("Cannot publish {%u,%u,%u}, overlap error\n", |
265 | type, lower, upper); | ||
266 | return NULL; | 266 | return NULL; |
267 | } | 267 | } |
268 | } else { | 268 | } else { |
@@ -277,7 +277,8 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
277 | 277 | ||
278 | if ((inspos < nseq->first_free) && | 278 | if ((inspos < nseq->first_free) && |
279 | (upper >= nseq->sseqs[inspos].lower)) { | 279 | (upper >= nseq->sseqs[inspos].lower)) { |
280 | warn("Overlapping publ <%u,%u,%u>\n", type, lower, upper); | 280 | warn("Cannot publish {%u,%u,%u}, overlap error\n", |
281 | type, lower, upper); | ||
281 | return NULL; | 282 | return NULL; |
282 | } | 283 | } |
283 | 284 | ||
@@ -287,7 +288,8 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
287 | struct sub_seq *sseqs = tipc_subseq_alloc(nseq->alloc * 2); | 288 | struct sub_seq *sseqs = tipc_subseq_alloc(nseq->alloc * 2); |
288 | 289 | ||
289 | if (!sseqs) { | 290 | if (!sseqs) { |
290 | warn("Memory squeeze; failed to create sub-sequence\n"); | 291 | warn("Cannot publish {%u,%u,%u}, no memory\n", |
292 | type, lower, upper); | ||
291 | return NULL; | 293 | return NULL; |
292 | } | 294 | } |
293 | dbg("Allocated %u more sseqs\n", nseq->alloc); | 295 | dbg("Allocated %u more sseqs\n", nseq->alloc); |
@@ -311,7 +313,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
311 | sseq->upper = upper; | 313 | sseq->upper = upper; |
312 | created_subseq = 1; | 314 | created_subseq = 1; |
313 | } | 315 | } |
314 | dbg("inserting (%u %u %u) from %x:%u into sseq %x(%u,%u) of seq %x\n", | 316 | dbg("inserting {%u,%u,%u} from <0x%x:%u> into sseq %p(%u,%u) of seq %p\n", |
315 | type, lower, upper, node, port, sseq, | 317 | type, lower, upper, node, port, sseq, |
316 | sseq->lower, sseq->upper, nseq); | 318 | sseq->lower, sseq->upper, nseq); |
317 | 319 | ||
@@ -320,7 +322,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
320 | publ = publ_create(type, lower, upper, scope, node, port, key); | 322 | publ = publ_create(type, lower, upper, scope, node, port, key); |
321 | if (!publ) | 323 | if (!publ) |
322 | return NULL; | 324 | return NULL; |
323 | dbg("inserting publ %x, node=%x publ->node=%x, subscr->node=%x\n", | 325 | dbg("inserting publ %p, node=0x%x publ->node=0x%x, subscr->node=%p\n", |
324 | publ, node, publ->node, publ->subscr.node); | 326 | publ, node, publ->node, publ->subscr.node); |
325 | 327 | ||
326 | if (!sseq->zone_list) | 328 | if (!sseq->zone_list) |
@@ -367,45 +369,47 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
367 | 369 | ||
368 | /** | 370 | /** |
369 | * tipc_nameseq_remove_publ - | 371 | * tipc_nameseq_remove_publ - |
372 | * | ||
373 | * NOTE: There may be cases where TIPC is asked to remove a publication | ||
374 | * that is not in the name table. For example, if another node issues a | ||
375 | * publication for a name sequence that overlaps an existing name sequence | ||
376 | * the publication will not be recorded, which means the publication won't | ||
377 | * be found when the name sequence is later withdrawn by that node. | ||
378 | * A failed withdraw request simply returns a failure indication and lets the | ||
379 | * caller issue any error or warning messages associated with such a problem. | ||
370 | */ | 380 | */ |
371 | 381 | ||
372 | static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 inst, | 382 | static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 inst, |
373 | u32 node, u32 ref, u32 key) | 383 | u32 node, u32 ref, u32 key) |
374 | { | 384 | { |
375 | struct publication *publ; | 385 | struct publication *publ; |
386 | struct publication *curr; | ||
376 | struct publication *prev; | 387 | struct publication *prev; |
377 | struct sub_seq *sseq = nameseq_find_subseq(nseq, inst); | 388 | struct sub_seq *sseq = nameseq_find_subseq(nseq, inst); |
378 | struct sub_seq *free; | 389 | struct sub_seq *free; |
379 | struct subscription *s, *st; | 390 | struct subscription *s, *st; |
380 | int removed_subseq = 0; | 391 | int removed_subseq = 0; |
381 | 392 | ||
382 | assert(nseq); | 393 | if (!sseq) |
383 | |||
384 | if (!sseq) { | ||
385 | int i; | ||
386 | |||
387 | warn("Withdraw unknown <%u,%u>?\n", nseq->type, inst); | ||
388 | assert(nseq->sseqs); | ||
389 | dbg("Dumping subseqs %x for %x, alloc = %u,ff=%u\n", | ||
390 | nseq->sseqs, nseq, nseq->alloc, | ||
391 | nseq->first_free); | ||
392 | for (i = 0; i < nseq->first_free; i++) { | ||
393 | dbg("Subseq %u(%x): lower = %u,upper = %u\n", | ||
394 | i, &nseq->sseqs[i], nseq->sseqs[i].lower, | ||
395 | nseq->sseqs[i].upper); | ||
396 | } | ||
397 | return NULL; | 394 | return NULL; |
398 | } | 395 | |
399 | dbg("nameseq_remove: seq: %x, sseq %x, <%u,%u> key %u\n", | 396 | dbg("tipc_nameseq_remove_publ: seq: %p, sseq %p, {%u,%u}, key %u\n", |
400 | nseq, sseq, nseq->type, inst, key); | 397 | nseq, sseq, nseq->type, inst, key); |
401 | 398 | ||
399 | /* Remove publication from zone scope list */ | ||
400 | |||
402 | prev = sseq->zone_list; | 401 | prev = sseq->zone_list; |
403 | publ = sseq->zone_list->zone_list_next; | 402 | publ = sseq->zone_list->zone_list_next; |
404 | while ((publ->key != key) || (publ->ref != ref) || | 403 | while ((publ->key != key) || (publ->ref != ref) || |
405 | (publ->node && (publ->node != node))) { | 404 | (publ->node && (publ->node != node))) { |
406 | prev = publ; | 405 | prev = publ; |
407 | publ = publ->zone_list_next; | 406 | publ = publ->zone_list_next; |
408 | assert(prev != sseq->zone_list); | 407 | if (prev == sseq->zone_list) { |
408 | |||
409 | /* Prevent endless loop if publication not found */ | ||
410 | |||
411 | return NULL; | ||
412 | } | ||
409 | } | 413 | } |
410 | if (publ != sseq->zone_list) | 414 | if (publ != sseq->zone_list) |
411 | prev->zone_list_next = publ->zone_list_next; | 415 | prev->zone_list_next = publ->zone_list_next; |
@@ -416,14 +420,24 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i | |||
416 | sseq->zone_list = NULL; | 420 | sseq->zone_list = NULL; |
417 | } | 421 | } |
418 | 422 | ||
423 | /* Remove publication from cluster scope list, if present */ | ||
424 | |||
419 | if (in_own_cluster(node)) { | 425 | if (in_own_cluster(node)) { |
420 | prev = sseq->cluster_list; | 426 | prev = sseq->cluster_list; |
421 | publ = sseq->cluster_list->cluster_list_next; | 427 | curr = sseq->cluster_list->cluster_list_next; |
422 | while ((publ->key != key) || (publ->ref != ref) || | 428 | while (curr != publ) { |
423 | (publ->node && (publ->node != node))) { | 429 | prev = curr; |
424 | prev = publ; | 430 | curr = curr->cluster_list_next; |
425 | publ = publ->cluster_list_next; | 431 | if (prev == sseq->cluster_list) { |
426 | assert(prev != sseq->cluster_list); | 432 | |
433 | /* Prevent endless loop for malformed list */ | ||
434 | |||
435 | err("Unable to de-list cluster publication\n" | ||
436 | "{%u%u}, node=0x%x, ref=%u, key=%u)\n", | ||
437 | publ->type, publ->lower, publ->node, | ||
438 | publ->ref, publ->key); | ||
439 | goto end_cluster; | ||
440 | } | ||
427 | } | 441 | } |
428 | if (publ != sseq->cluster_list) | 442 | if (publ != sseq->cluster_list) |
429 | prev->cluster_list_next = publ->cluster_list_next; | 443 | prev->cluster_list_next = publ->cluster_list_next; |
@@ -434,15 +448,26 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i | |||
434 | sseq->cluster_list = NULL; | 448 | sseq->cluster_list = NULL; |
435 | } | 449 | } |
436 | } | 450 | } |
451 | end_cluster: | ||
452 | |||
453 | /* Remove publication from node scope list, if present */ | ||
437 | 454 | ||
438 | if (node == tipc_own_addr) { | 455 | if (node == tipc_own_addr) { |
439 | prev = sseq->node_list; | 456 | prev = sseq->node_list; |
440 | publ = sseq->node_list->node_list_next; | 457 | curr = sseq->node_list->node_list_next; |
441 | while ((publ->key != key) || (publ->ref != ref) || | 458 | while (curr != publ) { |
442 | (publ->node && (publ->node != node))) { | 459 | prev = curr; |
443 | prev = publ; | 460 | curr = curr->node_list_next; |
444 | publ = publ->node_list_next; | 461 | if (prev == sseq->node_list) { |
445 | assert(prev != sseq->node_list); | 462 | |
463 | /* Prevent endless loop for malformed list */ | ||
464 | |||
465 | err("Unable to de-list node publication\n" | ||
466 | "{%u%u}, node=0x%x, ref=%u, key=%u)\n", | ||
467 | publ->type, publ->lower, publ->node, | ||
468 | publ->ref, publ->key); | ||
469 | goto end_node; | ||
470 | } | ||
446 | } | 471 | } |
447 | if (publ != sseq->node_list) | 472 | if (publ != sseq->node_list) |
448 | prev->node_list_next = publ->node_list_next; | 473 | prev->node_list_next = publ->node_list_next; |
@@ -453,22 +478,18 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i | |||
453 | sseq->node_list = NULL; | 478 | sseq->node_list = NULL; |
454 | } | 479 | } |
455 | } | 480 | } |
456 | assert(!publ->node || (publ->node == node)); | 481 | end_node: |
457 | assert(publ->ref == ref); | ||
458 | assert(publ->key == key); | ||
459 | 482 | ||
460 | /* | 483 | /* Contract subseq list if no more publications for that subseq */ |
461 | * Contract subseq list if no more publications: | 484 | |
462 | */ | 485 | if (!sseq->zone_list) { |
463 | if (!sseq->node_list && !sseq->cluster_list && !sseq->zone_list) { | ||
464 | free = &nseq->sseqs[nseq->first_free--]; | 486 | free = &nseq->sseqs[nseq->first_free--]; |
465 | memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof (*sseq)); | 487 | memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof (*sseq)); |
466 | removed_subseq = 1; | 488 | removed_subseq = 1; |
467 | } | 489 | } |
468 | 490 | ||
469 | /* | 491 | /* Notify any waiting subscriptions */ |
470 | * Any subscriptions waiting ? | 492 | |
471 | */ | ||
472 | list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) { | 493 | list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) { |
473 | tipc_subscr_report_overlap(s, | 494 | tipc_subscr_report_overlap(s, |
474 | publ->lower, | 495 | publ->lower, |
@@ -478,6 +499,7 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i | |||
478 | publ->node, | 499 | publ->node, |
479 | removed_subseq); | 500 | removed_subseq); |
480 | } | 501 | } |
502 | |||
481 | return publ; | 503 | return publ; |
482 | } | 504 | } |
483 | 505 | ||
@@ -530,7 +552,7 @@ static struct name_seq *nametbl_find_seq(u32 type) | |||
530 | seq_head = &table.types[hash(type)]; | 552 | seq_head = &table.types[hash(type)]; |
531 | hlist_for_each_entry(ns, seq_node, seq_head, ns_list) { | 553 | hlist_for_each_entry(ns, seq_node, seq_head, ns_list) { |
532 | if (ns->type == type) { | 554 | if (ns->type == type) { |
533 | dbg("found %x\n", ns); | 555 | dbg("found %p\n", ns); |
534 | return ns; | 556 | return ns; |
535 | } | 557 | } |
536 | } | 558 | } |
@@ -543,22 +565,21 @@ struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper, | |||
543 | { | 565 | { |
544 | struct name_seq *seq = nametbl_find_seq(type); | 566 | struct name_seq *seq = nametbl_find_seq(type); |
545 | 567 | ||
546 | dbg("ins_publ: <%u,%x,%x> found %x\n", type, lower, upper, seq); | 568 | dbg("tipc_nametbl_insert_publ: {%u,%u,%u} found %p\n", type, lower, upper, seq); |
547 | if (lower > upper) { | 569 | if (lower > upper) { |
548 | warn("Failed to publish illegal <%u,%u,%u>\n", | 570 | warn("Failed to publish illegal {%u,%u,%u}\n", |
549 | type, lower, upper); | 571 | type, lower, upper); |
550 | return NULL; | 572 | return NULL; |
551 | } | 573 | } |
552 | 574 | ||
553 | dbg("Publishing <%u,%u,%u> from %x\n", type, lower, upper, node); | 575 | dbg("Publishing {%u,%u,%u} from 0x%x\n", type, lower, upper, node); |
554 | if (!seq) { | 576 | if (!seq) { |
555 | seq = tipc_nameseq_create(type, &table.types[hash(type)]); | 577 | seq = tipc_nameseq_create(type, &table.types[hash(type)]); |
556 | dbg("tipc_nametbl_insert_publ: created %x\n", seq); | 578 | dbg("tipc_nametbl_insert_publ: created %p\n", seq); |
557 | } | 579 | } |
558 | if (!seq) | 580 | if (!seq) |
559 | return NULL; | 581 | return NULL; |
560 | 582 | ||
561 | assert(seq->type == type); | ||
562 | return tipc_nameseq_insert_publ(seq, type, lower, upper, | 583 | return tipc_nameseq_insert_publ(seq, type, lower, upper, |
563 | scope, node, port, key); | 584 | scope, node, port, key); |
564 | } | 585 | } |
@@ -572,7 +593,7 @@ struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, | |||
572 | if (!seq) | 593 | if (!seq) |
573 | return NULL; | 594 | return NULL; |
574 | 595 | ||
575 | dbg("Withdrawing <%u,%u> from %x\n", type, lower, node); | 596 | dbg("Withdrawing {%u,%u} from 0x%x\n", type, lower, node); |
576 | publ = tipc_nameseq_remove_publ(seq, lower, node, ref, key); | 597 | publ = tipc_nameseq_remove_publ(seq, lower, node, ref, key); |
577 | 598 | ||
578 | if (!seq->first_free && list_empty(&seq->subscriptions)) { | 599 | if (!seq->first_free && list_empty(&seq->subscriptions)) { |
@@ -743,7 +764,7 @@ struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper, | |||
743 | return NULL; | 764 | return NULL; |
744 | } | 765 | } |
745 | if ((type < TIPC_RESERVED_TYPES) && !atomic_read(&rsv_publ_ok)) { | 766 | if ((type < TIPC_RESERVED_TYPES) && !atomic_read(&rsv_publ_ok)) { |
746 | warn("Failed to publish reserved name <%u,%u,%u>\n", | 767 | warn("Publication failed, reserved name {%u,%u,%u}\n", |
747 | type, lower, upper); | 768 | type, lower, upper); |
748 | return NULL; | 769 | return NULL; |
749 | } | 770 | } |
@@ -767,10 +788,10 @@ int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key) | |||
767 | { | 788 | { |
768 | struct publication *publ; | 789 | struct publication *publ; |
769 | 790 | ||
770 | dbg("tipc_nametbl_withdraw:<%d,%d,%d>\n", type, lower, key); | 791 | dbg("tipc_nametbl_withdraw: {%u,%u}, key=%u\n", type, lower, key); |
771 | write_lock_bh(&tipc_nametbl_lock); | 792 | write_lock_bh(&tipc_nametbl_lock); |
772 | publ = tipc_nametbl_remove_publ(type, lower, tipc_own_addr, ref, key); | 793 | publ = tipc_nametbl_remove_publ(type, lower, tipc_own_addr, ref, key); |
773 | if (publ) { | 794 | if (likely(publ)) { |
774 | table.local_publ_count--; | 795 | table.local_publ_count--; |
775 | if (publ->scope != TIPC_NODE_SCOPE) | 796 | if (publ->scope != TIPC_NODE_SCOPE) |
776 | tipc_named_withdraw(publ); | 797 | tipc_named_withdraw(publ); |
@@ -780,6 +801,9 @@ int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key) | |||
780 | return 1; | 801 | return 1; |
781 | } | 802 | } |
782 | write_unlock_bh(&tipc_nametbl_lock); | 803 | write_unlock_bh(&tipc_nametbl_lock); |
804 | err("Unable to remove local publication\n" | ||
805 | "(type=%u, lower=%u, ref=%u, key=%u)\n", | ||
806 | type, lower, ref, key); | ||
783 | return 0; | 807 | return 0; |
784 | } | 808 | } |
785 | 809 | ||
@@ -787,8 +811,7 @@ int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key) | |||
787 | * tipc_nametbl_subscribe - add a subscription object to the name table | 811 | * tipc_nametbl_subscribe - add a subscription object to the name table |
788 | */ | 812 | */ |
789 | 813 | ||
790 | void | 814 | void tipc_nametbl_subscribe(struct subscription *s) |
791 | tipc_nametbl_subscribe(struct subscription *s) | ||
792 | { | 815 | { |
793 | u32 type = s->seq.type; | 816 | u32 type = s->seq.type; |
794 | struct name_seq *seq; | 817 | struct name_seq *seq; |
@@ -800,11 +823,13 @@ tipc_nametbl_subscribe(struct subscription *s) | |||
800 | } | 823 | } |
801 | if (seq){ | 824 | if (seq){ |
802 | spin_lock_bh(&seq->lock); | 825 | spin_lock_bh(&seq->lock); |
803 | dbg("tipc_nametbl_subscribe:found %x for <%u,%u,%u>\n", | 826 | dbg("tipc_nametbl_subscribe:found %p for {%u,%u,%u}\n", |
804 | seq, type, s->seq.lower, s->seq.upper); | 827 | seq, type, s->seq.lower, s->seq.upper); |
805 | assert(seq->type == type); | ||
806 | tipc_nameseq_subscribe(seq, s); | 828 | tipc_nameseq_subscribe(seq, s); |
807 | spin_unlock_bh(&seq->lock); | 829 | spin_unlock_bh(&seq->lock); |
830 | } else { | ||
831 | warn("Failed to create subscription for {%u,%u,%u}\n", | ||
832 | s->seq.type, s->seq.lower, s->seq.upper); | ||
808 | } | 833 | } |
809 | write_unlock_bh(&tipc_nametbl_lock); | 834 | write_unlock_bh(&tipc_nametbl_lock); |
810 | } | 835 | } |
@@ -813,8 +838,7 @@ tipc_nametbl_subscribe(struct subscription *s) | |||
813 | * tipc_nametbl_unsubscribe - remove a subscription object from name table | 838 | * tipc_nametbl_unsubscribe - remove a subscription object from name table |
814 | */ | 839 | */ |
815 | 840 | ||
816 | void | 841 | void tipc_nametbl_unsubscribe(struct subscription *s) |
817 | tipc_nametbl_unsubscribe(struct subscription *s) | ||
818 | { | 842 | { |
819 | struct name_seq *seq; | 843 | struct name_seq *seq; |
820 | 844 | ||
@@ -1049,35 +1073,20 @@ int tipc_nametbl_init(void) | |||
1049 | 1073 | ||
1050 | void tipc_nametbl_stop(void) | 1074 | void tipc_nametbl_stop(void) |
1051 | { | 1075 | { |
1052 | struct hlist_head *seq_head; | ||
1053 | struct hlist_node *seq_node; | ||
1054 | struct hlist_node *tmp; | ||
1055 | struct name_seq *seq; | ||
1056 | u32 i; | 1076 | u32 i; |
1057 | 1077 | ||
1058 | if (!table.types) | 1078 | if (!table.types) |
1059 | return; | 1079 | return; |
1060 | 1080 | ||
1081 | /* Verify name table is empty, then release it */ | ||
1082 | |||
1061 | write_lock_bh(&tipc_nametbl_lock); | 1083 | write_lock_bh(&tipc_nametbl_lock); |
1062 | for (i = 0; i < tipc_nametbl_size; i++) { | 1084 | for (i = 0; i < tipc_nametbl_size; i++) { |
1063 | seq_head = &table.types[i]; | 1085 | if (!hlist_empty(&table.types[i])) |
1064 | hlist_for_each_entry_safe(seq, seq_node, tmp, seq_head, ns_list) { | 1086 | err("tipc_nametbl_stop(): hash chain %u is non-null\n", i); |
1065 | struct sub_seq *sseq = seq->sseqs; | ||
1066 | |||
1067 | for (; sseq != &seq->sseqs[seq->first_free]; sseq++) { | ||
1068 | struct publication *publ = sseq->zone_list; | ||
1069 | assert(publ); | ||
1070 | do { | ||
1071 | struct publication *next = | ||
1072 | publ->zone_list_next; | ||
1073 | kfree(publ); | ||
1074 | publ = next; | ||
1075 | } | ||
1076 | while (publ != sseq->zone_list); | ||
1077 | } | ||
1078 | } | ||
1079 | } | 1087 | } |
1080 | kfree(table.types); | 1088 | kfree(table.types); |
1081 | table.types = NULL; | 1089 | table.types = NULL; |
1082 | write_unlock_bh(&tipc_nametbl_lock); | 1090 | write_unlock_bh(&tipc_nametbl_lock); |
1083 | } | 1091 | } |
1092 | |||
diff --git a/net/tipc/node.c b/net/tipc/node.c index 0d5db06e203f..b54462bd98d7 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -234,7 +234,6 @@ struct node *tipc_node_attach_link(struct link *l_ptr) | |||
234 | u32 bearer_id = l_ptr->b_ptr->identity; | 234 | u32 bearer_id = l_ptr->b_ptr->identity; |
235 | char addr_string[16]; | 235 | char addr_string[16]; |
236 | 236 | ||
237 | assert(bearer_id < MAX_BEARERS); | ||
238 | if (n_ptr->link_cnt >= 2) { | 237 | if (n_ptr->link_cnt >= 2) { |
239 | char addr_string[16]; | 238 | char addr_string[16]; |
240 | 239 | ||
@@ -314,7 +313,7 @@ static void node_established_contact(struct node *n_ptr) | |||
314 | struct cluster *c_ptr; | 313 | struct cluster *c_ptr; |
315 | 314 | ||
316 | dbg("node_established_contact:-> %x\n", n_ptr->addr); | 315 | dbg("node_established_contact:-> %x\n", n_ptr->addr); |
317 | if (!tipc_node_has_active_routes(n_ptr)) { | 316 | if (!tipc_node_has_active_routes(n_ptr) && in_own_cluster(n_ptr->addr)) { |
318 | tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr); | 317 | tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr); |
319 | } | 318 | } |
320 | 319 | ||
diff --git a/net/tipc/node_subscr.c b/net/tipc/node_subscr.c index cff4068cc755..cc3fff3dec4f 100644 --- a/net/tipc/node_subscr.c +++ b/net/tipc/node_subscr.c | |||
@@ -47,18 +47,19 @@ | |||
47 | void tipc_nodesub_subscribe(struct node_subscr *node_sub, u32 addr, | 47 | void tipc_nodesub_subscribe(struct node_subscr *node_sub, u32 addr, |
48 | void *usr_handle, net_ev_handler handle_down) | 48 | void *usr_handle, net_ev_handler handle_down) |
49 | { | 49 | { |
50 | node_sub->node = NULL; | 50 | if (addr == tipc_own_addr) { |
51 | if (addr == tipc_own_addr) | 51 | node_sub->node = NULL; |
52 | return; | 52 | return; |
53 | if (!tipc_addr_node_valid(addr)) { | 53 | } |
54 | warn("node_subscr with illegal %x\n", addr); | 54 | |
55 | node_sub->node = tipc_node_find(addr); | ||
56 | if (!node_sub->node) { | ||
57 | warn("Node subscription rejected, unknown node 0x%x\n", addr); | ||
55 | return; | 58 | return; |
56 | } | 59 | } |
57 | |||
58 | node_sub->handle_node_down = handle_down; | 60 | node_sub->handle_node_down = handle_down; |
59 | node_sub->usr_handle = usr_handle; | 61 | node_sub->usr_handle = usr_handle; |
60 | node_sub->node = tipc_node_find(addr); | 62 | |
61 | assert(node_sub->node); | ||
62 | tipc_node_lock(node_sub->node); | 63 | tipc_node_lock(node_sub->node); |
63 | list_add_tail(&node_sub->nodesub_list, &node_sub->node->nsub); | 64 | list_add_tail(&node_sub->nodesub_list, &node_sub->node->nsub); |
64 | tipc_node_unlock(node_sub->node); | 65 | tipc_node_unlock(node_sub->node); |
diff --git a/net/tipc/port.c b/net/tipc/port.c index 99846a18d94e..3aab67a56649 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c | |||
@@ -168,7 +168,6 @@ void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp) | |||
168 | struct port_list *item = dp; | 168 | struct port_list *item = dp; |
169 | int cnt = 0; | 169 | int cnt = 0; |
170 | 170 | ||
171 | assert(buf); | ||
172 | msg = buf_msg(buf); | 171 | msg = buf_msg(buf); |
173 | 172 | ||
174 | /* Create destination port list, if one wasn't supplied */ | 173 | /* Create destination port list, if one wasn't supplied */ |
diff --git a/net/tipc/ref.c b/net/tipc/ref.c index 33bbf5095094..d2f0cce10e20 100644 --- a/net/tipc/ref.c +++ b/net/tipc/ref.c | |||
@@ -127,7 +127,14 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock) | |||
127 | u32 next_plus_upper; | 127 | u32 next_plus_upper; |
128 | u32 reference = 0; | 128 | u32 reference = 0; |
129 | 129 | ||
130 | assert(tipc_ref_table.entries && object); | 130 | if (!object) { |
131 | err("Attempt to acquire reference to non-existent object\n"); | ||
132 | return 0; | ||
133 | } | ||
134 | if (!tipc_ref_table.entries) { | ||
135 | err("Reference table not found during acquisition attempt\n"); | ||
136 | return 0; | ||
137 | } | ||
131 | 138 | ||
132 | write_lock_bh(&ref_table_lock); | 139 | write_lock_bh(&ref_table_lock); |
133 | if (tipc_ref_table.first_free) { | 140 | if (tipc_ref_table.first_free) { |
@@ -162,15 +169,28 @@ void tipc_ref_discard(u32 ref) | |||
162 | u32 index; | 169 | u32 index; |
163 | u32 index_mask; | 170 | u32 index_mask; |
164 | 171 | ||
165 | assert(tipc_ref_table.entries); | 172 | if (!ref) { |
166 | assert(ref != 0); | 173 | err("Attempt to discard reference 0\n"); |
174 | return; | ||
175 | } | ||
176 | if (!tipc_ref_table.entries) { | ||
177 | err("Reference table not found during discard attempt\n"); | ||
178 | return; | ||
179 | } | ||
167 | 180 | ||
168 | write_lock_bh(&ref_table_lock); | 181 | write_lock_bh(&ref_table_lock); |
169 | index_mask = tipc_ref_table.index_mask; | 182 | index_mask = tipc_ref_table.index_mask; |
170 | index = ref & index_mask; | 183 | index = ref & index_mask; |
171 | entry = &(tipc_ref_table.entries[index]); | 184 | entry = &(tipc_ref_table.entries[index]); |
172 | assert(entry->object != 0); | 185 | |
173 | assert(entry->data.reference == ref); | 186 | if (!entry->object) { |
187 | err("Attempt to discard reference to non-existent object\n"); | ||
188 | goto exit; | ||
189 | } | ||
190 | if (entry->data.reference != ref) { | ||
191 | err("Attempt to discard non-existent reference\n"); | ||
192 | goto exit; | ||
193 | } | ||
174 | 194 | ||
175 | /* mark entry as unused */ | 195 | /* mark entry as unused */ |
176 | entry->object = NULL; | 196 | entry->object = NULL; |
@@ -184,6 +204,7 @@ void tipc_ref_discard(u32 ref) | |||
184 | 204 | ||
185 | /* increment upper bits of entry to invalidate subsequent references */ | 205 | /* increment upper bits of entry to invalidate subsequent references */ |
186 | entry->data.next_plus_upper = (ref & ~index_mask) + (index_mask + 1); | 206 | entry->data.next_plus_upper = (ref & ~index_mask) + (index_mask + 1); |
207 | exit: | ||
187 | write_unlock_bh(&ref_table_lock); | 208 | write_unlock_bh(&ref_table_lock); |
188 | } | 209 | } |
189 | 210 | ||