|
@@ -185,6 +185,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa)
|
|
new = get_from_free_list(idp);
|
|
new = get_from_free_list(idp);
|
|
if (!new)
|
|
if (!new)
|
|
return -1;
|
|
return -1;
|
|
|
|
+ new->layer = l-1;
|
|
rcu_assign_pointer(p->ary[m], new);
|
|
rcu_assign_pointer(p->ary[m], new);
|
|
p->count++;
|
|
p->count++;
|
|
}
|
|
}
|
|
@@ -210,6 +211,7 @@ build_up:
|
|
if (unlikely(!p)) {
|
|
if (unlikely(!p)) {
|
|
if (!(p = get_from_free_list(idp)))
|
|
if (!(p = get_from_free_list(idp)))
|
|
return -1;
|
|
return -1;
|
|
|
|
+ p->layer = 0;
|
|
layers = 1;
|
|
layers = 1;
|
|
}
|
|
}
|
|
/*
|
|
/*
|
|
@@ -237,6 +239,7 @@ build_up:
|
|
}
|
|
}
|
|
new->ary[0] = p;
|
|
new->ary[0] = p;
|
|
new->count = 1;
|
|
new->count = 1;
|
|
|
|
+ new->layer = layers-1;
|
|
if (p->bitmap == IDR_FULL)
|
|
if (p->bitmap == IDR_FULL)
|
|
__set_bit(0, &new->bitmap);
|
|
__set_bit(0, &new->bitmap);
|
|
p = new;
|
|
p = new;
|
|
@@ -493,17 +496,21 @@ void *idr_find(struct idr *idp, int id)
|
|
int n;
|
|
int n;
|
|
struct idr_layer *p;
|
|
struct idr_layer *p;
|
|
|
|
|
|
- n = idp->layers * IDR_BITS;
|
|
|
|
p = rcu_dereference(idp->top);
|
|
p = rcu_dereference(idp->top);
|
|
|
|
+ if (!p)
|
|
|
|
+ return NULL;
|
|
|
|
+ n = (p->layer+1) * IDR_BITS;
|
|
|
|
|
|
/* Mask off upper bits we don't use for the search. */
|
|
/* Mask off upper bits we don't use for the search. */
|
|
id &= MAX_ID_MASK;
|
|
id &= MAX_ID_MASK;
|
|
|
|
|
|
if (id >= (1 << n))
|
|
if (id >= (1 << n))
|
|
return NULL;
|
|
return NULL;
|
|
|
|
+ BUG_ON(n == 0);
|
|
|
|
|
|
while (n > 0 && p) {
|
|
while (n > 0 && p) {
|
|
n -= IDR_BITS;
|
|
n -= IDR_BITS;
|
|
|
|
+ BUG_ON(n != p->layer*IDR_BITS);
|
|
p = rcu_dereference(p->ary[(id >> n) & IDR_MASK]);
|
|
p = rcu_dereference(p->ary[(id >> n) & IDR_MASK]);
|
|
}
|
|
}
|
|
return((void *)p);
|
|
return((void *)p);
|
|
@@ -582,8 +589,11 @@ void *idr_replace(struct idr *idp, void *ptr, int id)
|
|
int n;
|
|
int n;
|
|
struct idr_layer *p, *old_p;
|
|
struct idr_layer *p, *old_p;
|
|
|
|
|
|
- n = idp->layers * IDR_BITS;
|
|
|
|
p = idp->top;
|
|
p = idp->top;
|
|
|
|
+ if (!p)
|
|
|
|
+ return ERR_PTR(-EINVAL);
|
|
|
|
+
|
|
|
|
+ n = (p->layer+1) * IDR_BITS;
|
|
|
|
|
|
id &= MAX_ID_MASK;
|
|
id &= MAX_ID_MASK;
|
|
|
|
|