- /*
- * bios can get merged in funny ways, and so we need to
- * be careful with the state variable. We know the
- * state won't be merged with others because it has
- * WRITEBACK set, but we can't be sure each biovec is
- * sequential in the file. So, if our cached state
- * doesn't match the expected end, search the tree
- * for the correct one.
- */
-
- spin_lock_irqsave(&tree->lock, flags);
- if (!state || state->end != end) {
- state = NULL;
- node = __etree_search(tree, start, NULL, NULL);
- if (node) {
- state = rb_entry(node, struct extent_state,
- rb_node);
- if (state->end != end ||
- !(state->state & EXTENT_WRITEBACK))
- state = NULL;
- }
- if (!state) {
- spin_unlock_irqrestore(&tree->lock, flags);
- clear_extent_writeback(tree, start,
- end, GFP_ATOMIC);
- goto next_io;
- }
- }
- cur = end;
- while(1) {
- struct extent_state *clear = state;
- cur = state->start;
- node = rb_prev(&state->rb_node);
- if (node) {
- state = rb_entry(node,
- struct extent_state,
- rb_node);
- } else {
- state = NULL;
- }
-
- clear_state_bit(tree, clear, EXTENT_WRITEBACK,
- 1, 0);
- if (cur == start)
- break;
- if (cur < start) {
- WARN_ON(1);
- break;
- }
- if (!node)
- break;
- }
- /* before releasing the lock, make sure the next state
- * variable has the expected bits set and corresponds
- * to the correct offsets in the file
- */
- if (state && (state->end + 1 != start ||
- !(state->state & EXTENT_WRITEBACK))) {
- state = NULL;
- }
- spin_unlock_irqrestore(&tree->lock, flags);
-next_io: