Commit ed49cb09 authored by Andrew Morton's avatar Andrew Morton Committed by James Bottomley

[PATCH] radix_tree_delete API improvement

radix_tree_delete() currently returns 0 on success, -ENOENT if there was
nothing to delete.

But it is more useful to return the address of the deleted item on success
and NULL if there was no matching item.  It can potentially save a
lookup+delete operation.
parent 932fd605
...@@ -43,7 +43,7 @@ do { \ ...@@ -43,7 +43,7 @@ do { \
extern int radix_tree_insert(struct radix_tree_root *, unsigned long, void *); extern int radix_tree_insert(struct radix_tree_root *, unsigned long, void *);
extern void *radix_tree_lookup(struct radix_tree_root *, unsigned long); extern void *radix_tree_lookup(struct radix_tree_root *, unsigned long);
extern int radix_tree_delete(struct radix_tree_root *, unsigned long); extern void *radix_tree_delete(struct radix_tree_root *, unsigned long);
extern unsigned int extern unsigned int
radix_tree_gang_lookup(struct radix_tree_root *root, void **results, radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
unsigned long first_index, unsigned int max_items); unsigned long first_index, unsigned int max_items);
......
...@@ -349,15 +349,18 @@ EXPORT_SYMBOL(radix_tree_gang_lookup); ...@@ -349,15 +349,18 @@ EXPORT_SYMBOL(radix_tree_gang_lookup);
* @index: index key * @index: index key
* *
* Remove the item at @index from the radix tree rooted at @root. * Remove the item at @index from the radix tree rooted at @root.
*
* Returns the address of the deleted item, or NULL if it was not present.
*/ */
int radix_tree_delete(struct radix_tree_root *root, unsigned long index) void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
{ {
struct radix_tree_path path[RADIX_TREE_MAX_PATH], *pathp = path; struct radix_tree_path path[RADIX_TREE_MAX_PATH], *pathp = path;
unsigned int height, shift; unsigned int height, shift;
void *ret = NULL;
height = root->height; height = root->height;
if (index > radix_tree_maxindex(height)) if (index > radix_tree_maxindex(height))
return -ENOENT; goto out;
shift = (height-1) * RADIX_TREE_MAP_SHIFT; shift = (height-1) * RADIX_TREE_MAP_SHIFT;
pathp->node = NULL; pathp->node = NULL;
...@@ -365,7 +368,7 @@ int radix_tree_delete(struct radix_tree_root *root, unsigned long index) ...@@ -365,7 +368,7 @@ int radix_tree_delete(struct radix_tree_root *root, unsigned long index)
while (height > 0) { while (height > 0) {
if (*pathp->slot == NULL) if (*pathp->slot == NULL)
return -ENOENT; goto out;
pathp[1].node = *pathp[0].slot; pathp[1].node = *pathp[0].slot;
pathp[1].slot = (struct radix_tree_node **) pathp[1].slot = (struct radix_tree_node **)
...@@ -375,8 +378,9 @@ int radix_tree_delete(struct radix_tree_root *root, unsigned long index) ...@@ -375,8 +378,9 @@ int radix_tree_delete(struct radix_tree_root *root, unsigned long index)
height--; height--;
} }
if (*pathp[0].slot == NULL) ret = *pathp[0].slot;
return -ENOENT; if (ret == NULL)
goto out;
*pathp[0].slot = NULL; *pathp[0].slot = NULL;
while (pathp[0].node && --pathp[0].node->count == 0) { while (pathp[0].node && --pathp[0].node->count == 0) {
...@@ -387,8 +391,8 @@ int radix_tree_delete(struct radix_tree_root *root, unsigned long index) ...@@ -387,8 +391,8 @@ int radix_tree_delete(struct radix_tree_root *root, unsigned long index)
if (root->rnode == NULL) if (root->rnode == NULL)
root->height = 0; /* Empty tree, we can reset the height */ root->height = 0; /* Empty tree, we can reset the height */
out:
return 0; return ret;
} }
EXPORT_SYMBOL(radix_tree_delete); EXPORT_SYMBOL(radix_tree_delete);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment