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.c55
1 files changed, 38 insertions, 17 deletions
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index ac7dfdda7973..cd72e22b132b 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -2,7 +2,7 @@
2 * net/tipc/name_table.c: TIPC name table code 2 * net/tipc/name_table.c: TIPC name table code
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2004-2005, Wind River Systems 5 * Copyright (c) 2004-2008, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -52,9 +52,16 @@ static int tipc_nametbl_size = 1024; /* must be a power of 2 */
52 * struct sub_seq - container for all published instances of a name sequence 52 * struct sub_seq - container for all published instances of a name sequence
53 * @lower: name sequence lower bound 53 * @lower: name sequence lower bound
54 * @upper: name sequence upper bound 54 * @upper: name sequence upper bound
55 * @node_list: circular list of matching publications with >= node scope 55 * @node_list: circular list of publications made by own node
56 * @cluster_list: circular list of matching publications with >= cluster scope 56 * @cluster_list: circular list of publications made by own cluster
57 * @zone_list: circular list of matching publications with >= zone scope 57 * @zone_list: circular list of publications made by own zone
58 * @node_list_size: number of entries in "node_list"
59 * @cluster_list_size: number of entries in "cluster_list"
60 * @zone_list_size: number of entries in "zone_list"
61 *
62 * Note: The zone list always contains at least one entry, since all
63 * publications of the associated name sequence belong to it.
64 * (The cluster and node lists may be empty.)
58 */ 65 */
59 66
60struct sub_seq { 67struct sub_seq {
@@ -63,6 +70,9 @@ struct sub_seq {
63 struct publication *node_list; 70 struct publication *node_list;
64 struct publication *cluster_list; 71 struct publication *cluster_list;
65 struct publication *zone_list; 72 struct publication *zone_list;
73 u32 node_list_size;
74 u32 cluster_list_size;
75 u32 zone_list_size;
66}; 76};
67 77
68/** 78/**
@@ -74,7 +84,7 @@ struct sub_seq {
74 * @first_free: array index of first unused sub-sequence entry 84 * @first_free: array index of first unused sub-sequence entry
75 * @ns_list: links to adjacent name sequences in hash chain 85 * @ns_list: links to adjacent name sequences in hash chain
76 * @subscriptions: list of subscriptions for this 'type' 86 * @subscriptions: list of subscriptions for this 'type'
77 * @lock: spinlock controlling access to name sequence structure 87 * @lock: spinlock controlling access to publication lists of all sub-sequences
78 */ 88 */
79 89
80struct name_seq { 90struct name_seq {
@@ -317,6 +327,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
317 dbg("inserting publ %p, node=0x%x publ->node=0x%x, subscr->node=%p\n", 327 dbg("inserting publ %p, node=0x%x publ->node=0x%x, subscr->node=%p\n",
318 publ, node, publ->node, publ->subscr.node); 328 publ, node, publ->node, publ->subscr.node);
319 329
330 sseq->zone_list_size++;
320 if (!sseq->zone_list) 331 if (!sseq->zone_list)
321 sseq->zone_list = publ->zone_list_next = publ; 332 sseq->zone_list = publ->zone_list_next = publ;
322 else { 333 else {
@@ -325,6 +336,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
325 } 336 }
326 337
327 if (in_own_cluster(node)) { 338 if (in_own_cluster(node)) {
339 sseq->cluster_list_size++;
328 if (!sseq->cluster_list) 340 if (!sseq->cluster_list)
329 sseq->cluster_list = publ->cluster_list_next = publ; 341 sseq->cluster_list = publ->cluster_list_next = publ;
330 else { 342 else {
@@ -335,6 +347,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
335 } 347 }
336 348
337 if (node == tipc_own_addr) { 349 if (node == tipc_own_addr) {
350 sseq->node_list_size++;
338 if (!sseq->node_list) 351 if (!sseq->node_list)
339 sseq->node_list = publ->node_list_next = publ; 352 sseq->node_list = publ->node_list_next = publ;
340 else { 353 else {
@@ -411,6 +424,7 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i
411 } else { 424 } else {
412 sseq->zone_list = NULL; 425 sseq->zone_list = NULL;
413 } 426 }
427 sseq->zone_list_size--;
414 428
415 /* Remove publication from cluster scope list, if present */ 429 /* Remove publication from cluster scope list, if present */
416 430
@@ -439,6 +453,7 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i
439 } else { 453 } else {
440 sseq->cluster_list = NULL; 454 sseq->cluster_list = NULL;
441 } 455 }
456 sseq->cluster_list_size--;
442 } 457 }
443end_cluster: 458end_cluster:
444 459
@@ -469,6 +484,7 @@ end_cluster:
469 } else { 484 } else {
470 sseq->node_list = NULL; 485 sseq->node_list = NULL;
471 } 486 }
487 sseq->node_list_size--;
472 } 488 }
473end_node: 489end_node:
474 490
@@ -709,15 +725,18 @@ int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit,
709 725
710 if (sseq->lower > upper) 726 if (sseq->lower > upper)
711 break; 727 break;
712 publ = sseq->cluster_list; 728
713 if (publ && (publ->scope <= limit)) 729 publ = sseq->node_list;
730 if (publ) {
714 do { 731 do {
715 if (publ->node == tipc_own_addr) 732 if (publ->scope <= limit)
716 tipc_port_list_add(dports, publ->ref); 733 tipc_port_list_add(dports, publ->ref);
717 else 734 publ = publ->node_list_next;
718 res = 1; 735 } while (publ != sseq->node_list);
719 publ = publ->cluster_list_next; 736 }
720 } while (publ != sseq->cluster_list); 737
738 if (sseq->cluster_list_size != sseq->node_list_size)
739 res = 1;
721 } 740 }
722 741
723 spin_unlock_bh(&seq->lock); 742 spin_unlock_bh(&seq->lock);
@@ -905,6 +924,9 @@ static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth,
905 struct sub_seq *sseq; 924 struct sub_seq *sseq;
906 char typearea[11]; 925 char typearea[11];
907 926
927 if (seq->first_free == 0)
928 return;
929
908 sprintf(typearea, "%-10u", seq->type); 930 sprintf(typearea, "%-10u", seq->type);
909 931
910 if (depth == 1) { 932 if (depth == 1) {
@@ -915,7 +937,9 @@ static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth,
915 for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) { 937 for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) {
916 if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) { 938 if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) {
917 tipc_printf(buf, "%s ", typearea); 939 tipc_printf(buf, "%s ", typearea);
940 spin_lock_bh(&seq->lock);
918 subseq_list(sseq, buf, depth, index); 941 subseq_list(sseq, buf, depth, index);
942 spin_unlock_bh(&seq->lock);
919 sprintf(typearea, "%10s", " "); 943 sprintf(typearea, "%10s", " ");
920 } 944 }
921 } 945 }
@@ -1050,15 +1074,12 @@ void tipc_nametbl_dump(void)
1050 1074
1051int tipc_nametbl_init(void) 1075int tipc_nametbl_init(void)
1052{ 1076{
1053 int array_size = sizeof(struct hlist_head) * tipc_nametbl_size; 1077 table.types = kcalloc(tipc_nametbl_size, sizeof(struct hlist_head),
1054 1078 GFP_ATOMIC);
1055 table.types = kzalloc(array_size, GFP_ATOMIC);
1056 if (!table.types) 1079 if (!table.types)
1057 return -ENOMEM; 1080 return -ENOMEM;
1058 1081
1059 write_lock_bh(&tipc_nametbl_lock);
1060 table.local_publ_count = 0; 1082 table.local_publ_count = 0;
1061 write_unlock_bh(&tipc_nametbl_lock);
1062 return 0; 1083 return 0;
1063} 1084}
1064 1085