aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/name_table.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/name_table.c')
-rw-r--r--net/tipc/name_table.c223
1 files changed, 112 insertions, 111 deletions
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index d129422fc5c2..049242ea5c38 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
@@ -101,7 +101,7 @@ struct name_table {
101 101
102static struct name_table table = { NULL } ; 102static struct name_table table = { NULL } ;
103static atomic_t rsv_publ_ok = ATOMIC_INIT(0); 103static atomic_t rsv_publ_ok = ATOMIC_INIT(0);
104rwlock_t tipc_nametbl_lock = RW_LOCK_UNLOCKED; 104DEFINE_RWLOCK(tipc_nametbl_lock);
105 105
106 106
107static int hash(int x) 107static int hash(int x)
@@ -117,14 +117,12 @@ static struct publication *publ_create(u32 type, u32 lower, u32 upper,
117 u32 scope, u32 node, u32 port_ref, 117 u32 scope, u32 node, u32 port_ref,
118 u32 key) 118 u32 key)
119{ 119{
120 struct publication *publ = 120 struct publication *publ = kzalloc(sizeof(*publ), GFP_ATOMIC);
121 (struct publication *)kmalloc(sizeof(*publ), GFP_ATOMIC);
122 if (publ == NULL) { 121 if (publ == NULL) {
123 warn("Memory squeeze; failed to create publication\n"); 122 warn("Publication creation failure, no memory\n");
124 return NULL; 123 return NULL;
125 } 124 }
126 125
127 memset(publ, 0, sizeof(*publ));
128 publ->type = type; 126 publ->type = type;
129 publ->lower = lower; 127 publ->lower = lower;
130 publ->upper = upper; 128 publ->upper = upper;
@@ -144,11 +142,7 @@ static struct publication *publ_create(u32 type, u32 lower, u32 upper,
144 142
145static struct sub_seq *tipc_subseq_alloc(u32 cnt) 143static struct sub_seq *tipc_subseq_alloc(u32 cnt)
146{ 144{
147 u32 sz = cnt * sizeof(struct sub_seq); 145 struct sub_seq *sseq = kcalloc(cnt, sizeof(struct sub_seq), GFP_ATOMIC);
148 struct sub_seq *sseq = (struct sub_seq *)kmalloc(sz, GFP_ATOMIC);
149
150 if (sseq)
151 memset(sseq, 0, sz);
152 return sseq; 146 return sseq;
153} 147}
154 148
@@ -160,22 +154,20 @@ static struct sub_seq *tipc_subseq_alloc(u32 cnt)
160 154
161static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_head) 155static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_head)
162{ 156{
163 struct name_seq *nseq = 157 struct name_seq *nseq = kzalloc(sizeof(*nseq), GFP_ATOMIC);
164 (struct name_seq *)kmalloc(sizeof(*nseq), GFP_ATOMIC);
165 struct sub_seq *sseq = tipc_subseq_alloc(1); 158 struct sub_seq *sseq = tipc_subseq_alloc(1);
166 159
167 if (!nseq || !sseq) { 160 if (!nseq || !sseq) {
168 warn("Memory squeeze; failed to create name sequence\n"); 161 warn("Name sequence creation failed, no memory\n");
169 kfree(nseq); 162 kfree(nseq);
170 kfree(sseq); 163 kfree(sseq);
171 return NULL; 164 return NULL;
172 } 165 }
173 166
174 memset(nseq, 0, sizeof(*nseq)); 167 spin_lock_init(&nseq->lock);
175 nseq->lock = SPIN_LOCK_UNLOCKED;
176 nseq->type = type; 168 nseq->type = type;
177 nseq->sseqs = sseq; 169 nseq->sseqs = sseq;
178 dbg("tipc_nameseq_create() nseq = %x type %u, ssseqs %x, ff: %u\n", 170 dbg("tipc_nameseq_create(): nseq = %p, type %u, ssseqs %p, ff: %u\n",
179 nseq, type, nseq->sseqs, nseq->first_free); 171 nseq, type, nseq->sseqs, nseq->first_free);
180 nseq->alloc = 1; 172 nseq->alloc = 1;
181 INIT_HLIST_NODE(&nseq->ns_list); 173 INIT_HLIST_NODE(&nseq->ns_list);
@@ -253,16 +245,16 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
253 struct sub_seq *sseq; 245 struct sub_seq *sseq;
254 int created_subseq = 0; 246 int created_subseq = 0;
255 247
256 assert(nseq->first_free <= nseq->alloc);
257 sseq = nameseq_find_subseq(nseq, lower); 248 sseq = nameseq_find_subseq(nseq, lower);
258 dbg("nameseq_ins: for seq %x,<%u,%u>, found sseq %x\n", 249 dbg("nameseq_ins: for seq %p, {%u,%u}, found sseq %p\n",
259 nseq, type, lower, sseq); 250 nseq, type, lower, sseq);
260 if (sseq) { 251 if (sseq) {
261 252
262 /* Lower end overlaps existing entry => need an exact match */ 253 /* Lower end overlaps existing entry => need an exact match */
263 254
264 if ((sseq->lower != lower) || (sseq->upper != upper)) { 255 if ((sseq->lower != lower) || (sseq->upper != upper)) {
265 warn("Overlapping publ <%u,%u,%u>\n", type, lower, upper); 256 warn("Cannot publish {%u,%u,%u}, overlap error\n",
257 type, lower, upper);
266 return NULL; 258 return NULL;
267 } 259 }
268 } else { 260 } else {
@@ -277,25 +269,27 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
277 269
278 if ((inspos < nseq->first_free) && 270 if ((inspos < nseq->first_free) &&
279 (upper >= nseq->sseqs[inspos].lower)) { 271 (upper >= nseq->sseqs[inspos].lower)) {
280 warn("Overlapping publ <%u,%u,%u>\n", type, lower, upper); 272 warn("Cannot publish {%u,%u,%u}, overlap error\n",
273 type, lower, upper);
281 return NULL; 274 return NULL;
282 } 275 }
283 276
284 /* Ensure there is space for new sub-sequence */ 277 /* Ensure there is space for new sub-sequence */
285 278
286 if (nseq->first_free == nseq->alloc) { 279 if (nseq->first_free == nseq->alloc) {
287 struct sub_seq *sseqs = nseq->sseqs; 280 struct sub_seq *sseqs = tipc_subseq_alloc(nseq->alloc * 2);
288 nseq->sseqs = tipc_subseq_alloc(nseq->alloc * 2); 281
289 if (nseq->sseqs != NULL) { 282 if (!sseqs) {
290 memcpy(nseq->sseqs, sseqs, 283 warn("Cannot publish {%u,%u,%u}, no memory\n",
291 nseq->alloc * sizeof (struct sub_seq)); 284 type, lower, upper);
292 kfree(sseqs);
293 dbg("Allocated %u sseqs\n", nseq->alloc);
294 nseq->alloc *= 2;
295 } else {
296 warn("Memory squeeze; failed to create sub-sequence\n");
297 return NULL; 285 return NULL;
298 } 286 }
287 dbg("Allocated %u more sseqs\n", nseq->alloc);
288 memcpy(sseqs, nseq->sseqs,
289 nseq->alloc * sizeof(struct sub_seq));
290 kfree(nseq->sseqs);
291 nseq->sseqs = sseqs;
292 nseq->alloc *= 2;
299 } 293 }
300 dbg("Have %u sseqs for type %u\n", nseq->alloc, type); 294 dbg("Have %u sseqs for type %u\n", nseq->alloc, type);
301 295
@@ -311,7 +305,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
311 sseq->upper = upper; 305 sseq->upper = upper;
312 created_subseq = 1; 306 created_subseq = 1;
313 } 307 }
314 dbg("inserting (%u %u %u) from %x:%u into sseq %x(%u,%u) of seq %x\n", 308 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, 309 type, lower, upper, node, port, sseq,
316 sseq->lower, sseq->upper, nseq); 310 sseq->lower, sseq->upper, nseq);
317 311
@@ -320,7 +314,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
320 publ = publ_create(type, lower, upper, scope, node, port, key); 314 publ = publ_create(type, lower, upper, scope, node, port, key);
321 if (!publ) 315 if (!publ)
322 return NULL; 316 return NULL;
323 dbg("inserting publ %x, node=%x publ->node=%x, subscr->node=%x\n", 317 dbg("inserting publ %p, node=0x%x publ->node=0x%x, subscr->node=%p\n",
324 publ, node, publ->node, publ->subscr.node); 318 publ, node, publ->node, publ->subscr.node);
325 319
326 if (!sseq->zone_list) 320 if (!sseq->zone_list)
@@ -367,45 +361,47 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
367 361
368/** 362/**
369 * tipc_nameseq_remove_publ - 363 * tipc_nameseq_remove_publ -
364 *
365 * NOTE: There may be cases where TIPC is asked to remove a publication
366 * that is not in the name table. For example, if another node issues a
367 * publication for a name sequence that overlaps an existing name sequence
368 * the publication will not be recorded, which means the publication won't
369 * be found when the name sequence is later withdrawn by that node.
370 * A failed withdraw request simply returns a failure indication and lets the
371 * caller issue any error or warning messages associated with such a problem.
370 */ 372 */
371 373
372static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 inst, 374static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 inst,
373 u32 node, u32 ref, u32 key) 375 u32 node, u32 ref, u32 key)
374{ 376{
375 struct publication *publ; 377 struct publication *publ;
378 struct publication *curr;
376 struct publication *prev; 379 struct publication *prev;
377 struct sub_seq *sseq = nameseq_find_subseq(nseq, inst); 380 struct sub_seq *sseq = nameseq_find_subseq(nseq, inst);
378 struct sub_seq *free; 381 struct sub_seq *free;
379 struct subscription *s, *st; 382 struct subscription *s, *st;
380 int removed_subseq = 0; 383 int removed_subseq = 0;
381 384
382 assert(nseq); 385 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; 386 return NULL;
398 } 387
399 dbg("nameseq_remove: seq: %x, sseq %x, <%u,%u> key %u\n", 388 dbg("tipc_nameseq_remove_publ: seq: %p, sseq %p, {%u,%u}, key %u\n",
400 nseq, sseq, nseq->type, inst, key); 389 nseq, sseq, nseq->type, inst, key);
401 390
391 /* Remove publication from zone scope list */
392
402 prev = sseq->zone_list; 393 prev = sseq->zone_list;
403 publ = sseq->zone_list->zone_list_next; 394 publ = sseq->zone_list->zone_list_next;
404 while ((publ->key != key) || (publ->ref != ref) || 395 while ((publ->key != key) || (publ->ref != ref) ||
405 (publ->node && (publ->node != node))) { 396 (publ->node && (publ->node != node))) {
406 prev = publ; 397 prev = publ;
407 publ = publ->zone_list_next; 398 publ = publ->zone_list_next;
408 assert(prev != sseq->zone_list); 399 if (prev == sseq->zone_list) {
400
401 /* Prevent endless loop if publication not found */
402
403 return NULL;
404 }
409 } 405 }
410 if (publ != sseq->zone_list) 406 if (publ != sseq->zone_list)
411 prev->zone_list_next = publ->zone_list_next; 407 prev->zone_list_next = publ->zone_list_next;
@@ -416,14 +412,24 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i
416 sseq->zone_list = NULL; 412 sseq->zone_list = NULL;
417 } 413 }
418 414
415 /* Remove publication from cluster scope list, if present */
416
419 if (in_own_cluster(node)) { 417 if (in_own_cluster(node)) {
420 prev = sseq->cluster_list; 418 prev = sseq->cluster_list;
421 publ = sseq->cluster_list->cluster_list_next; 419 curr = sseq->cluster_list->cluster_list_next;
422 while ((publ->key != key) || (publ->ref != ref) || 420 while (curr != publ) {
423 (publ->node && (publ->node != node))) { 421 prev = curr;
424 prev = publ; 422 curr = curr->cluster_list_next;
425 publ = publ->cluster_list_next; 423 if (prev == sseq->cluster_list) {
426 assert(prev != sseq->cluster_list); 424
425 /* Prevent endless loop for malformed list */
426
427 err("Unable to de-list cluster publication\n"
428 "{%u%u}, node=0x%x, ref=%u, key=%u)\n",
429 publ->type, publ->lower, publ->node,
430 publ->ref, publ->key);
431 goto end_cluster;
432 }
427 } 433 }
428 if (publ != sseq->cluster_list) 434 if (publ != sseq->cluster_list)
429 prev->cluster_list_next = publ->cluster_list_next; 435 prev->cluster_list_next = publ->cluster_list_next;
@@ -434,15 +440,26 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i
434 sseq->cluster_list = NULL; 440 sseq->cluster_list = NULL;
435 } 441 }
436 } 442 }
443end_cluster:
444
445 /* Remove publication from node scope list, if present */
437 446
438 if (node == tipc_own_addr) { 447 if (node == tipc_own_addr) {
439 prev = sseq->node_list; 448 prev = sseq->node_list;
440 publ = sseq->node_list->node_list_next; 449 curr = sseq->node_list->node_list_next;
441 while ((publ->key != key) || (publ->ref != ref) || 450 while (curr != publ) {
442 (publ->node && (publ->node != node))) { 451 prev = curr;
443 prev = publ; 452 curr = curr->node_list_next;
444 publ = publ->node_list_next; 453 if (prev == sseq->node_list) {
445 assert(prev != sseq->node_list); 454
455 /* Prevent endless loop for malformed list */
456
457 err("Unable to de-list node publication\n"
458 "{%u%u}, node=0x%x, ref=%u, key=%u)\n",
459 publ->type, publ->lower, publ->node,
460 publ->ref, publ->key);
461 goto end_node;
462 }
446 } 463 }
447 if (publ != sseq->node_list) 464 if (publ != sseq->node_list)
448 prev->node_list_next = publ->node_list_next; 465 prev->node_list_next = publ->node_list_next;
@@ -453,22 +470,18 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i
453 sseq->node_list = NULL; 470 sseq->node_list = NULL;
454 } 471 }
455 } 472 }
456 assert(!publ->node || (publ->node == node)); 473end_node:
457 assert(publ->ref == ref);
458 assert(publ->key == key);
459 474
460 /* 475 /* Contract subseq list if no more publications for that subseq */
461 * Contract subseq list if no more publications: 476
462 */ 477 if (!sseq->zone_list) {
463 if (!sseq->node_list && !sseq->cluster_list && !sseq->zone_list) {
464 free = &nseq->sseqs[nseq->first_free--]; 478 free = &nseq->sseqs[nseq->first_free--];
465 memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof (*sseq)); 479 memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof (*sseq));
466 removed_subseq = 1; 480 removed_subseq = 1;
467 } 481 }
468 482
469 /* 483 /* Notify any waiting subscriptions */
470 * Any subscriptions waiting ? 484
471 */
472 list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) { 485 list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) {
473 tipc_subscr_report_overlap(s, 486 tipc_subscr_report_overlap(s,
474 publ->lower, 487 publ->lower,
@@ -478,6 +491,7 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i
478 publ->node, 491 publ->node,
479 removed_subseq); 492 removed_subseq);
480 } 493 }
494
481 return publ; 495 return publ;
482} 496}
483 497
@@ -530,7 +544,7 @@ static struct name_seq *nametbl_find_seq(u32 type)
530 seq_head = &table.types[hash(type)]; 544 seq_head = &table.types[hash(type)];
531 hlist_for_each_entry(ns, seq_node, seq_head, ns_list) { 545 hlist_for_each_entry(ns, seq_node, seq_head, ns_list) {
532 if (ns->type == type) { 546 if (ns->type == type) {
533 dbg("found %x\n", ns); 547 dbg("found %p\n", ns);
534 return ns; 548 return ns;
535 } 549 }
536 } 550 }
@@ -543,22 +557,21 @@ struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper,
543{ 557{
544 struct name_seq *seq = nametbl_find_seq(type); 558 struct name_seq *seq = nametbl_find_seq(type);
545 559
546 dbg("ins_publ: <%u,%x,%x> found %x\n", type, lower, upper, seq); 560 dbg("tipc_nametbl_insert_publ: {%u,%u,%u} found %p\n", type, lower, upper, seq);
547 if (lower > upper) { 561 if (lower > upper) {
548 warn("Failed to publish illegal <%u,%u,%u>\n", 562 warn("Failed to publish illegal {%u,%u,%u}\n",
549 type, lower, upper); 563 type, lower, upper);
550 return NULL; 564 return NULL;
551 } 565 }
552 566
553 dbg("Publishing <%u,%u,%u> from %x\n", type, lower, upper, node); 567 dbg("Publishing {%u,%u,%u} from 0x%x\n", type, lower, upper, node);
554 if (!seq) { 568 if (!seq) {
555 seq = tipc_nameseq_create(type, &table.types[hash(type)]); 569 seq = tipc_nameseq_create(type, &table.types[hash(type)]);
556 dbg("tipc_nametbl_insert_publ: created %x\n", seq); 570 dbg("tipc_nametbl_insert_publ: created %p\n", seq);
557 } 571 }
558 if (!seq) 572 if (!seq)
559 return NULL; 573 return NULL;
560 574
561 assert(seq->type == type);
562 return tipc_nameseq_insert_publ(seq, type, lower, upper, 575 return tipc_nameseq_insert_publ(seq, type, lower, upper,
563 scope, node, port, key); 576 scope, node, port, key);
564} 577}
@@ -572,7 +585,7 @@ struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower,
572 if (!seq) 585 if (!seq)
573 return NULL; 586 return NULL;
574 587
575 dbg("Withdrawing <%u,%u> from %x\n", type, lower, node); 588 dbg("Withdrawing {%u,%u} from 0x%x\n", type, lower, node);
576 publ = tipc_nameseq_remove_publ(seq, lower, node, ref, key); 589 publ = tipc_nameseq_remove_publ(seq, lower, node, ref, key);
577 590
578 if (!seq->first_free && list_empty(&seq->subscriptions)) { 591 if (!seq->first_free && list_empty(&seq->subscriptions)) {
@@ -738,12 +751,12 @@ struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
738 struct publication *publ; 751 struct publication *publ;
739 752
740 if (table.local_publ_count >= tipc_max_publications) { 753 if (table.local_publ_count >= tipc_max_publications) {
741 warn("Failed publish: max %u local publication\n", 754 warn("Publication failed, local publication limit reached (%u)\n",
742 tipc_max_publications); 755 tipc_max_publications);
743 return NULL; 756 return NULL;
744 } 757 }
745 if ((type < TIPC_RESERVED_TYPES) && !atomic_read(&rsv_publ_ok)) { 758 if ((type < TIPC_RESERVED_TYPES) && !atomic_read(&rsv_publ_ok)) {
746 warn("Failed to publish reserved name <%u,%u,%u>\n", 759 warn("Publication failed, reserved name {%u,%u,%u}\n",
747 type, lower, upper); 760 type, lower, upper);
748 return NULL; 761 return NULL;
749 } 762 }
@@ -767,10 +780,10 @@ int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key)
767{ 780{
768 struct publication *publ; 781 struct publication *publ;
769 782
770 dbg("tipc_nametbl_withdraw:<%d,%d,%d>\n", type, lower, key); 783 dbg("tipc_nametbl_withdraw: {%u,%u}, key=%u\n", type, lower, key);
771 write_lock_bh(&tipc_nametbl_lock); 784 write_lock_bh(&tipc_nametbl_lock);
772 publ = tipc_nametbl_remove_publ(type, lower, tipc_own_addr, ref, key); 785 publ = tipc_nametbl_remove_publ(type, lower, tipc_own_addr, ref, key);
773 if (publ) { 786 if (likely(publ)) {
774 table.local_publ_count--; 787 table.local_publ_count--;
775 if (publ->scope != TIPC_NODE_SCOPE) 788 if (publ->scope != TIPC_NODE_SCOPE)
776 tipc_named_withdraw(publ); 789 tipc_named_withdraw(publ);
@@ -780,6 +793,9 @@ int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key)
780 return 1; 793 return 1;
781 } 794 }
782 write_unlock_bh(&tipc_nametbl_lock); 795 write_unlock_bh(&tipc_nametbl_lock);
796 err("Unable to remove local publication\n"
797 "(type=%u, lower=%u, ref=%u, key=%u)\n",
798 type, lower, ref, key);
783 return 0; 799 return 0;
784} 800}
785 801
@@ -787,8 +803,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 803 * tipc_nametbl_subscribe - add a subscription object to the name table
788 */ 804 */
789 805
790void 806void tipc_nametbl_subscribe(struct subscription *s)
791tipc_nametbl_subscribe(struct subscription *s)
792{ 807{
793 u32 type = s->seq.type; 808 u32 type = s->seq.type;
794 struct name_seq *seq; 809 struct name_seq *seq;
@@ -800,11 +815,13 @@ tipc_nametbl_subscribe(struct subscription *s)
800 } 815 }
801 if (seq){ 816 if (seq){
802 spin_lock_bh(&seq->lock); 817 spin_lock_bh(&seq->lock);
803 dbg("tipc_nametbl_subscribe:found %x for <%u,%u,%u>\n", 818 dbg("tipc_nametbl_subscribe:found %p for {%u,%u,%u}\n",
804 seq, type, s->seq.lower, s->seq.upper); 819 seq, type, s->seq.lower, s->seq.upper);
805 assert(seq->type == type);
806 tipc_nameseq_subscribe(seq, s); 820 tipc_nameseq_subscribe(seq, s);
807 spin_unlock_bh(&seq->lock); 821 spin_unlock_bh(&seq->lock);
822 } else {
823 warn("Failed to create subscription for {%u,%u,%u}\n",
824 s->seq.type, s->seq.lower, s->seq.upper);
808 } 825 }
809 write_unlock_bh(&tipc_nametbl_lock); 826 write_unlock_bh(&tipc_nametbl_lock);
810} 827}
@@ -813,8 +830,7 @@ tipc_nametbl_subscribe(struct subscription *s)
813 * tipc_nametbl_unsubscribe - remove a subscription object from name table 830 * tipc_nametbl_unsubscribe - remove a subscription object from name table
814 */ 831 */
815 832
816void 833void tipc_nametbl_unsubscribe(struct subscription *s)
817tipc_nametbl_unsubscribe(struct subscription *s)
818{ 834{
819 struct name_seq *seq; 835 struct name_seq *seq;
820 836
@@ -1036,7 +1052,7 @@ int tipc_nametbl_init(void)
1036{ 1052{
1037 int array_size = sizeof(struct hlist_head) * tipc_nametbl_size; 1053 int array_size = sizeof(struct hlist_head) * tipc_nametbl_size;
1038 1054
1039 table.types = (struct hlist_head *)kmalloc(array_size, GFP_ATOMIC); 1055 table.types = kmalloc(array_size, GFP_ATOMIC);
1040 if (!table.types) 1056 if (!table.types)
1041 return -ENOMEM; 1057 return -ENOMEM;
1042 1058
@@ -1049,35 +1065,20 @@ int tipc_nametbl_init(void)
1049 1065
1050void tipc_nametbl_stop(void) 1066void tipc_nametbl_stop(void)
1051{ 1067{
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; 1068 u32 i;
1057 1069
1058 if (!table.types) 1070 if (!table.types)
1059 return; 1071 return;
1060 1072
1073 /* Verify name table is empty, then release it */
1074
1061 write_lock_bh(&tipc_nametbl_lock); 1075 write_lock_bh(&tipc_nametbl_lock);
1062 for (i = 0; i < tipc_nametbl_size; i++) { 1076 for (i = 0; i < tipc_nametbl_size; i++) {
1063 seq_head = &table.types[i]; 1077 if (!hlist_empty(&table.types[i]))
1064 hlist_for_each_entry_safe(seq, seq_node, tmp, seq_head, ns_list) { 1078 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 } 1079 }
1080 kfree(table.types); 1080 kfree(table.types);
1081 table.types = NULL; 1081 table.types = NULL;
1082 write_unlock_bh(&tipc_nametbl_lock); 1082 write_unlock_bh(&tipc_nametbl_lock);
1083} 1083}
1084