On Fri, Feb 08, 2013 at 04:35:00PM +0100, Jan Kara wrote: [snip] > > -static int __es_insert_extent(struct ext4_es_tree *tree, ext4_lblk_t offset, > > - ext4_lblk_t len) > > +static int __es_insert_extent(struct ext4_es_tree *tree, > > + struct extent_status *newes) > > { > > struct rb_node **p = &tree->root.rb_node; > > struct rb_node *parent = NULL; > > struct extent_status *es; > > - ext4_lblk_t end = offset + len - 1; > > - > > - BUG_ON(end < offset); > > - es = tree->cache_es; > > - if (es && offset == (extent_status_end(es) + 1)) { > > - es_debug("cached by [%u/%u)\n", es->start, es->len); > > - es->len += len; > > - es = ext4_es_try_to_merge_right(tree, es); > > - goto out; > > - } else if (es && es->start == end + 1) { > > - es_debug("cached by [%u/%u)\n", es->start, es->len); > > - es->start = offset; > > - es->len += len; > > - es = ext4_es_try_to_merge_left(tree, es); > > - goto out; > > - } else if (es && es->start <= offset && > > - end <= extent_status_end(es)) { > > - es_debug("cached by [%u/%u)\n", es->start, es->len); > > - goto out; > > - } > > > > while (*p) { > > parent = *p; > > es = rb_entry(parent, struct extent_status, rb_node); > > > > - if (offset < es->start) { > > - if (es->start == end + 1) { > > - es->start = offset; > > - es->len += len; > > + if (newes->es_lblk < es->es_lblk) { > > + if (ext4_es_can_be_merged(newes, es)) { > > + es->es_lblk = newes->es_lblk; > > + es->es_len += newes->es_len; > This is wrong, isn't it? You cannot change es->es_lblk because that can > break ordering of elements in the tree... thinking ... ah, it's OK because > you have non-overlapping intervals. But it deserves a comment I guess. Hi Jan, Sorry for the delay reply. I will add a comment here to describe why es_lblk can be changed directly. Thanks, - Zheng -- To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html