forked from Minki/linux
[PATCH] reiser4: add radix_tree_lookup_slot()
Reiser4 uses radix trees to solve a trouble reiser4_readdir has serving nfs requests. Unfortunately, radix tree api lacks an operation suitable for modifying existing entry. This patch adds radix_tree_lookup_slot which returns pointer to found item within the tree. That location can be then updated. Both Nick and Christoph Lameter have patches which need this as well. Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
7361f4d8ca
commit
a43313668f
@ -46,6 +46,7 @@ do { \
|
||||
|
||||
int radix_tree_insert(struct radix_tree_root *, unsigned long, void *);
|
||||
void *radix_tree_lookup(struct radix_tree_root *, unsigned long);
|
||||
void **radix_tree_lookup_slot(struct radix_tree_root *, unsigned long);
|
||||
void *radix_tree_delete(struct radix_tree_root *, unsigned long);
|
||||
unsigned int
|
||||
radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
|
||||
|
@ -281,6 +281,47 @@ int radix_tree_insert(struct radix_tree_root *root,
|
||||
}
|
||||
EXPORT_SYMBOL(radix_tree_insert);
|
||||
|
||||
static inline void **__lookup_slot(struct radix_tree_root *root,
|
||||
unsigned long index)
|
||||
{
|
||||
unsigned int height, shift;
|
||||
struct radix_tree_node **slot;
|
||||
|
||||
height = root->height;
|
||||
if (index > radix_tree_maxindex(height))
|
||||
return NULL;
|
||||
|
||||
shift = (height-1) * RADIX_TREE_MAP_SHIFT;
|
||||
slot = &root->rnode;
|
||||
|
||||
while (height > 0) {
|
||||
if (*slot == NULL)
|
||||
return NULL;
|
||||
|
||||
slot = (struct radix_tree_node **)
|
||||
((*slot)->slots +
|
||||
((index >> shift) & RADIX_TREE_MAP_MASK));
|
||||
shift -= RADIX_TREE_MAP_SHIFT;
|
||||
height--;
|
||||
}
|
||||
|
||||
return (void **)slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* radix_tree_lookup_slot - lookup a slot in a radix tree
|
||||
* @root: radix tree root
|
||||
* @index: index key
|
||||
*
|
||||
* Lookup the slot corresponding to the position @index in the radix tree
|
||||
* @root. This is useful for update-if-exists operations.
|
||||
*/
|
||||
void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index)
|
||||
{
|
||||
return __lookup_slot(root, index);
|
||||
}
|
||||
EXPORT_SYMBOL(radix_tree_lookup_slot);
|
||||
|
||||
/**
|
||||
* radix_tree_lookup - perform lookup operation on a radix tree
|
||||
* @root: radix tree root
|
||||
@ -290,26 +331,10 @@ EXPORT_SYMBOL(radix_tree_insert);
|
||||
*/
|
||||
void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index)
|
||||
{
|
||||
unsigned int height, shift;
|
||||
struct radix_tree_node *slot;
|
||||
void **slot;
|
||||
|
||||
height = root->height;
|
||||
if (index > radix_tree_maxindex(height))
|
||||
return NULL;
|
||||
|
||||
shift = (height-1) * RADIX_TREE_MAP_SHIFT;
|
||||
slot = root->rnode;
|
||||
|
||||
while (height > 0) {
|
||||
if (slot == NULL)
|
||||
return NULL;
|
||||
|
||||
slot = slot->slots[(index >> shift) & RADIX_TREE_MAP_MASK];
|
||||
shift -= RADIX_TREE_MAP_SHIFT;
|
||||
height--;
|
||||
}
|
||||
|
||||
return slot;
|
||||
slot = __lookup_slot(root, index);
|
||||
return slot != NULL ? *slot : NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(radix_tree_lookup);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user