diff -r 41243548e445 extent_io.c --- a/extent_io.c Tue Jun 10 10:40:46 2008 -0400 +++ b/extent_io.c Tue Jun 10 14:09:20 2008 -0400 @@ -173,6 +173,38 @@ static struct rb_node *tree_insert(struc rb_link_node(node, parent, p); rb_insert_color(node, root); return NULL; +} + +/* + * tree_insert_left - insert split off node to a /known/ left node in a tree + * @root: root of the whole tree + * @parent: new node's parent + * @child: new node + * + * Since we /know/ the position to insert into (the /left/ of the + * given parent), we can short-circuit the complete tree search. + * + * There are really two cases: + * (1) The parent's left is NULL, this means that the new node is + * to be placed there. + * + * (2) The parent's left is non-NULL, we then search for the + * right-most decendent of the parent's left-child. This is + * a simple decent down the right links. + * + * Note: We could (should?) complicate the code to add in checks for + * already existing (or overlapping) entries... + */ +static void tree_insert_left(struct rb_root *root, struct rb_node *parent, + struct rb_node *child) +{ + struct rb_node **link; + + for (link = &parent->rb_left; *link; link = &parent->rb_right) + parent = *link; + + rb_link_node(child, parent, link); + rb_insert_color(child, root); } static struct rb_node *__etree_search(struct extent_io_tree *tree, u64 offset, @@ -369,20 +401,12 @@ static int split_state(struct extent_io_ static int split_state(struct extent_io_tree *tree, struct extent_state *orig, struct extent_state *prealloc, u64 split) { - struct rb_node *node; prealloc->start = orig->start; prealloc->end = split - 1; prealloc->state = orig->state; orig->start = split; - node = tree_insert(&tree->state, prealloc->end, &prealloc->rb_node); - if (node) { - struct extent_state *found; - found = rb_entry(node, struct extent_state, rb_node); - printk("found node %Lu %Lu on insert of %Lu %Lu\n", found->start, found->end, prealloc->start, prealloc->end); - free_extent_state(prealloc); - return -EEXIST; - } + tree_insert_left(&tree->state, &orig->rb_node, &prealloc->rb_node); prealloc->tree = tree; return 0; }