diff options
Diffstat (limited to 'lib/idr.c')
| -rw-r--r-- | lib/idr.c | 16 | 
1 files changed, 9 insertions, 7 deletions
| @@ -156,10 +156,12 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa) | |||
| 156 | id = (id | ((1 << (IDR_BITS * l)) - 1)) + 1; | 156 | id = (id | ((1 << (IDR_BITS * l)) - 1)) + 1; | 
| 157 | 157 | ||
| 158 | /* if already at the top layer, we need to grow */ | 158 | /* if already at the top layer, we need to grow */ | 
| 159 | if (!(p = pa[l])) { | 159 | if (id >= 1 << (idp->layers * IDR_BITS)) { | 
| 160 | *starting_id = id; | 160 | *starting_id = id; | 
| 161 | return IDR_NEED_TO_GROW; | 161 | return IDR_NEED_TO_GROW; | 
| 162 | } | 162 | } | 
| 163 | p = pa[l]; | ||
| 164 | BUG_ON(!p); | ||
| 163 | 165 | ||
| 164 | /* If we need to go up one layer, continue the | 166 | /* If we need to go up one layer, continue the | 
| 165 | * loop; otherwise, restart from the top. | 167 | * loop; otherwise, restart from the top. | 
| @@ -281,7 +283,7 @@ static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id) | |||
| 281 | /** | 283 | /** | 
| 282 | * idr_get_new_above - allocate new idr entry above or equal to a start id | 284 | * idr_get_new_above - allocate new idr entry above or equal to a start id | 
| 283 | * @idp: idr handle | 285 | * @idp: idr handle | 
| 284 | * @ptr: pointer you want associated with the ide | 286 | * @ptr: pointer you want associated with the id | 
| 285 | * @start_id: id to start search at | 287 | * @start_id: id to start search at | 
| 286 | * @id: pointer to the allocated handle | 288 | * @id: pointer to the allocated handle | 
| 287 | * | 289 | * | 
| @@ -313,7 +315,7 @@ EXPORT_SYMBOL(idr_get_new_above); | |||
| 313 | /** | 315 | /** | 
| 314 | * idr_get_new - allocate new idr entry | 316 | * idr_get_new - allocate new idr entry | 
| 315 | * @idp: idr handle | 317 | * @idp: idr handle | 
| 316 | * @ptr: pointer you want associated with the ide | 318 | * @ptr: pointer you want associated with the id | 
| 317 | * @id: pointer to the allocated handle | 319 | * @id: pointer to the allocated handle | 
| 318 | * | 320 | * | 
| 319 | * This is the allocate id function. It should be called with any | 321 | * This is the allocate id function. It should be called with any | 
| @@ -502,7 +504,7 @@ void *idr_find(struct idr *idp, int id) | |||
| 502 | int n; | 504 | int n; | 
| 503 | struct idr_layer *p; | 505 | struct idr_layer *p; | 
| 504 | 506 | ||
| 505 | p = rcu_dereference(idp->top); | 507 | p = rcu_dereference_raw(idp->top); | 
| 506 | if (!p) | 508 | if (!p) | 
| 507 | return NULL; | 509 | return NULL; | 
| 508 | n = (p->layer+1) * IDR_BITS; | 510 | n = (p->layer+1) * IDR_BITS; | 
| @@ -517,7 +519,7 @@ void *idr_find(struct idr *idp, int id) | |||
| 517 | while (n > 0 && p) { | 519 | while (n > 0 && p) { | 
| 518 | n -= IDR_BITS; | 520 | n -= IDR_BITS; | 
| 519 | BUG_ON(n != p->layer*IDR_BITS); | 521 | BUG_ON(n != p->layer*IDR_BITS); | 
| 520 | p = rcu_dereference(p->ary[(id >> n) & IDR_MASK]); | 522 | p = rcu_dereference_raw(p->ary[(id >> n) & IDR_MASK]); | 
| 521 | } | 523 | } | 
| 522 | return((void *)p); | 524 | return((void *)p); | 
| 523 | } | 525 | } | 
| @@ -550,7 +552,7 @@ int idr_for_each(struct idr *idp, | |||
| 550 | struct idr_layer **paa = &pa[0]; | 552 | struct idr_layer **paa = &pa[0]; | 
| 551 | 553 | ||
| 552 | n = idp->layers * IDR_BITS; | 554 | n = idp->layers * IDR_BITS; | 
| 553 | p = rcu_dereference(idp->top); | 555 | p = rcu_dereference_raw(idp->top); | 
| 554 | max = 1 << n; | 556 | max = 1 << n; | 
| 555 | 557 | ||
| 556 | id = 0; | 558 | id = 0; | 
| @@ -558,7 +560,7 @@ int idr_for_each(struct idr *idp, | |||
| 558 | while (n > 0 && p) { | 560 | while (n > 0 && p) { | 
| 559 | n -= IDR_BITS; | 561 | n -= IDR_BITS; | 
| 560 | *paa++ = p; | 562 | *paa++ = p; | 
| 561 | p = rcu_dereference(p->ary[(id >> n) & IDR_MASK]); | 563 | p = rcu_dereference_raw(p->ary[(id >> n) & IDR_MASK]); | 
| 562 | } | 564 | } | 
| 563 | 565 | ||
| 564 | if (p) { | 566 | if (p) { | 
