diff options
Diffstat (limited to 'net/tipc/name_table.c')
-rw-r--r-- | net/tipc/name_table.c | 150 |
1 files changed, 89 insertions, 61 deletions
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 205ed4a4e186..9cd58f8318f1 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c | |||
@@ -44,9 +44,7 @@ | |||
44 | static int tipc_nametbl_size = 1024; /* must be a power of 2 */ | 44 | static int tipc_nametbl_size = 1024; /* must be a power of 2 */ |
45 | 45 | ||
46 | /** | 46 | /** |
47 | * struct sub_seq - container for all published instances of a name sequence | 47 | * struct name_info - name sequence publication info |
48 | * @lower: name sequence lower bound | ||
49 | * @upper: name sequence upper bound | ||
50 | * @node_list: circular list of publications made by own node | 48 | * @node_list: circular list of publications made by own node |
51 | * @cluster_list: circular list of publications made by own cluster | 49 | * @cluster_list: circular list of publications made by own cluster |
52 | * @zone_list: circular list of publications made by own zone | 50 | * @zone_list: circular list of publications made by own zone |
@@ -59,9 +57,7 @@ static int tipc_nametbl_size = 1024; /* must be a power of 2 */ | |||
59 | * (The cluster and node lists may be empty.) | 57 | * (The cluster and node lists may be empty.) |
60 | */ | 58 | */ |
61 | 59 | ||
62 | struct sub_seq { | 60 | struct name_info { |
63 | u32 lower; | ||
64 | u32 upper; | ||
65 | struct publication *node_list; | 61 | struct publication *node_list; |
66 | struct publication *cluster_list; | 62 | struct publication *cluster_list; |
67 | struct publication *zone_list; | 63 | struct publication *zone_list; |
@@ -71,6 +67,19 @@ struct sub_seq { | |||
71 | }; | 67 | }; |
72 | 68 | ||
73 | /** | 69 | /** |
70 | * struct sub_seq - container for all published instances of a name sequence | ||
71 | * @lower: name sequence lower bound | ||
72 | * @upper: name sequence upper bound | ||
73 | * @info: pointer to name sequence publication info | ||
74 | */ | ||
75 | |||
76 | struct sub_seq { | ||
77 | u32 lower; | ||
78 | u32 upper; | ||
79 | struct name_info *info; | ||
80 | }; | ||
81 | |||
82 | /** | ||
74 | * struct name_seq - container for all published instances of a name type | 83 | * struct name_seq - container for all published instances of a name type |
75 | * @type: 32 bit 'type' value for name sequence | 84 | * @type: 32 bit 'type' value for name sequence |
76 | * @sseq: pointer to dynamically-sized array of sub-sequences of this 'type'; | 85 | * @sseq: pointer to dynamically-sized array of sub-sequences of this 'type'; |
@@ -246,6 +255,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
246 | struct subscription *st; | 255 | struct subscription *st; |
247 | struct publication *publ; | 256 | struct publication *publ; |
248 | struct sub_seq *sseq; | 257 | struct sub_seq *sseq; |
258 | struct name_info *info; | ||
249 | int created_subseq = 0; | 259 | int created_subseq = 0; |
250 | 260 | ||
251 | sseq = nameseq_find_subseq(nseq, lower); | 261 | sseq = nameseq_find_subseq(nseq, lower); |
@@ -258,6 +268,8 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
258 | type, lower, upper); | 268 | type, lower, upper); |
259 | return NULL; | 269 | return NULL; |
260 | } | 270 | } |
271 | |||
272 | info = sseq->info; | ||
261 | } else { | 273 | } else { |
262 | u32 inspos; | 274 | u32 inspos; |
263 | struct sub_seq *freesseq; | 275 | struct sub_seq *freesseq; |
@@ -292,6 +304,13 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
292 | nseq->alloc *= 2; | 304 | nseq->alloc *= 2; |
293 | } | 305 | } |
294 | 306 | ||
307 | info = kzalloc(sizeof(*info), GFP_ATOMIC); | ||
308 | if (!info) { | ||
309 | warn("Cannot publish {%u,%u,%u}, no memory\n", | ||
310 | type, lower, upper); | ||
311 | return NULL; | ||
312 | } | ||
313 | |||
295 | /* Insert new sub-sequence */ | 314 | /* Insert new sub-sequence */ |
296 | 315 | ||
297 | sseq = &nseq->sseqs[inspos]; | 316 | sseq = &nseq->sseqs[inspos]; |
@@ -301,6 +320,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
301 | nseq->first_free++; | 320 | nseq->first_free++; |
302 | sseq->lower = lower; | 321 | sseq->lower = lower; |
303 | sseq->upper = upper; | 322 | sseq->upper = upper; |
323 | sseq->info = info; | ||
304 | created_subseq = 1; | 324 | created_subseq = 1; |
305 | } | 325 | } |
306 | 326 | ||
@@ -310,32 +330,32 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
310 | if (!publ) | 330 | if (!publ) |
311 | return NULL; | 331 | return NULL; |
312 | 332 | ||
313 | sseq->zone_list_size++; | 333 | info->zone_list_size++; |
314 | if (!sseq->zone_list) | 334 | if (!info->zone_list) |
315 | sseq->zone_list = publ->zone_list_next = publ; | 335 | info->zone_list = publ->zone_list_next = publ; |
316 | else { | 336 | else { |
317 | publ->zone_list_next = sseq->zone_list->zone_list_next; | 337 | publ->zone_list_next = info->zone_list->zone_list_next; |
318 | sseq->zone_list->zone_list_next = publ; | 338 | info->zone_list->zone_list_next = publ; |
319 | } | 339 | } |
320 | 340 | ||
321 | if (in_own_cluster(node)) { | 341 | if (in_own_cluster(node)) { |
322 | sseq->cluster_list_size++; | 342 | info->cluster_list_size++; |
323 | if (!sseq->cluster_list) | 343 | if (!info->cluster_list) |
324 | sseq->cluster_list = publ->cluster_list_next = publ; | 344 | info->cluster_list = publ->cluster_list_next = publ; |
325 | else { | 345 | else { |
326 | publ->cluster_list_next = | 346 | publ->cluster_list_next = |
327 | sseq->cluster_list->cluster_list_next; | 347 | info->cluster_list->cluster_list_next; |
328 | sseq->cluster_list->cluster_list_next = publ; | 348 | info->cluster_list->cluster_list_next = publ; |
329 | } | 349 | } |
330 | } | 350 | } |
331 | 351 | ||
332 | if (node == tipc_own_addr) { | 352 | if (node == tipc_own_addr) { |
333 | sseq->node_list_size++; | 353 | info->node_list_size++; |
334 | if (!sseq->node_list) | 354 | if (!info->node_list) |
335 | sseq->node_list = publ->node_list_next = publ; | 355 | info->node_list = publ->node_list_next = publ; |
336 | else { | 356 | else { |
337 | publ->node_list_next = sseq->node_list->node_list_next; | 357 | publ->node_list_next = info->node_list->node_list_next; |
338 | sseq->node_list->node_list_next = publ; | 358 | info->node_list->node_list_next = publ; |
339 | } | 359 | } |
340 | } | 360 | } |
341 | 361 | ||
@@ -373,6 +393,7 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i | |||
373 | struct publication *curr; | 393 | struct publication *curr; |
374 | struct publication *prev; | 394 | struct publication *prev; |
375 | struct sub_seq *sseq = nameseq_find_subseq(nseq, inst); | 395 | struct sub_seq *sseq = nameseq_find_subseq(nseq, inst); |
396 | struct name_info *info; | ||
376 | struct sub_seq *free; | 397 | struct sub_seq *free; |
377 | struct subscription *s, *st; | 398 | struct subscription *s, *st; |
378 | int removed_subseq = 0; | 399 | int removed_subseq = 0; |
@@ -380,40 +401,42 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i | |||
380 | if (!sseq) | 401 | if (!sseq) |
381 | return NULL; | 402 | return NULL; |
382 | 403 | ||
404 | info = sseq->info; | ||
405 | |||
383 | /* Remove publication from zone scope list */ | 406 | /* Remove publication from zone scope list */ |
384 | 407 | ||
385 | prev = sseq->zone_list; | 408 | prev = info->zone_list; |
386 | publ = sseq->zone_list->zone_list_next; | 409 | publ = info->zone_list->zone_list_next; |
387 | while ((publ->key != key) || (publ->ref != ref) || | 410 | while ((publ->key != key) || (publ->ref != ref) || |
388 | (publ->node && (publ->node != node))) { | 411 | (publ->node && (publ->node != node))) { |
389 | prev = publ; | 412 | prev = publ; |
390 | publ = publ->zone_list_next; | 413 | publ = publ->zone_list_next; |
391 | if (prev == sseq->zone_list) { | 414 | if (prev == info->zone_list) { |
392 | 415 | ||
393 | /* Prevent endless loop if publication not found */ | 416 | /* Prevent endless loop if publication not found */ |
394 | 417 | ||
395 | return NULL; | 418 | return NULL; |
396 | } | 419 | } |
397 | } | 420 | } |
398 | if (publ != sseq->zone_list) | 421 | if (publ != info->zone_list) |
399 | prev->zone_list_next = publ->zone_list_next; | 422 | prev->zone_list_next = publ->zone_list_next; |
400 | else if (publ->zone_list_next != publ) { | 423 | else if (publ->zone_list_next != publ) { |
401 | prev->zone_list_next = publ->zone_list_next; | 424 | prev->zone_list_next = publ->zone_list_next; |
402 | sseq->zone_list = publ->zone_list_next; | 425 | info->zone_list = publ->zone_list_next; |
403 | } else { | 426 | } else { |
404 | sseq->zone_list = NULL; | 427 | info->zone_list = NULL; |
405 | } | 428 | } |
406 | sseq->zone_list_size--; | 429 | info->zone_list_size--; |
407 | 430 | ||
408 | /* Remove publication from cluster scope list, if present */ | 431 | /* Remove publication from cluster scope list, if present */ |
409 | 432 | ||
410 | if (in_own_cluster(node)) { | 433 | if (in_own_cluster(node)) { |
411 | prev = sseq->cluster_list; | 434 | prev = info->cluster_list; |
412 | curr = sseq->cluster_list->cluster_list_next; | 435 | curr = info->cluster_list->cluster_list_next; |
413 | while (curr != publ) { | 436 | while (curr != publ) { |
414 | prev = curr; | 437 | prev = curr; |
415 | curr = curr->cluster_list_next; | 438 | curr = curr->cluster_list_next; |
416 | if (prev == sseq->cluster_list) { | 439 | if (prev == info->cluster_list) { |
417 | 440 | ||
418 | /* Prevent endless loop for malformed list */ | 441 | /* Prevent endless loop for malformed list */ |
419 | 442 | ||
@@ -424,27 +447,27 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i | |||
424 | goto end_cluster; | 447 | goto end_cluster; |
425 | } | 448 | } |
426 | } | 449 | } |
427 | if (publ != sseq->cluster_list) | 450 | if (publ != info->cluster_list) |
428 | prev->cluster_list_next = publ->cluster_list_next; | 451 | prev->cluster_list_next = publ->cluster_list_next; |
429 | else if (publ->cluster_list_next != publ) { | 452 | else if (publ->cluster_list_next != publ) { |
430 | prev->cluster_list_next = publ->cluster_list_next; | 453 | prev->cluster_list_next = publ->cluster_list_next; |
431 | sseq->cluster_list = publ->cluster_list_next; | 454 | info->cluster_list = publ->cluster_list_next; |
432 | } else { | 455 | } else { |
433 | sseq->cluster_list = NULL; | 456 | info->cluster_list = NULL; |
434 | } | 457 | } |
435 | sseq->cluster_list_size--; | 458 | info->cluster_list_size--; |
436 | } | 459 | } |
437 | end_cluster: | 460 | end_cluster: |
438 | 461 | ||
439 | /* Remove publication from node scope list, if present */ | 462 | /* Remove publication from node scope list, if present */ |
440 | 463 | ||
441 | if (node == tipc_own_addr) { | 464 | if (node == tipc_own_addr) { |
442 | prev = sseq->node_list; | 465 | prev = info->node_list; |
443 | curr = sseq->node_list->node_list_next; | 466 | curr = info->node_list->node_list_next; |
444 | while (curr != publ) { | 467 | while (curr != publ) { |
445 | prev = curr; | 468 | prev = curr; |
446 | curr = curr->node_list_next; | 469 | curr = curr->node_list_next; |
447 | if (prev == sseq->node_list) { | 470 | if (prev == info->node_list) { |
448 | 471 | ||
449 | /* Prevent endless loop for malformed list */ | 472 | /* Prevent endless loop for malformed list */ |
450 | 473 | ||
@@ -455,21 +478,22 @@ end_cluster: | |||
455 | goto end_node; | 478 | goto end_node; |
456 | } | 479 | } |
457 | } | 480 | } |
458 | if (publ != sseq->node_list) | 481 | if (publ != info->node_list) |
459 | prev->node_list_next = publ->node_list_next; | 482 | prev->node_list_next = publ->node_list_next; |
460 | else if (publ->node_list_next != publ) { | 483 | else if (publ->node_list_next != publ) { |
461 | prev->node_list_next = publ->node_list_next; | 484 | prev->node_list_next = publ->node_list_next; |
462 | sseq->node_list = publ->node_list_next; | 485 | info->node_list = publ->node_list_next; |
463 | } else { | 486 | } else { |
464 | sseq->node_list = NULL; | 487 | info->node_list = NULL; |
465 | } | 488 | } |
466 | sseq->node_list_size--; | 489 | info->node_list_size--; |
467 | } | 490 | } |
468 | end_node: | 491 | end_node: |
469 | 492 | ||
470 | /* Contract subseq list if no more publications for that subseq */ | 493 | /* Contract subseq list if no more publications for that subseq */ |
471 | 494 | ||
472 | if (!sseq->zone_list) { | 495 | if (!info->zone_list) { |
496 | kfree(info); | ||
473 | free = &nseq->sseqs[nseq->first_free--]; | 497 | free = &nseq->sseqs[nseq->first_free--]; |
474 | memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof(*sseq)); | 498 | memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof(*sseq)); |
475 | removed_subseq = 1; | 499 | removed_subseq = 1; |
@@ -506,7 +530,7 @@ static void tipc_nameseq_subscribe(struct name_seq *nseq, struct subscription *s | |||
506 | return; | 530 | return; |
507 | 531 | ||
508 | while (sseq != &nseq->sseqs[nseq->first_free]) { | 532 | while (sseq != &nseq->sseqs[nseq->first_free]) { |
509 | struct publication *zl = sseq->zone_list; | 533 | struct publication *zl = sseq->info->zone_list; |
510 | if (zl && tipc_subscr_overlap(s, sseq->lower, sseq->upper)) { | 534 | if (zl && tipc_subscr_overlap(s, sseq->lower, sseq->upper)) { |
511 | struct publication *crs = zl; | 535 | struct publication *crs = zl; |
512 | int must_report = 1; | 536 | int must_report = 1; |
@@ -591,6 +615,7 @@ struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, | |||
591 | u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode) | 615 | u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode) |
592 | { | 616 | { |
593 | struct sub_seq *sseq; | 617 | struct sub_seq *sseq; |
618 | struct name_info *info; | ||
594 | struct publication *publ = NULL; | 619 | struct publication *publ = NULL; |
595 | struct name_seq *seq; | 620 | struct name_seq *seq; |
596 | u32 ref; | 621 | u32 ref; |
@@ -606,12 +631,13 @@ u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode) | |||
606 | if (unlikely(!sseq)) | 631 | if (unlikely(!sseq)) |
607 | goto not_found; | 632 | goto not_found; |
608 | spin_lock_bh(&seq->lock); | 633 | spin_lock_bh(&seq->lock); |
634 | info = sseq->info; | ||
609 | 635 | ||
610 | /* Closest-First Algorithm: */ | 636 | /* Closest-First Algorithm: */ |
611 | if (likely(!*destnode)) { | 637 | if (likely(!*destnode)) { |
612 | publ = sseq->node_list; | 638 | publ = info->node_list; |
613 | if (publ) { | 639 | if (publ) { |
614 | sseq->node_list = publ->node_list_next; | 640 | info->node_list = publ->node_list_next; |
615 | found: | 641 | found: |
616 | ref = publ->ref; | 642 | ref = publ->ref; |
617 | *destnode = publ->node; | 643 | *destnode = publ->node; |
@@ -619,35 +645,35 @@ found: | |||
619 | read_unlock_bh(&tipc_nametbl_lock); | 645 | read_unlock_bh(&tipc_nametbl_lock); |
620 | return ref; | 646 | return ref; |
621 | } | 647 | } |
622 | publ = sseq->cluster_list; | 648 | publ = info->cluster_list; |
623 | if (publ) { | 649 | if (publ) { |
624 | sseq->cluster_list = publ->cluster_list_next; | 650 | info->cluster_list = publ->cluster_list_next; |
625 | goto found; | 651 | goto found; |
626 | } | 652 | } |
627 | publ = sseq->zone_list; | 653 | publ = info->zone_list; |
628 | if (publ) { | 654 | if (publ) { |
629 | sseq->zone_list = publ->zone_list_next; | 655 | info->zone_list = publ->zone_list_next; |
630 | goto found; | 656 | goto found; |
631 | } | 657 | } |
632 | } | 658 | } |
633 | 659 | ||
634 | /* Round-Robin Algorithm: */ | 660 | /* Round-Robin Algorithm: */ |
635 | else if (*destnode == tipc_own_addr) { | 661 | else if (*destnode == tipc_own_addr) { |
636 | publ = sseq->node_list; | 662 | publ = info->node_list; |
637 | if (publ) { | 663 | if (publ) { |
638 | sseq->node_list = publ->node_list_next; | 664 | info->node_list = publ->node_list_next; |
639 | goto found; | 665 | goto found; |
640 | } | 666 | } |
641 | } else if (in_own_cluster(*destnode)) { | 667 | } else if (in_own_cluster(*destnode)) { |
642 | publ = sseq->cluster_list; | 668 | publ = info->cluster_list; |
643 | if (publ) { | 669 | if (publ) { |
644 | sseq->cluster_list = publ->cluster_list_next; | 670 | info->cluster_list = publ->cluster_list_next; |
645 | goto found; | 671 | goto found; |
646 | } | 672 | } |
647 | } else { | 673 | } else { |
648 | publ = sseq->zone_list; | 674 | publ = info->zone_list; |
649 | if (publ) { | 675 | if (publ) { |
650 | sseq->zone_list = publ->zone_list_next; | 676 | info->zone_list = publ->zone_list_next; |
651 | goto found; | 677 | goto found; |
652 | } | 678 | } |
653 | } | 679 | } |
@@ -676,6 +702,7 @@ int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit, | |||
676 | struct name_seq *seq; | 702 | struct name_seq *seq; |
677 | struct sub_seq *sseq; | 703 | struct sub_seq *sseq; |
678 | struct sub_seq *sseq_stop; | 704 | struct sub_seq *sseq_stop; |
705 | struct name_info *info; | ||
679 | int res = 0; | 706 | int res = 0; |
680 | 707 | ||
681 | read_lock_bh(&tipc_nametbl_lock); | 708 | read_lock_bh(&tipc_nametbl_lock); |
@@ -693,16 +720,17 @@ int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit, | |||
693 | if (sseq->lower > upper) | 720 | if (sseq->lower > upper) |
694 | break; | 721 | break; |
695 | 722 | ||
696 | publ = sseq->node_list; | 723 | info = sseq->info; |
724 | publ = info->node_list; | ||
697 | if (publ) { | 725 | if (publ) { |
698 | do { | 726 | do { |
699 | if (publ->scope <= limit) | 727 | if (publ->scope <= limit) |
700 | tipc_port_list_add(dports, publ->ref); | 728 | tipc_port_list_add(dports, publ->ref); |
701 | publ = publ->node_list_next; | 729 | publ = publ->node_list_next; |
702 | } while (publ != sseq->node_list); | 730 | } while (publ != info->node_list); |
703 | } | 731 | } |
704 | 732 | ||
705 | if (sseq->cluster_list_size != sseq->node_list_size) | 733 | if (info->cluster_list_size != info->node_list_size) |
706 | res = 1; | 734 | res = 1; |
707 | } | 735 | } |
708 | 736 | ||
@@ -840,7 +868,7 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, | |||
840 | { | 868 | { |
841 | char portIdStr[27]; | 869 | char portIdStr[27]; |
842 | const char *scope_str[] = {"", " zone", " cluster", " node"}; | 870 | const char *scope_str[] = {"", " zone", " cluster", " node"}; |
843 | struct publication *publ = sseq->zone_list; | 871 | struct publication *publ = sseq->info->zone_list; |
844 | 872 | ||
845 | tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper); | 873 | tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper); |
846 | 874 | ||
@@ -860,7 +888,7 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, | |||
860 | } | 888 | } |
861 | 889 | ||
862 | publ = publ->zone_list_next; | 890 | publ = publ->zone_list_next; |
863 | if (publ == sseq->zone_list) | 891 | if (publ == sseq->info->zone_list) |
864 | break; | 892 | break; |
865 | 893 | ||
866 | tipc_printf(buf, "\n%33s", " "); | 894 | tipc_printf(buf, "\n%33s", " "); |