diff options
Diffstat (limited to 'net/tipc/name_table.c')
-rw-r--r-- | net/tipc/name_table.c | 55 |
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 | ||
60 | struct sub_seq { | 67 | struct 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 | ||
80 | struct name_seq { | 90 | struct 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 | } |
443 | end_cluster: | 458 | end_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 | } |
473 | end_node: | 489 | end_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 | ||
1051 | int tipc_nametbl_init(void) | 1075 | int 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 | ||