Blame view
net/tipc/name_table.c
25 KB
b97bf3fd8 [TIPC] Initial merge |
1 2 |
/* * net/tipc/name_table.c: TIPC name table code |
c43072852 [NET] TIPC: Fix w... |
3 |
* |
593a5f22d [TIPC] More updat... |
4 |
* Copyright (c) 2000-2006, Ericsson AB |
f6f0a4d2d tipc: Convert nam... |
5 |
* Copyright (c) 2004-2008, 2010-2011, Wind River Systems |
b97bf3fd8 [TIPC] Initial merge |
6 7 |
* All rights reserved. * |
9ea1fd3c1 [TIPC] License he... |
8 |
* Redistribution and use in source and binary forms, with or without |
b97bf3fd8 [TIPC] Initial merge |
9 10 |
* modification, are permitted provided that the following conditions are met: * |
9ea1fd3c1 [TIPC] License he... |
11 12 13 14 15 16 17 18 |
* 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. |
b97bf3fd8 [TIPC] Initial merge |
19 |
* |
9ea1fd3c1 [TIPC] License he... |
20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
* 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 |
b97bf3fd8 [TIPC] Initial merge |
34 35 36 37 38 |
* POSSIBILITY OF SUCH DAMAGE. */ #include "core.h" #include "config.h" |
b97bf3fd8 [TIPC] Initial merge |
39 40 |
#include "name_table.h" #include "name_distr.h" |
b97bf3fd8 [TIPC] Initial merge |
41 42 |
#include "subscr.h" #include "port.h" |
b97bf3fd8 [TIPC] Initial merge |
43 |
|
988f088a8 [TIPC]: Cleanups |
44 |
static int tipc_nametbl_size = 1024; /* must be a power of 2 */ |
b97bf3fd8 [TIPC] Initial merge |
45 46 |
/** |
b52124a50 tipc: Partition n... |
47 |
* struct name_info - name sequence publication info |
968edbe1c tipc: Optimizatio... |
48 49 50 51 52 53 54 55 56 57 |
* @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.) |
b97bf3fd8 [TIPC] Initial merge |
58 |
*/ |
b52124a50 tipc: Partition n... |
59 |
struct name_info { |
f6f0a4d2d tipc: Convert nam... |
60 61 62 |
struct list_head node_list; struct list_head cluster_list; struct list_head zone_list; |
968edbe1c tipc: Optimizatio... |
63 64 65 |
u32 node_list_size; u32 cluster_list_size; u32 zone_list_size; |
b97bf3fd8 [TIPC] Initial merge |
66 |
}; |
c43072852 [NET] TIPC: Fix w... |
67 |
/** |
b52124a50 tipc: Partition n... |
68 69 70 71 72 73 74 75 76 77 78 79 80 |
* struct sub_seq - container for all published instances of a name sequence * @lower: name sequence lower bound * @upper: name sequence upper bound * @info: pointer to name sequence publication info */ struct sub_seq { u32 lower; u32 upper; struct name_info *info; }; /** |
b97bf3fd8 [TIPC] Initial merge |
81 82 83 84 85 |
* 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 |
f131072c3 [TIPC]: First pha... |
86 |
* @first_free: array index of first unused sub-sequence entry |
b97bf3fd8 [TIPC] Initial merge |
87 88 |
* @ns_list: links to adjacent name sequences in hash chain * @subscriptions: list of subscriptions for this 'type' |
307fdf5e7 tipc: Add missing... |
89 |
* @lock: spinlock controlling access to publication lists of all sub-sequences |
b97bf3fd8 [TIPC] Initial merge |
90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
*/ 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 |
c43072852 [NET] TIPC: Fix w... |
104 |
* @types: pointer to fixed-sized array of name sequence lists, |
b97bf3fd8 [TIPC] Initial merge |
105 106 107 108 109 110 111 112 |
* 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; }; |
e3ec9c7d5 tipc: remove zero... |
113 |
static struct name_table table; |
b97bf3fd8 [TIPC] Initial merge |
114 |
static atomic_t rsv_publ_ok = ATOMIC_INIT(0); |
34af946a2 [PATCH] spin/rwlo... |
115 |
DEFINE_RWLOCK(tipc_nametbl_lock); |
b97bf3fd8 [TIPC] Initial merge |
116 |
|
05790c645 [TIPC]: Remove in... |
117 |
static int hash(int x) |
b97bf3fd8 [TIPC] Initial merge |
118 |
{ |
a02cec215 net: return opera... |
119 |
return x & (tipc_nametbl_size - 1); |
b97bf3fd8 [TIPC] Initial merge |
120 121 122 123 124 |
} /** * publ_create - create a publication structure */ |
c43072852 [NET] TIPC: Fix w... |
125 126 |
static struct publication *publ_create(u32 type, u32 lower, u32 upper, u32 scope, u32 node, u32 port_ref, |
b97bf3fd8 [TIPC] Initial merge |
127 128 |
u32 key) { |
0da974f4f [NET]: Conversion... |
129 |
struct publication *publ = kzalloc(sizeof(*publ), GFP_ATOMIC); |
b97bf3fd8 [TIPC] Initial merge |
130 |
if (publ == NULL) { |
a10bd924a [TIPC]: Enhanced ... |
131 132 |
warn("Publication creation failure, no memory "); |
1fc54d8f4 [TIPC]: Fix simpl... |
133 |
return NULL; |
b97bf3fd8 [TIPC] Initial merge |
134 |
} |
b97bf3fd8 [TIPC] Initial merge |
135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
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; } /** |
4323add67 [TIPC] Avoid poll... |
149 |
* tipc_subseq_alloc - allocate a specified number of sub-sequence structures |
b97bf3fd8 [TIPC] Initial merge |
150 |
*/ |
988f088a8 [TIPC]: Cleanups |
151 |
static struct sub_seq *tipc_subseq_alloc(u32 cnt) |
b97bf3fd8 [TIPC] Initial merge |
152 |
{ |
0da974f4f [NET]: Conversion... |
153 |
struct sub_seq *sseq = kcalloc(cnt, sizeof(struct sub_seq), GFP_ATOMIC); |
b97bf3fd8 [TIPC] Initial merge |
154 155 156 157 |
return sseq; } /** |
4323add67 [TIPC] Avoid poll... |
158 |
* tipc_nameseq_create - create a name sequence structure for the specified 'type' |
c43072852 [NET] TIPC: Fix w... |
159 |
* |
b97bf3fd8 [TIPC] Initial merge |
160 161 |
* Allocates a single sub-sequence structure and sets it to all 0's. */ |
988f088a8 [TIPC]: Cleanups |
162 |
static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_head) |
b97bf3fd8 [TIPC] Initial merge |
163 |
{ |
0da974f4f [NET]: Conversion... |
164 |
struct name_seq *nseq = kzalloc(sizeof(*nseq), GFP_ATOMIC); |
4323add67 [TIPC] Avoid poll... |
165 |
struct sub_seq *sseq = tipc_subseq_alloc(1); |
b97bf3fd8 [TIPC] Initial merge |
166 167 |
if (!nseq || !sseq) { |
a10bd924a [TIPC]: Enhanced ... |
168 169 |
warn("Name sequence creation failed, no memory "); |
b97bf3fd8 [TIPC] Initial merge |
170 171 |
kfree(nseq); kfree(sseq); |
1fc54d8f4 [TIPC]: Fix simpl... |
172 |
return NULL; |
b97bf3fd8 [TIPC] Initial merge |
173 |
} |
34af946a2 [PATCH] spin/rwlo... |
174 |
spin_lock_init(&nseq->lock); |
b97bf3fd8 [TIPC] Initial merge |
175 176 |
nseq->type = type; nseq->sseqs = sseq; |
b97bf3fd8 [TIPC] Initial merge |
177 178 179 180 181 182 183 184 185 |
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 |
c43072852 [NET] TIPC: Fix w... |
186 |
* |
b97bf3fd8 [TIPC] Initial merge |
187 188 |
* Very time-critical, so binary searches through sub-sequence array. */ |
05790c645 [TIPC]: Remove in... |
189 190 |
static struct sub_seq *nameseq_find_subseq(struct name_seq *nseq, u32 instance) |
b97bf3fd8 [TIPC] Initial merge |
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
{ 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]; } |
1fc54d8f4 [TIPC]: Fix simpl... |
206 |
return NULL; |
b97bf3fd8 [TIPC] Initial merge |
207 208 209 210 |
} /** * nameseq_locate_subseq - determine position of name instance in sub-sequence |
c43072852 [NET] TIPC: Fix w... |
211 |
* |
b97bf3fd8 [TIPC] Initial merge |
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 |
* 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; } /** |
c43072852 [NET] TIPC: Fix w... |
239 |
* tipc_nameseq_insert_publ - |
b97bf3fd8 [TIPC] Initial merge |
240 |
*/ |
988f088a8 [TIPC]: Cleanups |
241 242 243 |
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) |
b97bf3fd8 [TIPC] Initial merge |
244 |
{ |
fead39098 tipc: rename stru... |
245 246 |
struct tipc_subscription *s; struct tipc_subscription *st; |
b97bf3fd8 [TIPC] Initial merge |
247 248 |
struct publication *publ; struct sub_seq *sseq; |
b52124a50 tipc: Partition n... |
249 |
struct name_info *info; |
b97bf3fd8 [TIPC] Initial merge |
250 |
int created_subseq = 0; |
b97bf3fd8 [TIPC] Initial merge |
251 |
sseq = nameseq_find_subseq(nseq, lower); |
b97bf3fd8 [TIPC] Initial merge |
252 253 254 255 256 |
if (sseq) { /* Lower end overlaps existing entry => need an exact match */ if ((sseq->lower != lower) || (sseq->upper != upper)) { |
f131072c3 [TIPC]: First pha... |
257 258 259 |
warn("Cannot publish {%u,%u,%u}, overlap error ", type, lower, upper); |
1fc54d8f4 [TIPC]: Fix simpl... |
260 |
return NULL; |
b97bf3fd8 [TIPC] Initial merge |
261 |
} |
b52124a50 tipc: Partition n... |
262 263 |
info = sseq->info; |
b97bf3fd8 [TIPC] Initial merge |
264 265 266 267 268 269 270 271 272 273 274 275 |
} 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)) { |
f131072c3 [TIPC]: First pha... |
276 277 278 |
warn("Cannot publish {%u,%u,%u}, overlap error ", type, lower, upper); |
1fc54d8f4 [TIPC]: Fix simpl... |
279 |
return NULL; |
b97bf3fd8 [TIPC] Initial merge |
280 281 282 283 284 |
} /* Ensure there is space for new sub-sequence */ if (nseq->first_free == nseq->alloc) { |
9ab230f82 [TIPC]: Prevent n... |
285 286 287 |
struct sub_seq *sseqs = tipc_subseq_alloc(nseq->alloc * 2); if (!sseqs) { |
f131072c3 [TIPC]: First pha... |
288 289 290 |
warn("Cannot publish {%u,%u,%u}, no memory ", type, lower, upper); |
1fc54d8f4 [TIPC]: Fix simpl... |
291 |
return NULL; |
b97bf3fd8 [TIPC] Initial merge |
292 |
} |
9ab230f82 [TIPC]: Prevent n... |
293 294 295 296 297 |
memcpy(sseqs, nseq->sseqs, nseq->alloc * sizeof(struct sub_seq)); kfree(nseq->sseqs); nseq->sseqs = sseqs; nseq->alloc *= 2; |
b97bf3fd8 [TIPC] Initial merge |
298 |
} |
b97bf3fd8 [TIPC] Initial merge |
299 |
|
b52124a50 tipc: Partition n... |
300 301 302 303 304 305 306 |
info = kzalloc(sizeof(*info), GFP_ATOMIC); if (!info) { warn("Cannot publish {%u,%u,%u}, no memory ", type, lower, upper); return NULL; } |
f6f0a4d2d tipc: Convert nam... |
307 308 309 |
INIT_LIST_HEAD(&info->node_list); INIT_LIST_HEAD(&info->cluster_list); INIT_LIST_HEAD(&info->zone_list); |
b97bf3fd8 [TIPC] Initial merge |
310 |
/* Insert new sub-sequence */ |
b97bf3fd8 [TIPC] Initial merge |
311 312 |
sseq = &nseq->sseqs[inspos]; freesseq = &nseq->sseqs[nseq->first_free]; |
0e65967e3 tipc: cleanup var... |
313 314 |
memmove(sseq + 1, sseq, (freesseq - sseq) * sizeof(*sseq)); memset(sseq, 0, sizeof(*sseq)); |
b97bf3fd8 [TIPC] Initial merge |
315 316 317 |
nseq->first_free++; sseq->lower = lower; sseq->upper = upper; |
b52124a50 tipc: Partition n... |
318 |
sseq->info = info; |
b97bf3fd8 [TIPC] Initial merge |
319 320 |
created_subseq = 1; } |
b97bf3fd8 [TIPC] Initial merge |
321 322 323 324 325 |
/* Insert a publication: */ publ = publ_create(type, lower, upper, scope, node, port, key); if (!publ) |
1fc54d8f4 [TIPC]: Fix simpl... |
326 |
return NULL; |
b97bf3fd8 [TIPC] Initial merge |
327 |
|
f6f0a4d2d tipc: Convert nam... |
328 |
list_add(&publ->zone_list, &info->zone_list); |
b52124a50 tipc: Partition n... |
329 |
info->zone_list_size++; |
b97bf3fd8 [TIPC] Initial merge |
330 331 |
if (in_own_cluster(node)) { |
f6f0a4d2d tipc: Convert nam... |
332 |
list_add(&publ->cluster_list, &info->cluster_list); |
b52124a50 tipc: Partition n... |
333 |
info->cluster_list_size++; |
b97bf3fd8 [TIPC] Initial merge |
334 335 336 |
} if (node == tipc_own_addr) { |
f6f0a4d2d tipc: Convert nam... |
337 |
list_add(&publ->node_list, &info->node_list); |
b52124a50 tipc: Partition n... |
338 |
info->node_list_size++; |
b97bf3fd8 [TIPC] Initial merge |
339 |
} |
c43072852 [NET] TIPC: Fix w... |
340 341 |
/* * Any subscriptions waiting for notification? |
b97bf3fd8 [TIPC] Initial merge |
342 343 |
*/ list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) { |
4323add67 [TIPC] Avoid poll... |
344 345 346 347 |
tipc_subscr_report_overlap(s, publ->lower, publ->upper, TIPC_PUBLISHED, |
c43072852 [NET] TIPC: Fix w... |
348 |
publ->ref, |
4323add67 [TIPC] Avoid poll... |
349 350 |
publ->node, created_subseq); |
b97bf3fd8 [TIPC] Initial merge |
351 352 353 354 355 |
} return publ; } /** |
4323add67 [TIPC] Avoid poll... |
356 |
* tipc_nameseq_remove_publ - |
c43072852 [NET] TIPC: Fix w... |
357 |
* |
f131072c3 [TIPC]: First pha... |
358 359 360 361 362 363 364 |
* 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 * the publication will not be recorded, which means the publication won't * be found when the name sequence is later withdrawn by that node. * A failed withdraw request simply returns a failure indication and lets the * caller issue any error or warning messages associated with such a problem. |
b97bf3fd8 [TIPC] Initial merge |
365 |
*/ |
988f088a8 [TIPC]: Cleanups |
366 367 |
static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 inst, u32 node, u32 ref, u32 key) |
b97bf3fd8 [TIPC] Initial merge |
368 369 |
{ struct publication *publ; |
b97bf3fd8 [TIPC] Initial merge |
370 |
struct sub_seq *sseq = nameseq_find_subseq(nseq, inst); |
b52124a50 tipc: Partition n... |
371 |
struct name_info *info; |
b97bf3fd8 [TIPC] Initial merge |
372 |
struct sub_seq *free; |
fead39098 tipc: rename stru... |
373 |
struct tipc_subscription *s, *st; |
b97bf3fd8 [TIPC] Initial merge |
374 |
int removed_subseq = 0; |
f131072c3 [TIPC]: First pha... |
375 |
if (!sseq) |
1fc54d8f4 [TIPC]: Fix simpl... |
376 |
return NULL; |
f131072c3 [TIPC]: First pha... |
377 |
|
b52124a50 tipc: Partition n... |
378 |
info = sseq->info; |
f6f0a4d2d tipc: Convert nam... |
379 |
/* Locate publication, if it exists */ |
f131072c3 [TIPC]: First pha... |
380 |
|
f6f0a4d2d tipc: Convert nam... |
381 382 383 384 385 386 |
list_for_each_entry(publ, &info->zone_list, zone_list) { if ((publ->key == key) && (publ->ref == ref) && (!publ->node || (publ->node == node))) goto found; } return NULL; |
c43072852 [NET] TIPC: Fix w... |
387 |
|
f6f0a4d2d tipc: Convert nam... |
388 389 |
found: /* Remove publication from zone scope list */ |
f131072c3 [TIPC]: First pha... |
390 |
|
f6f0a4d2d tipc: Convert nam... |
391 |
list_del(&publ->zone_list); |
b52124a50 tipc: Partition n... |
392 |
info->zone_list_size--; |
b97bf3fd8 [TIPC] Initial merge |
393 |
|
f131072c3 [TIPC]: First pha... |
394 |
/* Remove publication from cluster scope list, if present */ |
b97bf3fd8 [TIPC] Initial merge |
395 |
if (in_own_cluster(node)) { |
f6f0a4d2d tipc: Convert nam... |
396 |
list_del(&publ->cluster_list); |
b52124a50 tipc: Partition n... |
397 |
info->cluster_list_size--; |
b97bf3fd8 [TIPC] Initial merge |
398 |
} |
f131072c3 [TIPC]: First pha... |
399 400 |
/* Remove publication from node scope list, if present */ |
b97bf3fd8 [TIPC] Initial merge |
401 402 |
if (node == tipc_own_addr) { |
f6f0a4d2d tipc: Convert nam... |
403 |
list_del(&publ->node_list); |
b52124a50 tipc: Partition n... |
404 |
info->node_list_size--; |
b97bf3fd8 [TIPC] Initial merge |
405 |
} |
b97bf3fd8 [TIPC] Initial merge |
406 |
|
f131072c3 [TIPC]: First pha... |
407 |
/* Contract subseq list if no more publications for that subseq */ |
f6f0a4d2d tipc: Convert nam... |
408 |
if (list_empty(&info->zone_list)) { |
b52124a50 tipc: Partition n... |
409 |
kfree(info); |
b97bf3fd8 [TIPC] Initial merge |
410 |
free = &nseq->sseqs[nseq->first_free--]; |
0e65967e3 tipc: cleanup var... |
411 |
memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof(*sseq)); |
b97bf3fd8 [TIPC] Initial merge |
412 413 |
removed_subseq = 1; } |
f131072c3 [TIPC]: First pha... |
414 |
/* Notify any waiting subscriptions */ |
b97bf3fd8 [TIPC] Initial merge |
415 |
list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) { |
4323add67 [TIPC] Avoid poll... |
416 417 418 |
tipc_subscr_report_overlap(s, publ->lower, publ->upper, |
c43072852 [NET] TIPC: Fix w... |
419 420 |
TIPC_WITHDRAWN, publ->ref, |
4323add67 [TIPC] Avoid poll... |
421 422 |
publ->node, removed_subseq); |
b97bf3fd8 [TIPC] Initial merge |
423 |
} |
f131072c3 [TIPC]: First pha... |
424 |
|
b97bf3fd8 [TIPC] Initial merge |
425 426 427 428 |
return publ; } /** |
4323add67 [TIPC] Avoid poll... |
429 |
* tipc_nameseq_subscribe: attach a subscription, and issue |
b97bf3fd8 [TIPC] Initial merge |
430 431 432 |
* the prescribed number of events if there is any sub- * sequence overlapping with the requested sequence */ |
fead39098 tipc: rename stru... |
433 434 |
static void tipc_nameseq_subscribe(struct name_seq *nseq, struct tipc_subscription *s) |
b97bf3fd8 [TIPC] Initial merge |
435 436 437 438 439 440 441 442 443 |
{ struct sub_seq *sseq = nseq->sseqs; list_add(&s->nameseq_list, &nseq->subscriptions); if (!sseq) return; while (sseq != &nseq->sseqs[nseq->first_free]) { |
f6f0a4d2d tipc: Convert nam... |
444 445 446 |
if (tipc_subscr_overlap(s, sseq->lower, sseq->upper)) { struct publication *crs; struct name_info *info = sseq->info; |
b97bf3fd8 [TIPC] Initial merge |
447 |
int must_report = 1; |
f6f0a4d2d tipc: Convert nam... |
448 |
list_for_each_entry(crs, &info->zone_list, zone_list) { |
c43072852 [NET] TIPC: Fix w... |
449 450 |
tipc_subscr_report_overlap(s, sseq->lower, |
4323add67 [TIPC] Avoid poll... |
451 452 453 454 455 |
sseq->upper, TIPC_PUBLISHED, crs->ref, crs->node, must_report); |
b97bf3fd8 [TIPC] Initial merge |
456 |
must_report = 0; |
f6f0a4d2d tipc: Convert nam... |
457 |
} |
b97bf3fd8 [TIPC] Initial merge |
458 459 460 461 462 463 464 465 466 467 |
} sseq++; } } static struct name_seq *nametbl_find_seq(u32 type) { struct hlist_head *seq_head; struct hlist_node *seq_node; struct name_seq *ns; |
b97bf3fd8 [TIPC] Initial merge |
468 469 |
seq_head = &table.types[hash(type)]; hlist_for_each_entry(ns, seq_node, seq_head, ns_list) { |
b29f14284 tipc: remove call... |
470 |
if (ns->type == type) |
b97bf3fd8 [TIPC] Initial merge |
471 |
return ns; |
b97bf3fd8 [TIPC] Initial merge |
472 |
} |
1fc54d8f4 [TIPC]: Fix simpl... |
473 |
return NULL; |
b97bf3fd8 [TIPC] Initial merge |
474 |
}; |
4323add67 [TIPC] Avoid poll... |
475 476 |
struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper, u32 scope, u32 node, u32 port, u32 key) |
b97bf3fd8 [TIPC] Initial merge |
477 478 |
{ struct name_seq *seq = nametbl_find_seq(type); |
b97bf3fd8 [TIPC] Initial merge |
479 |
if (lower > upper) { |
f131072c3 [TIPC]: First pha... |
480 481 |
warn("Failed to publish illegal {%u,%u,%u} ", |
b97bf3fd8 [TIPC] Initial merge |
482 |
type, lower, upper); |
1fc54d8f4 [TIPC]: Fix simpl... |
483 |
return NULL; |
b97bf3fd8 [TIPC] Initial merge |
484 |
} |
b29f14284 tipc: remove call... |
485 |
if (!seq) |
4323add67 [TIPC] Avoid poll... |
486 |
seq = tipc_nameseq_create(type, &table.types[hash(type)]); |
b97bf3fd8 [TIPC] Initial merge |
487 |
if (!seq) |
1fc54d8f4 [TIPC]: Fix simpl... |
488 |
return NULL; |
b97bf3fd8 [TIPC] Initial merge |
489 |
|
4323add67 [TIPC] Avoid poll... |
490 491 |
return tipc_nameseq_insert_publ(seq, type, lower, upper, scope, node, port, key); |
b97bf3fd8 [TIPC] Initial merge |
492 |
} |
c43072852 [NET] TIPC: Fix w... |
493 |
struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, |
4323add67 [TIPC] Avoid poll... |
494 |
u32 node, u32 ref, u32 key) |
b97bf3fd8 [TIPC] Initial merge |
495 496 497 498 499 |
{ struct publication *publ; struct name_seq *seq = nametbl_find_seq(type); if (!seq) |
1fc54d8f4 [TIPC]: Fix simpl... |
500 |
return NULL; |
b97bf3fd8 [TIPC] Initial merge |
501 |
|
4323add67 [TIPC] Avoid poll... |
502 |
publ = tipc_nameseq_remove_publ(seq, lower, node, ref, key); |
b97bf3fd8 [TIPC] Initial merge |
503 504 505 506 507 508 509 510 511 512 |
if (!seq->first_free && list_empty(&seq->subscriptions)) { hlist_del_init(&seq->ns_list); kfree(seq->sseqs); kfree(seq); } return publ; } /* |
5d9c54c1e tipc: Minor optim... |
513 |
* tipc_nametbl_translate - translate name to port id |
b97bf3fd8 [TIPC] Initial merge |
514 515 516 517 |
* * Note: on entry 'destnode' is the search domain used during translation; * on exit it passes back the node address of the matching port (if any) */ |
4323add67 [TIPC] Avoid poll... |
518 |
u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode) |
b97bf3fd8 [TIPC] Initial merge |
519 520 |
{ struct sub_seq *sseq; |
b52124a50 tipc: Partition n... |
521 |
struct name_info *info; |
f6f0a4d2d tipc: Convert nam... |
522 |
struct publication *publ; |
b97bf3fd8 [TIPC] Initial merge |
523 |
struct name_seq *seq; |
f6f0a4d2d tipc: Convert nam... |
524 |
u32 ref = 0; |
b97bf3fd8 [TIPC] Initial merge |
525 |
|
c68ca7b72 tipc: add tipc_ p... |
526 |
if (!tipc_in_scope(*destnode, tipc_own_addr)) |
b97bf3fd8 [TIPC] Initial merge |
527 |
return 0; |
4323add67 [TIPC] Avoid poll... |
528 |
read_lock_bh(&tipc_nametbl_lock); |
b97bf3fd8 [TIPC] Initial merge |
529 530 531 532 533 534 535 |
seq = nametbl_find_seq(type); if (unlikely(!seq)) goto not_found; sseq = nameseq_find_subseq(seq, instance); if (unlikely(!sseq)) goto not_found; spin_lock_bh(&seq->lock); |
b52124a50 tipc: Partition n... |
536 |
info = sseq->info; |
b97bf3fd8 [TIPC] Initial merge |
537 538 539 |
/* Closest-First Algorithm: */ if (likely(!*destnode)) { |
f6f0a4d2d tipc: Convert nam... |
540 541 542 543 544 545 546 547 548 549 550 551 |
if (!list_empty(&info->node_list)) { publ = list_first_entry(&info->node_list, struct publication, node_list); list_move_tail(&publ->node_list, &info->node_list); } else if (!list_empty(&info->cluster_list)) { publ = list_first_entry(&info->cluster_list, struct publication, cluster_list); list_move_tail(&publ->cluster_list, &info->cluster_list); |
8af4638a2 tipc: Eliminate c... |
552 |
} else { |
f6f0a4d2d tipc: Convert nam... |
553 554 555 556 557 |
publ = list_first_entry(&info->zone_list, struct publication, zone_list); list_move_tail(&publ->zone_list, &info->zone_list); |
8af4638a2 tipc: Eliminate c... |
558 |
} |
b97bf3fd8 [TIPC] Initial merge |
559 560 561 562 |
} /* Round-Robin Algorithm: */ else if (*destnode == tipc_own_addr) { |
f6f0a4d2d tipc: Convert nam... |
563 564 565 566 567 |
if (list_empty(&info->node_list)) goto no_match; publ = list_first_entry(&info->node_list, struct publication, node_list); list_move_tail(&publ->node_list, &info->node_list); |
b97bf3fd8 [TIPC] Initial merge |
568 |
} else if (in_own_cluster(*destnode)) { |
f6f0a4d2d tipc: Convert nam... |
569 570 571 572 573 |
if (list_empty(&info->cluster_list)) goto no_match; publ = list_first_entry(&info->cluster_list, struct publication, cluster_list); list_move_tail(&publ->cluster_list, &info->cluster_list); |
b97bf3fd8 [TIPC] Initial merge |
574 |
} else { |
f6f0a4d2d tipc: Convert nam... |
575 576 577 |
publ = list_first_entry(&info->zone_list, struct publication, zone_list); list_move_tail(&publ->zone_list, &info->zone_list); |
b97bf3fd8 [TIPC] Initial merge |
578 |
} |
f6f0a4d2d tipc: Convert nam... |
579 580 581 582 |
ref = publ->ref; *destnode = publ->node; no_match: |
b97bf3fd8 [TIPC] Initial merge |
583 584 |
spin_unlock_bh(&seq->lock); not_found: |
4323add67 [TIPC] Avoid poll... |
585 |
read_unlock_bh(&tipc_nametbl_lock); |
f6f0a4d2d tipc: Convert nam... |
586 |
return ref; |
b97bf3fd8 [TIPC] Initial merge |
587 588 589 |
} /** |
4323add67 [TIPC] Avoid poll... |
590 |
* tipc_nametbl_mc_translate - find multicast destinations |
c43072852 [NET] TIPC: Fix w... |
591 |
* |
b97bf3fd8 [TIPC] Initial merge |
592 593 594 595 596 597 |
* 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) |
c43072852 [NET] TIPC: Fix w... |
598 |
* |
b97bf3fd8 [TIPC] Initial merge |
599 600 |
* Returns non-zero if any off-node ports overlap */ |
4323add67 [TIPC] Avoid poll... |
601 |
int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit, |
4584310b4 tipc: rename stru... |
602 |
struct tipc_port_list *dports) |
b97bf3fd8 [TIPC] Initial merge |
603 604 605 606 |
{ struct name_seq *seq; struct sub_seq *sseq; struct sub_seq *sseq_stop; |
b52124a50 tipc: Partition n... |
607 |
struct name_info *info; |
b97bf3fd8 [TIPC] Initial merge |
608 |
int res = 0; |
4323add67 [TIPC] Avoid poll... |
609 |
read_lock_bh(&tipc_nametbl_lock); |
b97bf3fd8 [TIPC] Initial merge |
610 611 612 613 614 615 616 617 618 619 620 621 622 |
seq = nametbl_find_seq(type); if (!seq) goto exit; spin_lock_bh(&seq->lock); sseq = seq->sseqs + nameseq_locate_subseq(seq, lower); sseq_stop = seq->sseqs + seq->first_free; for (; sseq != sseq_stop; sseq++) { struct publication *publ; if (sseq->lower > upper) break; |
968edbe1c tipc: Optimizatio... |
623 |
|
b52124a50 tipc: Partition n... |
624 |
info = sseq->info; |
f6f0a4d2d tipc: Convert nam... |
625 626 627 |
list_for_each_entry(publ, &info->node_list, node_list) { if (publ->scope <= limit) tipc_port_list_add(dports, publ->ref); |
968edbe1c tipc: Optimizatio... |
628 |
} |
b52124a50 tipc: Partition n... |
629 |
if (info->cluster_list_size != info->node_list_size) |
968edbe1c tipc: Optimizatio... |
630 |
res = 1; |
b97bf3fd8 [TIPC] Initial merge |
631 632 633 634 |
} spin_unlock_bh(&seq->lock); exit: |
4323add67 [TIPC] Avoid poll... |
635 |
read_unlock_bh(&tipc_nametbl_lock); |
b97bf3fd8 [TIPC] Initial merge |
636 637 638 639 |
return res; } /** |
4323add67 [TIPC] Avoid poll... |
640 |
* tipc_nametbl_publish_rsv - publish port name using a reserved name type |
b97bf3fd8 [TIPC] Initial merge |
641 |
*/ |
c43072852 [NET] TIPC: Fix w... |
642 |
int tipc_nametbl_publish_rsv(u32 ref, unsigned int scope, |
b97bf3fd8 [TIPC] Initial merge |
643 644 645 646 647 648 649 650 651 652 653 |
struct tipc_name_seq const *seq) { int res; atomic_inc(&rsv_publ_ok); res = tipc_publish(ref, scope, seq); atomic_dec(&rsv_publ_ok); return res; } /** |
4323add67 [TIPC] Avoid poll... |
654 |
* tipc_nametbl_publish - add name publication to network name tables |
b97bf3fd8 [TIPC] Initial merge |
655 |
*/ |
c43072852 [NET] TIPC: Fix w... |
656 |
struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper, |
b97bf3fd8 [TIPC] Initial merge |
657 658 659 660 661 |
u32 scope, u32 port_ref, u32 key) { struct publication *publ; if (table.local_publ_count >= tipc_max_publications) { |
c43072852 [NET] TIPC: Fix w... |
662 663 |
warn("Publication failed, local publication limit reached (%u) ", |
b97bf3fd8 [TIPC] Initial merge |
664 |
tipc_max_publications); |
1fc54d8f4 [TIPC]: Fix simpl... |
665 |
return NULL; |
b97bf3fd8 [TIPC] Initial merge |
666 667 |
} if ((type < TIPC_RESERVED_TYPES) && !atomic_read(&rsv_publ_ok)) { |
f131072c3 [TIPC]: First pha... |
668 669 |
warn("Publication failed, reserved name {%u,%u,%u} ", |
b97bf3fd8 [TIPC] Initial merge |
670 |
type, lower, upper); |
1fc54d8f4 [TIPC]: Fix simpl... |
671 |
return NULL; |
b97bf3fd8 [TIPC] Initial merge |
672 |
} |
4323add67 [TIPC] Avoid poll... |
673 |
write_lock_bh(&tipc_nametbl_lock); |
b97bf3fd8 [TIPC] Initial merge |
674 |
table.local_publ_count++; |
4323add67 [TIPC] Avoid poll... |
675 |
publ = tipc_nametbl_insert_publ(type, lower, upper, scope, |
b97bf3fd8 [TIPC] Initial merge |
676 |
tipc_own_addr, port_ref, key); |
a016892cd tipc: remove extr... |
677 |
if (publ && (scope != TIPC_NODE_SCOPE)) |
4323add67 [TIPC] Avoid poll... |
678 |
tipc_named_publish(publ); |
4323add67 [TIPC] Avoid poll... |
679 |
write_unlock_bh(&tipc_nametbl_lock); |
b97bf3fd8 [TIPC] Initial merge |
680 681 682 683 |
return publ; } /** |
4323add67 [TIPC] Avoid poll... |
684 |
* tipc_nametbl_withdraw - withdraw name publication from network name tables |
b97bf3fd8 [TIPC] Initial merge |
685 |
*/ |
4323add67 [TIPC] Avoid poll... |
686 |
int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key) |
b97bf3fd8 [TIPC] Initial merge |
687 688 |
{ struct publication *publ; |
4323add67 [TIPC] Avoid poll... |
689 690 |
write_lock_bh(&tipc_nametbl_lock); publ = tipc_nametbl_remove_publ(type, lower, tipc_own_addr, ref, key); |
f131072c3 [TIPC]: First pha... |
691 |
if (likely(publ)) { |
b97bf3fd8 [TIPC] Initial merge |
692 693 |
table.local_publ_count--; if (publ->scope != TIPC_NODE_SCOPE) |
4323add67 [TIPC] Avoid poll... |
694 695 |
tipc_named_withdraw(publ); write_unlock_bh(&tipc_nametbl_lock); |
b97bf3fd8 [TIPC] Initial merge |
696 697 698 699 |
list_del_init(&publ->pport_list); kfree(publ); return 1; } |
4323add67 [TIPC] Avoid poll... |
700 |
write_unlock_bh(&tipc_nametbl_lock); |
f131072c3 [TIPC]: First pha... |
701 702 703 704 705 |
err("Unable to remove local publication " "(type=%u, lower=%u, ref=%u, key=%u) ", type, lower, ref, key); |
b97bf3fd8 [TIPC] Initial merge |
706 707 708 709 |
return 0; } /** |
4323add67 [TIPC] Avoid poll... |
710 |
* tipc_nametbl_subscribe - add a subscription object to the name table |
b97bf3fd8 [TIPC] Initial merge |
711 |
*/ |
fead39098 tipc: rename stru... |
712 |
void tipc_nametbl_subscribe(struct tipc_subscription *s) |
b97bf3fd8 [TIPC] Initial merge |
713 714 715 |
{ u32 type = s->seq.type; struct name_seq *seq; |
c43072852 [NET] TIPC: Fix w... |
716 |
write_lock_bh(&tipc_nametbl_lock); |
b97bf3fd8 [TIPC] Initial merge |
717 |
seq = nametbl_find_seq(type); |
a016892cd tipc: remove extr... |
718 |
if (!seq) |
4323add67 [TIPC] Avoid poll... |
719 |
seq = tipc_nameseq_create(type, &table.types[hash(type)]); |
0e65967e3 tipc: cleanup var... |
720 |
if (seq) { |
c43072852 [NET] TIPC: Fix w... |
721 |
spin_lock_bh(&seq->lock); |
c43072852 [NET] TIPC: Fix w... |
722 723 724 |
tipc_nameseq_subscribe(seq, s); spin_unlock_bh(&seq->lock); } else { |
f131072c3 [TIPC]: First pha... |
725 726 727 |
warn("Failed to create subscription for {%u,%u,%u} ", s->seq.type, s->seq.lower, s->seq.upper); |
c43072852 [NET] TIPC: Fix w... |
728 729 |
} write_unlock_bh(&tipc_nametbl_lock); |
b97bf3fd8 [TIPC] Initial merge |
730 731 732 |
} /** |
4323add67 [TIPC] Avoid poll... |
733 |
* tipc_nametbl_unsubscribe - remove a subscription object from name table |
b97bf3fd8 [TIPC] Initial merge |
734 |
*/ |
fead39098 tipc: rename stru... |
735 |
void tipc_nametbl_unsubscribe(struct tipc_subscription *s) |
b97bf3fd8 [TIPC] Initial merge |
736 737 |
{ struct name_seq *seq; |
c43072852 [NET] TIPC: Fix w... |
738 739 |
write_lock_bh(&tipc_nametbl_lock); seq = nametbl_find_seq(s->seq.type); |
0e65967e3 tipc: cleanup var... |
740 |
if (seq != NULL) { |
c43072852 [NET] TIPC: Fix w... |
741 742 743 744 745 746 747 748 749 750 |
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); |
b97bf3fd8 [TIPC] Initial merge |
751 752 753 754 755 756 757 758 759 760 761 |
} /** * subseq_list: print specified sub-sequence contents into the given buffer */ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, u32 index) { char portIdStr[27]; |
c2de58140 tipc: Minor enhan... |
762 |
const char *scope_str[] = {"", " zone", " cluster", " node"}; |
f6f0a4d2d tipc: Convert nam... |
763 764 |
struct publication *publ; struct name_info *info; |
b97bf3fd8 [TIPC] Initial merge |
765 766 |
tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper); |
f6f0a4d2d tipc: Convert nam... |
767 |
if (depth == 2) { |
b97bf3fd8 [TIPC] Initial merge |
768 769 770 771 |
tipc_printf(buf, " "); return; } |
f6f0a4d2d tipc: Convert nam... |
772 773 774 |
info = sseq->info; list_for_each_entry(publ, &info->zone_list, zone_list) { |
0e65967e3 tipc: cleanup var... |
775 |
sprintf(portIdStr, "<%u.%u.%u:%u>", |
b97bf3fd8 [TIPC] Initial merge |
776 777 778 779 |
tipc_zone(publ->node), tipc_cluster(publ->node), tipc_node(publ->node), publ->ref); tipc_printf(buf, "%-26s ", portIdStr); if (depth > 3) { |
c2de58140 tipc: Minor enhan... |
780 781 |
tipc_printf(buf, "%-10u %s", publ->key, scope_str[publ->scope]); |
b97bf3fd8 [TIPC] Initial merge |
782 |
} |
f6f0a4d2d tipc: Convert nam... |
783 784 785 786 |
if (!list_is_last(&publ->zone_list, &info->zone_list)) tipc_printf(buf, " %33s", " "); }; |
b97bf3fd8 [TIPC] Initial merge |
787 788 789 790 791 792 793 794 795 796 797 798 799 800 |
tipc_printf(buf, " "); } /** * nameseq_list: print specified name sequence contents into the given buffer */ static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth, u32 type, u32 lowbound, u32 upbound, u32 index) { struct sub_seq *sseq; char typearea[11]; |
0f15d3645 tipc: Prevent dis... |
801 802 |
if (seq->first_free == 0) return; |
b97bf3fd8 [TIPC] Initial merge |
803 804 805 806 807 808 809 810 811 812 813 |
sprintf(typearea, "%-10u", seq->type); if (depth == 1) { tipc_printf(buf, "%s ", typearea); return; } for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) { if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) { tipc_printf(buf, "%s ", typearea); |
307fdf5e7 tipc: Add missing... |
814 |
spin_lock_bh(&seq->lock); |
b97bf3fd8 [TIPC] Initial merge |
815 |
subseq_list(sseq, buf, depth, index); |
307fdf5e7 tipc: Add missing... |
816 |
spin_unlock_bh(&seq->lock); |
b97bf3fd8 [TIPC] Initial merge |
817 818 819 820 821 822 823 824 825 826 827 |
sprintf(typearea, "%10s", " "); } } } /** * nametbl_header - print name table header into the given buffer */ static void nametbl_header(struct print_buf *buf, u32 depth) { |
c2de58140 tipc: Minor enhan... |
828 829 830 831 832 833 834 835 836 837 838 839 840 |
const char *header[] = { "Type ", "Lower Upper ", "Port Identity ", "Publication Scope" }; int i; if (depth > 4) depth = 4; for (i = 0; i < depth; i++) tipc_printf(buf, header[i]); |
b97bf3fd8 [TIPC] Initial merge |
841 842 843 844 845 846 847 |
tipc_printf(buf, " "); } /** * nametbl_list - print specified name table contents into the given buffer */ |
c43072852 [NET] TIPC: Fix w... |
848 |
static void nametbl_list(struct print_buf *buf, u32 depth_info, |
b97bf3fd8 [TIPC] Initial merge |
849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 |
u32 type, u32 lowbound, u32 upbound) { struct hlist_head *seq_head; struct hlist_node *seq_node; struct name_seq *seq; int all_types; u32 depth; u32 i; all_types = (depth_info & TIPC_NTQ_ALLTYPES); depth = (depth_info & ~TIPC_NTQ_ALLTYPES); if (depth == 0) return; if (all_types) { /* display all entries in name table to specified depth */ nametbl_header(buf, depth); lowbound = 0; upbound = ~0; for (i = 0; i < tipc_nametbl_size; i++) { seq_head = &table.types[i]; hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { |
c43072852 [NET] TIPC: Fix w... |
872 |
nameseq_list(seq, buf, depth, seq->type, |
b97bf3fd8 [TIPC] Initial merge |
873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 |
lowbound, upbound, i); } } } else { /* display only the sequence that matches the specified type */ if (upbound < lowbound) { tipc_printf(buf, "invalid name sequence specified "); return; } nametbl_header(buf, depth); i = hash(type); seq_head = &table.types[i]; hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { if (seq->type == type) { |
c43072852 [NET] TIPC: Fix w... |
888 |
nameseq_list(seq, buf, depth, type, |
b97bf3fd8 [TIPC] Initial merge |
889 890 891 892 893 894 |
lowbound, upbound, i); break; } } } } |
b97bf3fd8 [TIPC] Initial merge |
895 |
#define MAX_NAME_TBL_QUERY 32768 |
4323add67 [TIPC] Avoid poll... |
896 |
struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space) |
b97bf3fd8 [TIPC] Initial merge |
897 898 899 900 901 902 903 904 |
{ struct sk_buff *buf; struct tipc_name_table_query *argv; struct tlv_desc *rep_tlv; struct print_buf b; int str_len; if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NAME_TBL_QUERY)) |
4323add67 [TIPC] Avoid poll... |
905 |
return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); |
b97bf3fd8 [TIPC] Initial merge |
906 |
|
4323add67 [TIPC] Avoid poll... |
907 |
buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_NAME_TBL_QUERY)); |
b97bf3fd8 [TIPC] Initial merge |
908 909 910 911 |
if (!buf) return NULL; rep_tlv = (struct tlv_desc *)buf->data; |
4323add67 [TIPC] Avoid poll... |
912 |
tipc_printbuf_init(&b, TLV_DATA(rep_tlv), MAX_NAME_TBL_QUERY); |
b97bf3fd8 [TIPC] Initial merge |
913 |
argv = (struct tipc_name_table_query *)TLV_DATA(req_tlv_area); |
4323add67 [TIPC] Avoid poll... |
914 |
read_lock_bh(&tipc_nametbl_lock); |
c43072852 [NET] TIPC: Fix w... |
915 |
nametbl_list(&b, ntohl(argv->depth), ntohl(argv->type), |
b97bf3fd8 [TIPC] Initial merge |
916 |
ntohl(argv->lowbound), ntohl(argv->upbound)); |
4323add67 [TIPC] Avoid poll... |
917 918 |
read_unlock_bh(&tipc_nametbl_lock); str_len = tipc_printbuf_validate(&b); |
b97bf3fd8 [TIPC] Initial merge |
919 920 921 922 923 924 |
skb_put(buf, TLV_SPACE(str_len)); TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); return buf; } |
4323add67 [TIPC] Avoid poll... |
925 |
int tipc_nametbl_init(void) |
b97bf3fd8 [TIPC] Initial merge |
926 |
{ |
4e3e6dcb4 tipc: Enhancement... |
927 928 |
table.types = kcalloc(tipc_nametbl_size, sizeof(struct hlist_head), GFP_ATOMIC); |
b97bf3fd8 [TIPC] Initial merge |
929 930 |
if (!table.types) return -ENOMEM; |
b97bf3fd8 [TIPC] Initial merge |
931 |
table.local_publ_count = 0; |
b97bf3fd8 [TIPC] Initial merge |
932 933 |
return 0; } |
4323add67 [TIPC] Avoid poll... |
934 |
void tipc_nametbl_stop(void) |
b97bf3fd8 [TIPC] Initial merge |
935 |
{ |
b97bf3fd8 [TIPC] Initial merge |
936 937 938 939 |
u32 i; if (!table.types) return; |
f131072c3 [TIPC]: First pha... |
940 |
/* Verify name table is empty, then release it */ |
4323add67 [TIPC] Avoid poll... |
941 |
write_lock_bh(&tipc_nametbl_lock); |
b97bf3fd8 [TIPC] Initial merge |
942 |
for (i = 0; i < tipc_nametbl_size; i++) { |
f131072c3 [TIPC]: First pha... |
943 944 945 |
if (!hlist_empty(&table.types[i])) err("tipc_nametbl_stop(): hash chain %u is non-null ", i); |
b97bf3fd8 [TIPC] Initial merge |
946 947 948 |
} kfree(table.types); table.types = NULL; |
4323add67 [TIPC] Avoid poll... |
949 |
write_unlock_bh(&tipc_nametbl_lock); |
b97bf3fd8 [TIPC] Initial merge |
950 |
} |
f131072c3 [TIPC]: First pha... |
951 |