aboutsummaryrefslogtreecommitdiffstats
path: root/lib/idr.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/idr.c')
-rw-r--r--lib/idr.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/lib/idr.c b/lib/idr.c
index d29da6159dae..5ca67b3cfd35 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -391,6 +391,53 @@ void idr_remove(struct idr *idp, int id)
391EXPORT_SYMBOL(idr_remove); 391EXPORT_SYMBOL(idr_remove);
392 392
393/** 393/**
394 * idr_remove_all - remove all ids from the given idr tree
395 * @idp: idr handle
396 *
397 * idr_destroy() only frees up unused, cached idp_layers, but this
398 * function will remove all id mappings and leave all idp_layers
399 * unused.
400 *
401 * A typical clean-up sequence for objects stored in an idr tree, will
402 * use idr_for_each() to free all objects, if necessay, then
403 * idr_remove_all() to remove all ids, and idr_destroy() to free
404 * up the cached idr_layers.
405 */
406void idr_remove_all(struct idr *idp)
407{
408 int n, id, max, error = 0;
409 struct idr_layer *p;
410 struct idr_layer *pa[MAX_LEVEL];
411 struct idr_layer **paa = &pa[0];
412
413 n = idp->layers * IDR_BITS;
414 p = idp->top;
415 max = 1 << n;
416
417 id = 0;
418 while (id < max && !error) {
419 while (n > IDR_BITS && p) {
420 n -= IDR_BITS;
421 *paa++ = p;
422 p = p->ary[(id >> n) & IDR_MASK];
423 }
424
425 id += 1 << n;
426 while (n < fls(id)) {
427 if (p) {
428 memset(p, 0, sizeof *p);
429 free_layer(idp, p);
430 }
431 n += IDR_BITS;
432 p = *--paa;
433 }
434 }
435 idp->top = NULL;
436 idp->layers = 0;
437}
438EXPORT_SYMBOL(idr_remove_all);
439
440/**
394 * idr_destroy - release all cached layers within an idr tree 441 * idr_destroy - release all cached layers within an idr tree
395 * idp: idr handle 442 * idp: idr handle
396 */ 443 */