aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/radix-tree.h1
-rw-r--r--lib/radix-tree.c51
2 files changed, 39 insertions, 13 deletions
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index 9f0f9281f42a..36e5d269612f 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -46,6 +46,7 @@ do { \
46 46
47int radix_tree_insert(struct radix_tree_root *, unsigned long, void *); 47int radix_tree_insert(struct radix_tree_root *, unsigned long, void *);
48void *radix_tree_lookup(struct radix_tree_root *, unsigned long); 48void *radix_tree_lookup(struct radix_tree_root *, unsigned long);
49void **radix_tree_lookup_slot(struct radix_tree_root *, unsigned long);
49void *radix_tree_delete(struct radix_tree_root *, unsigned long); 50void *radix_tree_delete(struct radix_tree_root *, unsigned long);
50unsigned int 51unsigned int
51radix_tree_gang_lookup(struct radix_tree_root *root, void **results, 52radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index d1c057e71b68..88511c3805ad 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -281,35 +281,60 @@ int radix_tree_insert(struct radix_tree_root *root,
281} 281}
282EXPORT_SYMBOL(radix_tree_insert); 282EXPORT_SYMBOL(radix_tree_insert);
283 283
284/** 284static inline void **__lookup_slot(struct radix_tree_root *root,
285 * radix_tree_lookup - perform lookup operation on a radix tree 285 unsigned long index)
286 * @root: radix tree root
287 * @index: index key
288 *
289 * Lookup the item at the position @index in the radix tree @root.
290 */
291void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index)
292{ 286{
293 unsigned int height, shift; 287 unsigned int height, shift;
294 struct radix_tree_node *slot; 288 struct radix_tree_node **slot;
295 289
296 height = root->height; 290 height = root->height;
297 if (index > radix_tree_maxindex(height)) 291 if (index > radix_tree_maxindex(height))
298 return NULL; 292 return NULL;
299 293
300 shift = (height-1) * RADIX_TREE_MAP_SHIFT; 294 shift = (height-1) * RADIX_TREE_MAP_SHIFT;
301 slot = root->rnode; 295 slot = &root->rnode;
302 296
303 while (height > 0) { 297 while (height > 0) {
304 if (slot == NULL) 298 if (*slot == NULL)
305 return NULL; 299 return NULL;
306 300
307 slot = slot->slots[(index >> shift) & RADIX_TREE_MAP_MASK]; 301 slot = (struct radix_tree_node **)
302 ((*slot)->slots +
303 ((index >> shift) & RADIX_TREE_MAP_MASK));
308 shift -= RADIX_TREE_MAP_SHIFT; 304 shift -= RADIX_TREE_MAP_SHIFT;
309 height--; 305 height--;
310 } 306 }
311 307
312 return slot; 308 return (void **)slot;
309}
310
311/**
312 * radix_tree_lookup_slot - lookup a slot in a radix tree
313 * @root: radix tree root
314 * @index: index key
315 *
316 * Lookup the slot corresponding to the position @index in the radix tree
317 * @root. This is useful for update-if-exists operations.
318 */
319void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index)
320{
321 return __lookup_slot(root, index);
322}
323EXPORT_SYMBOL(radix_tree_lookup_slot);
324
325/**
326 * radix_tree_lookup - perform lookup operation on a radix tree
327 * @root: radix tree root
328 * @index: index key
329 *
330 * Lookup the item at the position @index in the radix tree @root.
331 */
332void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index)
333{
334 void **slot;
335
336 slot = __lookup_slot(root, index);
337 return slot != NULL ? *slot : NULL;
313} 338}
314EXPORT_SYMBOL(radix_tree_lookup); 339EXPORT_SYMBOL(radix_tree_lookup);
315 340