|
@@ -823,8 +823,8 @@ unsigned long radix_tree_prev_hole(struct radix_tree_root *root,
|
|
|
EXPORT_SYMBOL(radix_tree_prev_hole);
|
|
|
|
|
|
static unsigned int
|
|
|
-__lookup(struct radix_tree_node *slot, void ***results, unsigned long index,
|
|
|
- unsigned int max_items, unsigned long *next_index)
|
|
|
+__lookup(struct radix_tree_node *slot, void ***results, unsigned long *indices,
|
|
|
+ unsigned long index, unsigned int max_items, unsigned long *next_index)
|
|
|
{
|
|
|
unsigned int nr_found = 0;
|
|
|
unsigned int shift, height;
|
|
@@ -857,12 +857,16 @@ __lookup(struct radix_tree_node *slot, void ***results, unsigned long index,
|
|
|
|
|
|
/* Bottom level: grab some items */
|
|
|
for (i = index & RADIX_TREE_MAP_MASK; i < RADIX_TREE_MAP_SIZE; i++) {
|
|
|
- index++;
|
|
|
if (slot->slots[i]) {
|
|
|
- results[nr_found++] = &(slot->slots[i]);
|
|
|
- if (nr_found == max_items)
|
|
|
+ results[nr_found] = &(slot->slots[i]);
|
|
|
+ if (indices)
|
|
|
+ indices[nr_found] = index;
|
|
|
+ if (++nr_found == max_items) {
|
|
|
+ index++;
|
|
|
goto out;
|
|
|
+ }
|
|
|
}
|
|
|
+ index++;
|
|
|
}
|
|
|
out:
|
|
|
*next_index = index;
|
|
@@ -918,8 +922,8 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
|
|
|
|
|
|
if (cur_index > max_index)
|
|
|
break;
|
|
|
- slots_found = __lookup(node, (void ***)results + ret, cur_index,
|
|
|
- max_items - ret, &next_index);
|
|
|
+ slots_found = __lookup(node, (void ***)results + ret, NULL,
|
|
|
+ cur_index, max_items - ret, &next_index);
|
|
|
nr_found = 0;
|
|
|
for (i = 0; i < slots_found; i++) {
|
|
|
struct radix_tree_node *slot;
|
|
@@ -944,6 +948,7 @@ EXPORT_SYMBOL(radix_tree_gang_lookup);
|
|
|
* radix_tree_gang_lookup_slot - perform multiple slot lookup on radix tree
|
|
|
* @root: radix tree root
|
|
|
* @results: where the results of the lookup are placed
|
|
|
+ * @indices: where their indices should be placed (but usually NULL)
|
|
|
* @first_index: start the lookup from this key
|
|
|
* @max_items: place up to this many items at *results
|
|
|
*
|
|
@@ -958,7 +963,8 @@ EXPORT_SYMBOL(radix_tree_gang_lookup);
|
|
|
* protection, radix_tree_deref_slot may fail requiring a retry.
|
|
|
*/
|
|
|
unsigned int
|
|
|
-radix_tree_gang_lookup_slot(struct radix_tree_root *root, void ***results,
|
|
|
+radix_tree_gang_lookup_slot(struct radix_tree_root *root,
|
|
|
+ void ***results, unsigned long *indices,
|
|
|
unsigned long first_index, unsigned int max_items)
|
|
|
{
|
|
|
unsigned long max_index;
|
|
@@ -974,6 +980,8 @@ radix_tree_gang_lookup_slot(struct radix_tree_root *root, void ***results,
|
|
|
if (first_index > 0)
|
|
|
return 0;
|
|
|
results[0] = (void **)&root->rnode;
|
|
|
+ if (indices)
|
|
|
+ indices[0] = 0;
|
|
|
return 1;
|
|
|
}
|
|
|
node = indirect_to_ptr(node);
|
|
@@ -987,8 +995,9 @@ radix_tree_gang_lookup_slot(struct radix_tree_root *root, void ***results,
|
|
|
|
|
|
if (cur_index > max_index)
|
|
|
break;
|
|
|
- slots_found = __lookup(node, results + ret, cur_index,
|
|
|
- max_items - ret, &next_index);
|
|
|
+ slots_found = __lookup(node, results + ret,
|
|
|
+ indices ? indices + ret : NULL,
|
|
|
+ cur_index, max_items - ret, &next_index);
|
|
|
ret += slots_found;
|
|
|
if (next_index == 0)
|
|
|
break;
|