.. | .. |
---|
93 | 93 | newnode->next = prev->next; |
---|
94 | 94 | prev->next = newnode; |
---|
95 | 95 | } else { |
---|
96 | | - newnode->next = flex_array_get_ptr(h->htable, hvalue); |
---|
97 | | - if (flex_array_put_ptr(h->htable, hvalue, newnode, |
---|
98 | | - GFP_KERNEL|__GFP_ZERO)) { |
---|
99 | | - kmem_cache_free(avtab_node_cachep, newnode); |
---|
100 | | - return NULL; |
---|
101 | | - } |
---|
| 96 | + struct avtab_node **n = &h->htable[hvalue]; |
---|
| 97 | + |
---|
| 98 | + newnode->next = *n; |
---|
| 99 | + *n = newnode; |
---|
102 | 100 | } |
---|
103 | 101 | |
---|
104 | 102 | h->nel++; |
---|
.. | .. |
---|
111 | 109 | struct avtab_node *prev, *cur, *newnode; |
---|
112 | 110 | u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); |
---|
113 | 111 | |
---|
114 | | - if (!h || !h->htable) |
---|
| 112 | + if (!h || !h->nslot) |
---|
115 | 113 | return -EINVAL; |
---|
116 | 114 | |
---|
117 | 115 | hvalue = avtab_hash(key, h->mask); |
---|
118 | | - for (prev = NULL, cur = flex_array_get_ptr(h->htable, hvalue); |
---|
| 116 | + for (prev = NULL, cur = h->htable[hvalue]; |
---|
119 | 117 | cur; |
---|
120 | 118 | prev = cur, cur = cur->next) { |
---|
121 | 119 | if (key->source_type == cur->key.source_type && |
---|
.. | .. |
---|
156 | 154 | struct avtab_node *prev, *cur; |
---|
157 | 155 | u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); |
---|
158 | 156 | |
---|
159 | | - if (!h || !h->htable) |
---|
| 157 | + if (!h || !h->nslot) |
---|
160 | 158 | return NULL; |
---|
161 | 159 | hvalue = avtab_hash(key, h->mask); |
---|
162 | | - for (prev = NULL, cur = flex_array_get_ptr(h->htable, hvalue); |
---|
| 160 | + for (prev = NULL, cur = h->htable[hvalue]; |
---|
163 | 161 | cur; |
---|
164 | 162 | prev = cur, cur = cur->next) { |
---|
165 | 163 | if (key->source_type == cur->key.source_type && |
---|
.. | .. |
---|
186 | 184 | struct avtab_node *cur; |
---|
187 | 185 | u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); |
---|
188 | 186 | |
---|
189 | | - if (!h || !h->htable) |
---|
| 187 | + if (!h || !h->nslot) |
---|
190 | 188 | return NULL; |
---|
191 | 189 | |
---|
192 | 190 | hvalue = avtab_hash(key, h->mask); |
---|
193 | | - for (cur = flex_array_get_ptr(h->htable, hvalue); cur; |
---|
| 191 | + for (cur = h->htable[hvalue]; cur; |
---|
194 | 192 | cur = cur->next) { |
---|
195 | 193 | if (key->source_type == cur->key.source_type && |
---|
196 | 194 | key->target_type == cur->key.target_type && |
---|
.. | .. |
---|
222 | 220 | struct avtab_node *cur; |
---|
223 | 221 | u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); |
---|
224 | 222 | |
---|
225 | | - if (!h || !h->htable) |
---|
| 223 | + if (!h || !h->nslot) |
---|
226 | 224 | return NULL; |
---|
227 | 225 | |
---|
228 | 226 | hvalue = avtab_hash(key, h->mask); |
---|
229 | | - for (cur = flex_array_get_ptr(h->htable, hvalue); cur; |
---|
| 227 | + for (cur = h->htable[hvalue]; cur; |
---|
230 | 228 | cur = cur->next) { |
---|
231 | 229 | if (key->source_type == cur->key.source_type && |
---|
232 | 230 | key->target_type == cur->key.target_type && |
---|
.. | .. |
---|
281 | 279 | int i; |
---|
282 | 280 | struct avtab_node *cur, *temp; |
---|
283 | 281 | |
---|
284 | | - if (!h || !h->htable) |
---|
| 282 | + if (!h) |
---|
285 | 283 | return; |
---|
286 | 284 | |
---|
287 | 285 | for (i = 0; i < h->nslot; i++) { |
---|
288 | | - cur = flex_array_get_ptr(h->htable, i); |
---|
| 286 | + cur = h->htable[i]; |
---|
289 | 287 | while (cur) { |
---|
290 | 288 | temp = cur; |
---|
291 | 289 | cur = cur->next; |
---|
.. | .. |
---|
295 | 293 | kmem_cache_free(avtab_node_cachep, temp); |
---|
296 | 294 | } |
---|
297 | 295 | } |
---|
298 | | - flex_array_free(h->htable); |
---|
| 296 | + kvfree(h->htable); |
---|
299 | 297 | h->htable = NULL; |
---|
| 298 | + h->nel = 0; |
---|
300 | 299 | h->nslot = 0; |
---|
301 | 300 | h->mask = 0; |
---|
302 | 301 | } |
---|
303 | 302 | |
---|
304 | | -int avtab_init(struct avtab *h) |
---|
| 303 | +void avtab_init(struct avtab *h) |
---|
305 | 304 | { |
---|
306 | 305 | h->htable = NULL; |
---|
307 | 306 | h->nel = 0; |
---|
| 307 | + h->nslot = 0; |
---|
| 308 | + h->mask = 0; |
---|
| 309 | +} |
---|
| 310 | + |
---|
| 311 | +static int avtab_alloc_common(struct avtab *h, u32 nslot) |
---|
| 312 | +{ |
---|
| 313 | + if (!nslot) |
---|
| 314 | + return 0; |
---|
| 315 | + |
---|
| 316 | + h->htable = kvcalloc(nslot, sizeof(void *), GFP_KERNEL); |
---|
| 317 | + if (!h->htable) |
---|
| 318 | + return -ENOMEM; |
---|
| 319 | + |
---|
| 320 | + h->nslot = nslot; |
---|
| 321 | + h->mask = nslot - 1; |
---|
308 | 322 | return 0; |
---|
309 | 323 | } |
---|
310 | 324 | |
---|
311 | 325 | int avtab_alloc(struct avtab *h, u32 nrules) |
---|
312 | 326 | { |
---|
313 | | - u32 mask = 0; |
---|
314 | | - u32 shift = 0; |
---|
315 | | - u32 work = nrules; |
---|
| 327 | + int rc; |
---|
316 | 328 | u32 nslot = 0; |
---|
317 | 329 | |
---|
318 | | - if (nrules == 0) |
---|
319 | | - goto avtab_alloc_out; |
---|
| 330 | + if (nrules != 0) { |
---|
| 331 | + u32 shift = 1; |
---|
| 332 | + u32 work = nrules >> 3; |
---|
| 333 | + while (work) { |
---|
| 334 | + work >>= 1; |
---|
| 335 | + shift++; |
---|
| 336 | + } |
---|
| 337 | + nslot = 1 << shift; |
---|
| 338 | + if (nslot > MAX_AVTAB_HASH_BUCKETS) |
---|
| 339 | + nslot = MAX_AVTAB_HASH_BUCKETS; |
---|
320 | 340 | |
---|
321 | | - while (work) { |
---|
322 | | - work = work >> 1; |
---|
323 | | - shift++; |
---|
| 341 | + rc = avtab_alloc_common(h, nslot); |
---|
| 342 | + if (rc) |
---|
| 343 | + return rc; |
---|
324 | 344 | } |
---|
325 | | - if (shift > 2) |
---|
326 | | - shift = shift - 2; |
---|
327 | | - nslot = 1 << shift; |
---|
328 | | - if (nslot > MAX_AVTAB_HASH_BUCKETS) |
---|
329 | | - nslot = MAX_AVTAB_HASH_BUCKETS; |
---|
330 | | - mask = nslot - 1; |
---|
331 | 345 | |
---|
332 | | - h->htable = flex_array_alloc(sizeof(struct avtab_node *), nslot, |
---|
333 | | - GFP_KERNEL | __GFP_ZERO); |
---|
334 | | - if (!h->htable) |
---|
335 | | - return -ENOMEM; |
---|
336 | | - |
---|
337 | | - avtab_alloc_out: |
---|
338 | | - h->nel = 0; |
---|
339 | | - h->nslot = nslot; |
---|
340 | | - h->mask = mask; |
---|
341 | | - pr_debug("SELinux: %d avtab hash slots, %d rules.\n", |
---|
342 | | - h->nslot, nrules); |
---|
| 346 | + pr_debug("SELinux: %d avtab hash slots, %d rules.\n", nslot, nrules); |
---|
343 | 347 | return 0; |
---|
| 348 | +} |
---|
| 349 | + |
---|
| 350 | +int avtab_alloc_dup(struct avtab *new, const struct avtab *orig) |
---|
| 351 | +{ |
---|
| 352 | + return avtab_alloc_common(new, orig->nslot); |
---|
344 | 353 | } |
---|
345 | 354 | |
---|
346 | 355 | void avtab_hash_eval(struct avtab *h, char *tag) |
---|
.. | .. |
---|
353 | 362 | max_chain_len = 0; |
---|
354 | 363 | chain2_len_sum = 0; |
---|
355 | 364 | for (i = 0; i < h->nslot; i++) { |
---|
356 | | - cur = flex_array_get_ptr(h->htable, i); |
---|
| 365 | + cur = h->htable[i]; |
---|
357 | 366 | if (cur) { |
---|
358 | 367 | slots_used++; |
---|
359 | 368 | chain_len = 0; |
---|
.. | .. |
---|
646 | 655 | return rc; |
---|
647 | 656 | |
---|
648 | 657 | for (i = 0; i < a->nslot; i++) { |
---|
649 | | - for (cur = flex_array_get_ptr(a->htable, i); cur; |
---|
| 658 | + for (cur = a->htable[i]; cur; |
---|
650 | 659 | cur = cur->next) { |
---|
651 | 660 | rc = avtab_write_item(p, cur, fp); |
---|
652 | 661 | if (rc) |
---|