X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fidr.c;h=81fc430602ee8f4c2b4e336a606813ad54b0e5b2;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=972eefcce2b3a9b3ed825bb1b852a92fd3260f38;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/lib/idr.c b/lib/idr.c index 972eefcce..81fc43060 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -39,13 +39,11 @@ static struct idr_layer *alloc_layer(struct idr *idp) struct idr_layer *p; spin_lock(&idp->lock); - if (!(p = idp->id_free)) { - spin_unlock(&idp->lock); - return NULL; + if ((p = idp->id_free)) { + idp->id_free = p->ary[0]; + idp->id_free_cnt--; + p->ary[0] = NULL; } - idp->id_free = p->ary[0]; - idp->id_free_cnt--; - p->ary[0] = NULL; spin_unlock(&idp->lock); return(p); } @@ -277,24 +275,31 @@ int idr_get_new(struct idr *idp, void *ptr, int *id) } EXPORT_SYMBOL(idr_get_new); +static void idr_remove_warning(int id) +{ + printk("idr_remove called for id=%d which is not allocated.\n", id); + dump_stack(); +} + static void sub_remove(struct idr *idp, int shift, int id) { struct idr_layer *p = idp->top; struct idr_layer **pa[MAX_LEVEL]; struct idr_layer ***paa = &pa[0]; + int n; *paa = NULL; *++paa = &idp->top; while ((shift > 0) && p) { - int n = (id >> shift) & IDR_MASK; + n = (id >> shift) & IDR_MASK; __clear_bit(n, &p->bitmap); *++paa = &p->ary[n]; p = p->ary[n]; shift -= IDR_BITS; } - if (likely(p != NULL)){ - int n = id & IDR_MASK; + n = id & IDR_MASK; + if (likely(p != NULL && test_bit(n, &p->bitmap))){ __clear_bit(n, &p->bitmap); p->ary[n] = NULL; while(*paa && ! --((**paa)->count)){ @@ -303,6 +308,8 @@ static void sub_remove(struct idr *idp, int shift, int id) } if ( ! *paa ) idp->layers = 0; + } else { + idr_remove_warning(id); } }