int idr_alloc(struct idr *, void *ptr, int start, int end, gfp_t);
void *idr_remove(struct idr *, unsigned long id);
void *idr_find(const struct idr *, unsigned long id);
-int idr_for_each(const struct idr *,
- int (*fn)(int id, void *p, void *data), void *data);
void *idr_get_next(struct idr *, int *nextid);
void idr_destroy(struct idr *);
}
EXPORT_SYMBOL_GPL(idr_find);
-/**
- * idr_for_each() - Iterate through all stored pointers.
- * @idr: IDR handle.
- * @fn: Function to be called for each pointer.
- * @data: Data passed to callback function.
- *
- * The callback function will be called for each entry in @idr, passing
- * the ID, the entry and @data.
- *
- * If @fn returns anything other than %0, the iteration stops and that
- * value is returned from this function.
- *
- * idr_for_each() can be called concurrently with idr_alloc() and
- * idr_remove() if protected by RCU. Newly added entries may not be
- * seen and deleted entries may be seen, but adding and removing entries
- * will not cause other entries to be skipped, nor spurious ones to be seen.
- */
-int idr_for_each(const struct idr *idr,
- int (*fn)(int id, void *p, void *data), void *data)
-{
- struct radix_tree_iter iter;
- void __rcu **slot;
- int base = idr->idr_base;
-
- radix_tree_for_each_slot(slot, &idr->idr_rt, &iter, 0) {
- int ret;
- unsigned long id = iter.index + base;
-
- if (WARN_ON_ONCE(id > INT_MAX))
- break;
- ret = fn(id, rcu_dereference_raw(*slot), data);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(idr_for_each);
-
/**
* idr_get_next() - Find next populated entry.
* @idr: IDR handle.
{
unsigned long i;
int nextid;
+ struct item *item;
DEFINE_IDR(idr);
idr_init_base(&idr, base);
int indices[] = {4, 7, 9, 15, 65, 128, 1000, 99999, 0};
for(i = 0; indices[i]; i++) {
- struct item *item = item_create(indices[i], 0);
+ item = item_create(indices[i], 0);
assert(idr_alloc(&idr, item, indices[i], indices[i+1],
GFP_KERNEL) == indices[i]);
}
nextid++;
}
- idr_for_each(&idr, item_idr_free, &idr);
+ idr_for_each_entry(&idr, item, nextid)
+ item_idr_free(nextid, item, &idr);
idr_destroy(&idr);
}
void idr_checks(void)
{
unsigned long i;
+ int id;
+ struct item *item;
DEFINE_IDR(idr);
for (i = 0; i < 10000; i++) {
- struct item *item = item_create(i, 0);
+ item = item_create(i, 0);
assert(idr_alloc(&idr, item, 0, 20000, GFP_KERNEL) == i);
}
idr_remove(&idr, 3);
- idr_for_each(&idr, item_idr_free, &idr);
+ idr_for_each_entry(&idr, item, id)
+ item_idr_free(id, item, &idr);
idr_destroy(&idr);
assert(idr_is_empty(&idr));
idr_destroy(&idr);
for (i = INT_MAX - 3UL; i < INT_MAX + 1UL; i++) {
- struct item *item = item_create(i, 0);
+ item = item_create(i, 0);
assert(idr_alloc(&idr, item, i, i + 10, GFP_KERNEL) == i);
}
assert(idr_alloc(&idr, DUMMY_PTR, i - 2, i, GFP_KERNEL) == -ENOSPC);
assert(idr_alloc(&idr, DUMMY_PTR, i - 2, i + 10, GFP_KERNEL) == -ENOSPC);
- idr_for_each(&idr, item_idr_free, &idr);
+ idr_for_each_entry(&idr, item, id)
+ item_idr_free(id, item, &idr);
idr_destroy(&idr);
idr_destroy(&idr);
assert(idr_is_empty(&idr));
for (i = 1; i < 10000; i++) {
- struct item *item = item_create(i, 0);
+ item = item_create(i, 0);
assert(idr_alloc(&idr, item, 1, 20000, GFP_KERNEL) == i);
}
- idr_for_each(&idr, item_idr_free, &idr);
+ idr_for_each_entry(&idr, item, id)
+ item_idr_free(id, item, &idr);
idr_destroy(&idr);
idr_null_test();