diff options
Diffstat (limited to 'lib/idr.c')
| -rw-r--r-- | lib/idr.c | 46 |
1 files changed, 46 insertions, 0 deletions
| @@ -579,6 +579,52 @@ int idr_for_each(struct idr *idp, | |||
| 579 | EXPORT_SYMBOL(idr_for_each); | 579 | EXPORT_SYMBOL(idr_for_each); |
| 580 | 580 | ||
| 581 | /** | 581 | /** |
| 582 | * idr_get_next - lookup next object of id to given id. | ||
| 583 | * @idp: idr handle | ||
| 584 | * @id: pointer to lookup key | ||
| 585 | * | ||
| 586 | * Returns pointer to registered object with id, which is next number to | ||
| 587 | * given id. | ||
| 588 | */ | ||
| 589 | |||
| 590 | void *idr_get_next(struct idr *idp, int *nextidp) | ||
| 591 | { | ||
| 592 | struct idr_layer *p, *pa[MAX_LEVEL]; | ||
| 593 | struct idr_layer **paa = &pa[0]; | ||
| 594 | int id = *nextidp; | ||
| 595 | int n, max; | ||
| 596 | |||
| 597 | /* find first ent */ | ||
| 598 | n = idp->layers * IDR_BITS; | ||
| 599 | max = 1 << n; | ||
| 600 | p = rcu_dereference(idp->top); | ||
| 601 | if (!p) | ||
| 602 | return NULL; | ||
| 603 | |||
| 604 | while (id < max) { | ||
| 605 | while (n > 0 && p) { | ||
| 606 | n -= IDR_BITS; | ||
| 607 | *paa++ = p; | ||
| 608 | p = rcu_dereference(p->ary[(id >> n) & IDR_MASK]); | ||
| 609 | } | ||
| 610 | |||
| 611 | if (p) { | ||
| 612 | *nextidp = id; | ||
| 613 | return p; | ||
| 614 | } | ||
| 615 | |||
| 616 | id += 1 << n; | ||
| 617 | while (n < fls(id)) { | ||
| 618 | n += IDR_BITS; | ||
| 619 | p = *--paa; | ||
| 620 | } | ||
| 621 | } | ||
| 622 | return NULL; | ||
| 623 | } | ||
| 624 | |||
| 625 | |||
| 626 | |||
| 627 | /** | ||
| 582 | * idr_replace - replace pointer for given id | 628 | * idr_replace - replace pointer for given id |
| 583 | * @idp: idr handle | 629 | * @idp: idr handle |
| 584 | * @ptr: pointer you want associated with the id | 630 | * @ptr: pointer you want associated with the id |
