Commit 9db33891 authored by David Sterba's avatar David Sterba

btrfs: unify tree search helper returning prev and next nodes

Simplify helper to return only next and prev pointers, we don't need all
the node/parent/prev/next pointers of __etree_search as there are now
other specialized helpers. Rename parameters so they follow the naming.
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent ec60c76f
...@@ -374,81 +374,87 @@ void free_extent_state(struct extent_state *state) ...@@ -374,81 +374,87 @@ void free_extent_state(struct extent_state *state)
* *
* @tree: the tree to search * @tree: the tree to search
* @offset: offset that should fall within an entry in @tree * @offset: offset that should fall within an entry in @tree
* @next_ret: pointer to the first entry whose range ends after @offset * @node_ret: pointer where new node should be anchored (used when inserting an
* @prev_ret: pointer to the first entry whose range begins before @offset
* @p_ret: pointer where new node should be anchored (used when inserting an
* entry in the tree) * entry in the tree)
* @parent_ret: points to entry which would have been the parent of the entry, * @parent_ret: points to entry which would have been the parent of the entry,
* containing @offset * containing @offset
* *
* This function returns a pointer to the entry that contains @offset byte * Return a pointer to the entry that contains @offset byte address and don't change
* address. If no such entry exists, then NULL is returned and the other * @node_ret and @parent_ret.
* pointer arguments to the function are filled, otherwise the found entry is *
* returned and other pointers are left untouched. * If no such entry exists, return pointer to entry that ends before @offset
* and fill parameters @node_ret and @parent_ret, ie. does not return NULL.
*/ */
static struct rb_node *__etree_search(struct extent_io_tree *tree, u64 offset, static inline struct rb_node *tree_search_for_insert(struct extent_io_tree *tree,
struct rb_node **next_ret, u64 offset,
struct rb_node **prev_ret, struct rb_node ***node_ret,
struct rb_node ***p_ret,
struct rb_node **parent_ret) struct rb_node **parent_ret)
{ {
struct rb_root *root = &tree->state; struct rb_root *root = &tree->state;
struct rb_node **n = &root->rb_node; struct rb_node **node = &root->rb_node;
struct rb_node *prev = NULL; struct rb_node *prev = NULL;
struct rb_node *orig_prev = NULL;
struct tree_entry *entry; struct tree_entry *entry;
struct tree_entry *prev_entry = NULL;
while (*n) { while (*node) {
prev = *n; prev = *node;
entry = rb_entry(prev, struct tree_entry, rb_node); entry = rb_entry(prev, struct tree_entry, rb_node);
prev_entry = entry;
if (offset < entry->start) if (offset < entry->start)
n = &(*n)->rb_left; node = &(*node)->rb_left;
else if (offset > entry->end) else if (offset > entry->end)
n = &(*n)->rb_right; node = &(*node)->rb_right;
else else
return *n; return *node;
} }
if (p_ret) if (node_ret)
*p_ret = n; *node_ret = node;
if (parent_ret) if (parent_ret)
*parent_ret = prev; *parent_ret = prev;
if (next_ret) { /* Search neighbors until we find the first one past the end */
orig_prev = prev; while (prev && offset > entry->end) {
while (prev && offset > prev_entry->end) {
prev = rb_next(prev); prev = rb_next(prev);
prev_entry = rb_entry(prev, struct tree_entry, rb_node); entry = rb_entry(prev, struct tree_entry, rb_node);
}
*next_ret = prev;
prev = orig_prev;
} }
if (prev_ret) { return prev;
prev_entry = rb_entry(prev, struct tree_entry, rb_node); }
while (prev && offset < prev_entry->start) {
prev = rb_prev(prev); /*
prev_entry = rb_entry(prev, struct tree_entry, rb_node); * Inexact rb-tree search, return the next entry if @offset is not found
} */
*prev_ret = prev; static inline struct rb_node *tree_search(struct extent_io_tree *tree, u64 offset)
} {
return NULL; return tree_search_for_insert(tree, offset, NULL, NULL);
} }
static inline struct rb_node * /**
tree_search_for_insert(struct extent_io_tree *tree, * Search offset in the tree or fill neighbor rbtree node pointers.
*
* @tree: the tree to search
* @offset: offset that should fall within an entry in @tree
* @next_ret: pointer to the first entry whose range ends after @offset
* @prev_ret: pointer to the first entry whose range begins before @offset
*
* Return a pointer to the entry that contains @offset byte address. If no
* such entry exists, then return NULL and fill @prev_ret and @next_ret.
* Otherwise return the found entry and other pointers are left untouched.
*/
static struct rb_node *tree_search_prev_next(struct extent_io_tree *tree,
u64 offset, u64 offset,
struct rb_node ***p_ret, struct rb_node **prev_ret,
struct rb_node **parent_ret) struct rb_node **next_ret)
{ {
struct rb_root *root = &tree->state; struct rb_root *root = &tree->state;
struct rb_node **node = &root->rb_node; struct rb_node **node = &root->rb_node;
struct rb_node *prev = NULL; struct rb_node *prev = NULL;
struct rb_node *orig_prev = NULL;
struct tree_entry *entry; struct tree_entry *entry;
ASSERT(prev_ret);
ASSERT(next_ret);
while (*node) { while (*node) {
prev = *node; prev = *node;
entry = rb_entry(prev, struct tree_entry, rb_node); entry = rb_entry(prev, struct tree_entry, rb_node);
...@@ -461,26 +467,22 @@ tree_search_for_insert(struct extent_io_tree *tree, ...@@ -461,26 +467,22 @@ tree_search_for_insert(struct extent_io_tree *tree,
return *node; return *node;
} }
if (p_ret) orig_prev = prev;
*p_ret = node;
if (parent_ret)
*parent_ret = prev;
/* Search neighbors until we find the first one past the end */
while (prev && offset > entry->end) { while (prev && offset > entry->end) {
prev = rb_next(prev); prev = rb_next(prev);
entry = rb_entry(prev, struct tree_entry, rb_node); entry = rb_entry(prev, struct tree_entry, rb_node);
} }
*next_ret = prev;
prev = orig_prev;
return prev; entry = rb_entry(prev, struct tree_entry, rb_node);
} while (prev && offset < entry->start) {
prev = rb_prev(prev);
entry = rb_entry(prev, struct tree_entry, rb_node);
}
*prev_ret = prev;
/* return NULL;
* Inexact rb-tree search, return the next entry if @offset is not found
*/
static inline struct rb_node *tree_search(struct extent_io_tree *tree, u64 offset)
{
return tree_search_for_insert(tree, offset, NULL, NULL);
} }
/* /*
...@@ -1686,7 +1688,7 @@ void find_first_clear_extent_bit(struct extent_io_tree *tree, u64 start, ...@@ -1686,7 +1688,7 @@ void find_first_clear_extent_bit(struct extent_io_tree *tree, u64 start,
/* Find first extent with bits cleared */ /* Find first extent with bits cleared */
while (1) { while (1) {
node = __etree_search(tree, start, &next, &prev, NULL, NULL); node = tree_search_prev_next(tree, start, &prev, &next);
if (!node && !next && !prev) { if (!node && !next && !prev) {
/* /*
* Tree is completely empty, send full range and let * Tree is completely empty, send full range and let
......
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