From 9f512a765988104efff73515cdd8a972ae3e29cb Mon Sep 17 00:00:00 2001 From: Vinayak Menon Date: Mon, 20 Jul 2015 10:53:19 +0530 Subject: [PATCH] radix-tree: add radix_tree_gang_lookup_index Add radix_tree_gang_lookup_index to get the radix tree indices along with the pointers. This will be helpful, for e.g. if a radix_tree_delete has to be performed depending on one of the result values. Change-Id: Iab83d027968462aa30da5341fa3f60134b6c1137 Signed-off-by: Vinayak Menon Signed-off-by: Kevin F. Haggerty --- include/linux/radix-tree.h | 4 ++++ lib/radix-tree.c | 43 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index ffc444c38b0..9f72d1f2604 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -223,6 +223,10 @@ void *radix_tree_delete(struct radix_tree_root *, unsigned long); unsigned int radix_tree_gang_lookup(struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items); +unsigned int +radix_tree_gang_lookup_index(struct radix_tree_root *root, void **results, + unsigned long *indices, unsigned long first_index, + unsigned int max_items); unsigned int radix_tree_gang_lookup_slot(struct radix_tree_root *root, void ***results, unsigned long *indices, unsigned long first_index, unsigned int max_items); diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 3ac50dc5563..55733cd1b82 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c @@ -1013,6 +1013,49 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results, } EXPORT_SYMBOL(radix_tree_gang_lookup); +/** + * radix_tree_gang_lookup_index - perform multiple lookup on a radix tree + * @root: radix tree root + * @results: where the results of the lookup are placed + * @indices: where their indices should be placed + * @first_index: start the lookup from this key + * @max_items: place up to this many items at *results + * + * Performs an index-ascending scan of the tree for present items. Places + * them at *@results and returns the number of items which were placed at + * *@results. The indices are placed in @indices. + * + * The implementation is naive. + * + * Just one difference from radix_tree_gang_lookup, the indices are also + * collected along with the results of lookup. + */ +unsigned int +radix_tree_gang_lookup_index(struct radix_tree_root *root, void **results, + unsigned long *indices, unsigned long first_index, + unsigned int max_items) +{ + struct radix_tree_iter iter; + void **slot; + unsigned int ret = 0; + + if (unlikely(!max_items)) + return 0; + + radix_tree_for_each_slot(slot, root, &iter, first_index) { + results[ret] = indirect_to_ptr(rcu_dereference_raw(*slot)); + if (!results[ret]) + continue; + if (indices) + indices[ret] = iter.index; + if (++ret == max_items) + break; + } + + return ret; +} +EXPORT_SYMBOL(radix_tree_gang_lookup_index); + /** * radix_tree_gang_lookup_slot - perform multiple slot lookup on radix tree * @root: radix tree root