X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=net%2Ftipc%2Fname_table.c;h=892373e498e4865026b50fb9830ca51d7a7584fb;hb=5b06c85c3b96fa8db632f1ee94f99a2bd0215f3a;hp=e90dc80cd74a0ae8920c7138a475ab4eb7d19233;hpb=f131072c3da84e70a0f65d71b3a3f6611c6a22bc;p=safe%2Fjmp%2Flinux-2.6 diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index e90dc80..892373e 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -1,6 +1,6 @@ /* * net/tipc/name_table.c: TIPC name table code - * + * * Copyright (c) 2000-2006, Ericsson AB * Copyright (c) 2004-2005, Wind River Systems * All rights reserved. @@ -65,7 +65,7 @@ struct sub_seq { struct publication *zone_list; }; -/** +/** * struct name_seq - container for all published instances of a name type * @type: 32 bit 'type' value for name sequence * @sseq: pointer to dynamically-sized array of sub-sequences of this 'type'; @@ -89,7 +89,7 @@ struct name_seq { /** * struct name_table - table containing all existing port name publications - * @types: pointer to fixed-sized array of name sequence lists, + * @types: pointer to fixed-sized array of name sequence lists, * accessed via hashing on 'type'; name sequence lists are *not* sorted * @local_publ_count: number of publications issued by this node */ @@ -101,7 +101,7 @@ struct name_table { static struct name_table table = { NULL } ; static atomic_t rsv_publ_ok = ATOMIC_INIT(0); -rwlock_t tipc_nametbl_lock = RW_LOCK_UNLOCKED; +DEFINE_RWLOCK(tipc_nametbl_lock); static int hash(int x) @@ -113,18 +113,16 @@ static int hash(int x) * publ_create - create a publication structure */ -static struct publication *publ_create(u32 type, u32 lower, u32 upper, - u32 scope, u32 node, u32 port_ref, +static struct publication *publ_create(u32 type, u32 lower, u32 upper, + u32 scope, u32 node, u32 port_ref, u32 key) { - struct publication *publ = - (struct publication *)kmalloc(sizeof(*publ), GFP_ATOMIC); + struct publication *publ = kzalloc(sizeof(*publ), GFP_ATOMIC); if (publ == NULL) { - warn("Memory squeeze; failed to create publication\n"); + warn("Publication creation failure, no memory\n"); return NULL; } - memset(publ, 0, sizeof(*publ)); publ->type = type; publ->lower = lower; publ->upper = upper; @@ -144,35 +142,29 @@ static struct publication *publ_create(u32 type, u32 lower, u32 upper, static struct sub_seq *tipc_subseq_alloc(u32 cnt) { - u32 sz = cnt * sizeof(struct sub_seq); - struct sub_seq *sseq = (struct sub_seq *)kmalloc(sz, GFP_ATOMIC); - - if (sseq) - memset(sseq, 0, sz); + struct sub_seq *sseq = kcalloc(cnt, sizeof(struct sub_seq), GFP_ATOMIC); return sseq; } /** * tipc_nameseq_create - create a name sequence structure for the specified 'type' - * + * * Allocates a single sub-sequence structure and sets it to all 0's. */ static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_head) { - struct name_seq *nseq = - (struct name_seq *)kmalloc(sizeof(*nseq), GFP_ATOMIC); + struct name_seq *nseq = kzalloc(sizeof(*nseq), GFP_ATOMIC); struct sub_seq *sseq = tipc_subseq_alloc(1); if (!nseq || !sseq) { - warn("Memory squeeze; failed to create name sequence\n"); + warn("Name sequence creation failed, no memory\n"); kfree(nseq); kfree(sseq); return NULL; } - memset(nseq, 0, sizeof(*nseq)); - nseq->lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(&nseq->lock); nseq->type = type; nseq->sseqs = sseq; dbg("tipc_nameseq_create(): nseq = %p, type %u, ssseqs %p, ff: %u\n", @@ -186,7 +178,7 @@ static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_hea /** * nameseq_find_subseq - find sub-sequence (if any) matching a name instance - * + * * Very time-critical, so binary searches through sub-sequence array. */ @@ -212,7 +204,7 @@ static struct sub_seq *nameseq_find_subseq(struct name_seq *nseq, /** * nameseq_locate_subseq - determine position of name instance in sub-sequence - * + * * Returns index in sub-sequence array of the entry that contains the specified * instance value; if no entry contains that value, returns the position * where a new entry for it would be inserted in the array. @@ -240,7 +232,7 @@ static u32 nameseq_locate_subseq(struct name_seq *nseq, u32 instance) } /** - * tipc_nameseq_insert_publ - + * tipc_nameseq_insert_publ - */ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, @@ -351,8 +343,8 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, } } - /* - * Any subscriptions waiting for notification? + /* + * Any subscriptions waiting for notification? */ list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) { dbg("calling report_overlap()\n"); @@ -360,7 +352,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, publ->lower, publ->upper, TIPC_PUBLISHED, - publ->ref, + publ->ref, publ->node, created_subseq); } @@ -369,7 +361,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, /** * tipc_nameseq_remove_publ - - * + * * NOTE: There may be cases where TIPC is asked to remove a publication * that is not in the name table. For example, if another node issues a * publication for a name sequence that overlaps an existing name sequence @@ -400,12 +392,12 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i prev = sseq->zone_list; publ = sseq->zone_list->zone_list_next; - while ((publ->key != key) || (publ->ref != ref) || + while ((publ->key != key) || (publ->ref != ref) || (publ->node && (publ->node != node))) { prev = publ; publ = publ->zone_list_next; if (prev == sseq->zone_list) { - + /* Prevent endless loop if publication not found */ return NULL; @@ -434,7 +426,7 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i err("Unable to de-list cluster publication\n" "{%u%u}, node=0x%x, ref=%u, key=%u)\n", - publ->type, publ->lower, publ->node, + publ->type, publ->lower, publ->node, publ->ref, publ->key); goto end_cluster; } @@ -464,7 +456,7 @@ end_cluster: err("Unable to de-list node publication\n" "{%u%u}, node=0x%x, ref=%u, key=%u)\n", - publ->type, publ->lower, publ->node, + publ->type, publ->lower, publ->node, publ->ref, publ->key); goto end_node; } @@ -494,8 +486,8 @@ end_node: tipc_subscr_report_overlap(s, publ->lower, publ->upper, - TIPC_WITHDRAWN, - publ->ref, + TIPC_WITHDRAWN, + publ->ref, publ->node, removed_subseq); } @@ -509,7 +501,7 @@ end_node: * sequence overlapping with the requested sequence */ -void tipc_nameseq_subscribe(struct name_seq *nseq, struct subscription *s) +static void tipc_nameseq_subscribe(struct name_seq *nseq, struct subscription *s) { struct sub_seq *sseq = nseq->sseqs; @@ -525,8 +517,8 @@ void tipc_nameseq_subscribe(struct name_seq *nseq, struct subscription *s) int must_report = 1; do { - tipc_subscr_report_overlap(s, - sseq->lower, + tipc_subscr_report_overlap(s, + sseq->lower, sseq->upper, TIPC_PUBLISHED, crs->ref, @@ -584,7 +576,7 @@ struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper, scope, node, port, key); } -struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, +struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, u32 node, u32 ref, u32 key) { struct publication *publ; @@ -684,14 +676,14 @@ not_found: /** * tipc_nametbl_mc_translate - find multicast destinations - * + * * Creates list of all local ports that overlap the given multicast address; * also determines if any off-node ports overlap. * * Note: Publications with a scope narrower than 'limit' are ignored. * (i.e. local node-scope publications mustn't receive messages arriving * from another node, even if the multcast link brought it here) - * + * * Returns non-zero if any off-node ports overlap */ @@ -738,7 +730,7 @@ exit: * tipc_nametbl_publish_rsv - publish port name using a reserved name type */ -int tipc_nametbl_publish_rsv(u32 ref, unsigned int scope, +int tipc_nametbl_publish_rsv(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) { int res; @@ -753,13 +745,13 @@ int tipc_nametbl_publish_rsv(u32 ref, unsigned int scope, * tipc_nametbl_publish - add name publication to network name tables */ -struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper, +struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper, u32 scope, u32 port_ref, u32 key) { struct publication *publ; if (table.local_publ_count >= tipc_max_publications) { - warn("Failed publish: max %u local publication\n", + warn("Publication failed, local publication limit reached (%u)\n", tipc_max_publications); return NULL; } @@ -816,22 +808,22 @@ void tipc_nametbl_subscribe(struct subscription *s) u32 type = s->seq.type; struct name_seq *seq; - write_lock_bh(&tipc_nametbl_lock); + write_lock_bh(&tipc_nametbl_lock); seq = nametbl_find_seq(type); if (!seq) { seq = tipc_nameseq_create(type, &table.types[hash(type)]); } - if (seq){ - spin_lock_bh(&seq->lock); - dbg("tipc_nametbl_subscribe:found %p for {%u,%u,%u}\n", - seq, type, s->seq.lower, s->seq.upper); - tipc_nameseq_subscribe(seq, s); - spin_unlock_bh(&seq->lock); - } else { + if (seq){ + spin_lock_bh(&seq->lock); + dbg("tipc_nametbl_subscribe:found %p for {%u,%u,%u}\n", + seq, type, s->seq.lower, s->seq.upper); + tipc_nameseq_subscribe(seq, s); + spin_unlock_bh(&seq->lock); + } else { warn("Failed to create subscription for {%u,%u,%u}\n", s->seq.type, s->seq.lower, s->seq.upper); - } - write_unlock_bh(&tipc_nametbl_lock); + } + write_unlock_bh(&tipc_nametbl_lock); } /** @@ -842,19 +834,19 @@ void tipc_nametbl_unsubscribe(struct subscription *s) { struct name_seq *seq; - write_lock_bh(&tipc_nametbl_lock); - seq = nametbl_find_seq(s->seq.type); + write_lock_bh(&tipc_nametbl_lock); + seq = nametbl_find_seq(s->seq.type); if (seq != NULL){ - spin_lock_bh(&seq->lock); - list_del_init(&s->nameseq_list); - spin_unlock_bh(&seq->lock); - if ((seq->first_free == 0) && list_empty(&seq->subscriptions)) { - hlist_del_init(&seq->ns_list); - kfree(seq->sseqs); - kfree(seq); - } - } - write_unlock_bh(&tipc_nametbl_lock); + spin_lock_bh(&seq->lock); + list_del_init(&s->nameseq_list); + spin_unlock_bh(&seq->lock); + if ((seq->first_free == 0) && list_empty(&seq->subscriptions)) { + hlist_del_init(&seq->ns_list); + kfree(seq->sseqs); + kfree(seq); + } + } + write_unlock_bh(&tipc_nametbl_lock); } @@ -960,7 +952,7 @@ static void nametbl_header(struct print_buf *buf, u32 depth) * nametbl_list - print specified name table contents into the given buffer */ -static void nametbl_list(struct print_buf *buf, u32 depth_info, +static void nametbl_list(struct print_buf *buf, u32 depth_info, u32 type, u32 lowbound, u32 upbound) { struct hlist_head *seq_head; @@ -984,7 +976,7 @@ static void nametbl_list(struct print_buf *buf, u32 depth_info, for (i = 0; i < tipc_nametbl_size; i++) { seq_head = &table.types[i]; hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { - nameseq_list(seq, buf, depth, seq->type, + nameseq_list(seq, buf, depth, seq->type, lowbound, upbound, i); } } @@ -999,7 +991,7 @@ static void nametbl_list(struct print_buf *buf, u32 depth_info, seq_head = &table.types[i]; hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { if (seq->type == type) { - nameseq_list(seq, buf, depth, type, + nameseq_list(seq, buf, depth, type, lowbound, upbound, i); break; } @@ -1038,7 +1030,7 @@ struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space) tipc_printbuf_init(&b, TLV_DATA(rep_tlv), MAX_NAME_TBL_QUERY); argv = (struct tipc_name_table_query *)TLV_DATA(req_tlv_area); read_lock_bh(&tipc_nametbl_lock); - nametbl_list(&b, ntohl(argv->depth), ntohl(argv->type), + nametbl_list(&b, ntohl(argv->depth), ntohl(argv->type), ntohl(argv->lowbound), ntohl(argv->upbound)); read_unlock_bh(&tipc_nametbl_lock); str_len = tipc_printbuf_validate(&b); @@ -1058,16 +1050,12 @@ void tipc_nametbl_dump(void) int tipc_nametbl_init(void) { - int array_size = sizeof(struct hlist_head) * tipc_nametbl_size; - - table.types = (struct hlist_head *)kmalloc(array_size, GFP_ATOMIC); + table.types = kcalloc(tipc_nametbl_size, sizeof(struct hlist_head), + GFP_ATOMIC); if (!table.types) return -ENOMEM; - write_lock_bh(&tipc_nametbl_lock); - memset(table.types, 0, array_size); table.local_publ_count = 0; - write_unlock_bh(&tipc_nametbl_lock); return 0; }