From de2a7581cb29543b0bcce8511d435ab4a17d20e1 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Mon, 12 Mar 2012 16:39:48 +0800 Subject: [PATCH] --- yaml --- r: 299803 b: refs/heads/master c: cdc6a3952558f00b1bc3b6401e1cf98797632fe2 h: refs/heads/master i: 299801: 9d6b5cd99d7b6a1554319a6c63453050b72451cd 299799: fb9388b6d157d66435d024a21f93667335f5b340 v: v3 --- [refs] | 2 +- trunk/fs/btrfs/extent_io.c | 36 +++++++++++++++++++++--------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/[refs] b/[refs] index 145a959e86f5..a5f8a1ced90b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 8e52acf70459020d7e9e9fda25066be4da520943 +refs/heads/master: cdc6a3952558f00b1bc3b6401e1cf98797632fe2 diff --git a/trunk/fs/btrfs/extent_io.c b/trunk/fs/btrfs/extent_io.c index 05951bdf72cc..11eeb81fe695 100644 --- a/trunk/fs/btrfs/extent_io.c +++ b/trunk/fs/btrfs/extent_io.c @@ -402,6 +402,15 @@ static int split_state(struct extent_io_tree *tree, struct extent_state *orig, return 0; } +static struct extent_state *next_state(struct extent_state *state) +{ + struct rb_node *next = rb_next(&state->rb_node); + if (next) + return rb_entry(next, struct extent_state, rb_node); + else + return NULL; +} + /* * utility function to clear some bits in an extent state struct. * it will optionally wake up any one waiting on this state (wake == 1) @@ -409,10 +418,11 @@ static int split_state(struct extent_io_tree *tree, struct extent_state *orig, * If no bits are set on the state struct after clearing things, the * struct is freed and removed from the tree */ -static void clear_state_bit(struct extent_io_tree *tree, - struct extent_state *state, - int *bits, int wake) +static struct extent_state *clear_state_bit(struct extent_io_tree *tree, + struct extent_state *state, + int *bits, int wake) { + struct extent_state *next; int bits_to_clear = *bits & ~EXTENT_CTLBITS; if ((bits_to_clear & EXTENT_DIRTY) && (state->state & EXTENT_DIRTY)) { @@ -425,6 +435,7 @@ static void clear_state_bit(struct extent_io_tree *tree, if (wake) wake_up(&state->wq); if (state->state == 0) { + next = next_state(state); if (state->tree) { rb_erase(&state->rb_node, &tree->state); state->tree = NULL; @@ -434,7 +445,9 @@ static void clear_state_bit(struct extent_io_tree *tree, } } else { merge_state(tree, state); + next = next_state(state); } + return next; } static struct extent_state * @@ -473,7 +486,6 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, struct extent_state *state; struct extent_state *cached; struct extent_state *prealloc = NULL; - struct rb_node *next_node; struct rb_node *node; u64 last_end; int err; @@ -525,14 +537,11 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, WARN_ON(state->end < start); last_end = state->end; - if (state->end < end && !need_resched()) - next_node = rb_next(&state->rb_node); - else - next_node = NULL; - /* the state doesn't have the wanted bits, go ahead */ - if (!(state->state & bits)) + if (!(state->state & bits)) { + state = next_state(state); goto next; + } /* * | ---- desired range ---- | @@ -590,16 +599,13 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, goto out; } - clear_state_bit(tree, state, &bits, wake); + state = clear_state_bit(tree, state, &bits, wake); next: if (last_end == (u64)-1) goto out; start = last_end + 1; - if (start <= end && next_node) { - state = rb_entry(next_node, struct extent_state, - rb_node); + if (start <= end && state && !need_resched()) goto hit_next; - } goto search_again; out: