/*
* net/tipc/name_table.c: TIPC name table code
*
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "core.h"
#include "config.h"
#include "name_table.h"
#include "name_distr.h"
#include "subscr.h"
#include "port.h"
static int tipc_nametbl_size = 1024; /* must be a power of 2 */
/**
* struct sub_seq - container for all published instances of a name sequence
* @lower: name sequence lower bound
* @upper: name sequence upper bound
* @node_list: circular list of publications made by own node
* @cluster_list: circular list of publications made by own cluster
* @zone_list: circular list of publications made by own zone
* @node_list_size: number of entries in "node_list"
* @cluster_list_size: number of entries in "cluster_list"
* @zone_list_size: number of entries in "zone_list"
*
* Note: The zone list always contains at least one entry, since all
* publications of the associated name sequence belong to it.
* (The cluster and node lists may be empty.)
*/
struct sub_seq {
u32 lower;
u32 upper;
struct publication *node_list;
struct publication *cluster_list;
struct publication *zone_list;
u32 node_list_size;
u32 cluster_list_size;
u32 zone_list_size;
};
/**
* 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';
* sub-sequences are sorted in ascending order
* @alloc: number of sub-sequences currently in array
* @first_free: array index of first unused sub-sequence entry
* @ns_list: links to adjacent name sequences in hash chain
* @subscriptions: list of subscriptions for this 'type'
* @lock: spinlock controlling access to publication lists of all sub-sequences
*/
struct name_seq {
u32 type;
struct sub_seq *sseqs;
u32 alloc;
u32 first_free;
struct hlist_node ns_list;
struct list_head subscriptions;
spinlock_t lock;
};
/**
* struct name_table - table containing all existing port name publications
* @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
*/
struct name_table {
struct hlist_head *types;
u32 local_publ_count;
};
static struct name_table table;
static atomic_t rsv_publ_ok = ATOMIC_INIT(0);
DEFINE_RWLOCK(tipc_nametbl_lock);
static int hash(int x)
{
return x & (tipc_nametbl_size - 1);
}
/**
* publ_create - create a publication structure
*/
static struct publication *publ_create(u32 type, u32 lower, u32 upper,
u32 scope, u32 node, u32 port_ref,
u32 key)
{
struct publication *publ = kzalloc(sizeof(*publ), GFP_ATOMIC);
if (publ == NULL) {
warn("Publication creation failure, no memory\n");
return NULL;
}
publ->type = type;
publ->lower = lower;
publ->upper = upper;
publ->scope = scope;
publ->node = node;
publ->ref = port_ref;
publ->key = key;
INIT_LIST_HEAD(&publ->local_list);
INIT_LIST_HEAD(&publ->pport_list);
INIT_LIST_HEAD(&publ->subscr.nodesub_list);
return publ;
}
/**
* tipc_subseq_alloc - allocate a specified number of sub-sequence structures
*/
static struct sub_seq *tipc_subseq_alloc(u32 cnt)
{
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 = kzalloc(sizeof(*nseq), GFP_ATOMIC);
struct sub_seq *sseq = tipc_subseq_alloc(1);
if (!nseq || !sseq) {
warn("Name sequence creation failed, no memory\n");
kfree(nseq);
kfree(sseq);
return NULL;
}
spin_lock_init(&nseq->lock);
nseq->type = type;
nseq->sseqs = sseq;
nseq->alloc = 1;
INIT_HLIST_NODE(&nseq->ns_list);
INIT_LIST_HEAD(&nseq->subscriptions);
hlist_add_head(&nseq->ns_list, seq_head);
return nseq;
}
/**
* nameseq_find_subseq - find sub-sequence (if any) matching a name instance
*
* Very time-critical, so binary searches through sub-sequence array.
*/
static struct sub_seq *nameseq_find_subseq(struct name_seq *nseq,
u32 instance)
{
struct sub_seq *sseqs = nseq->sseqs;
int low = 0;
int high = nseq->first_free - 1;
int mid;
while (low <= high) {
mid = (low + high) / 2;
if (instance < sseqs[mid].lower)
high = mid - 1;
else if (instance > sseqs[mid].upper)
low = mid + 1;
else
return &sseqs[mid];
}
return NULL;
}
/**
* 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.
*
* Note: Similar to binary search code for locating a sub-sequence.
*/
static u32 nameseq_locate_subseq(struct name_seq *nseq, u32 instance)
{
struct sub_seq *sseqs = nseq->sseqs;
int low = 0;
int high = nseq->first_free - 1;
int mid;
while (low <= high) {
mid = (low + high) / 2;
if (instance < sseqs[mid].lower)
high = mid - 1;
else if (instance > sseqs[mid].upper)
low = mid + 1;
else
return mid;
}
return low;
}
/**
* tipc_nameseq_insert_publ -
*/
static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
u32 type, u32 lower, u32 upper,
u32 scope, u32 node, u32 port, u32 key)
{
struct subscription *s;
struct subscription *st;
struct publication *publ;
struct sub_seq *sseq;
int created_subseq = 0;
sseq = nameseq_find_subseq(nseq, lower);
if (sseq) {
/* Lower end overlaps existing entry => need an exact match */
if ((sseq->lower != lower) || (sseq->upper != upper)) {
warn("Cannot publish {%u,%u,%u}, overlap error\n",
type, lower, upper);
return NULL;
}
} else {
u32 inspos;
struct sub_seq *freesseq;
/* Find where lower end should be inserted */
inspos = nameseq_locate_subseq(nseq, lower);
/* Fail if upper end overlaps into an existing entry */
if ((inspos < nseq->first_free) &&
(upper >= nseq->sseqs[inspos].lower)) {
warn("Cannot publish {%u,%u,%u}, overlap error\n",
type, lo
没有合适的资源?快使用搜索试试~ 我知道了~
name_table.rar_Code Name
共1个文件
c:1个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 148 浏览量
2022-09-20
20:23:02
上传
评论
收藏 7KB RAR 举报
温馨提示
TIPC name table code
资源推荐
资源详情
资源评论
收起资源包目录
name_table.rar (1个子文件)
name_table.c 26KB
共 1 条
- 1
资源评论
寒泊
- 粉丝: 76
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功