diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-02-18 12:12:38 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:00 -0400 |
commit | d7fc640e6fed46932f7c74e14f9b58b8637c66cf (patch) | |
tree | 525eda21f9e0d6d18bd55fd23d3a31814b224aa8 /fs/btrfs/extent_io.c | |
parent | 9afbb0b752ef30a429c45b9de6706e28ad1a36e1 (diff) |
Btrfs: Allocator improvements
Reduce CPU time searching for free blocks by optimizing find_first_extent_bit
Fix find_free_extent to make better use of the last_alloc hint. Before it
was often finding blocks just before the hint.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r-- | fs/btrfs/extent_io.c | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 9262ab37a7cd..fb6400895ed6 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -255,7 +255,7 @@ static int merge_state(struct extent_io_tree *tree, | |||
255 | state->start = other->start; | 255 | state->start = other->start; |
256 | other->tree = NULL; | 256 | other->tree = NULL; |
257 | if (tree->last == other) | 257 | if (tree->last == other) |
258 | tree->last = NULL; | 258 | tree->last = state; |
259 | rb_erase(&other->rb_node, &tree->state); | 259 | rb_erase(&other->rb_node, &tree->state); |
260 | free_extent_state(other); | 260 | free_extent_state(other); |
261 | } | 261 | } |
@@ -268,7 +268,7 @@ static int merge_state(struct extent_io_tree *tree, | |||
268 | other->start = state->start; | 268 | other->start = state->start; |
269 | state->tree = NULL; | 269 | state->tree = NULL; |
270 | if (tree->last == state) | 270 | if (tree->last == state) |
271 | tree->last = NULL; | 271 | tree->last = other; |
272 | rb_erase(&state->rb_node, &tree->state); | 272 | rb_erase(&state->rb_node, &tree->state); |
273 | free_extent_state(state); | 273 | free_extent_state(state); |
274 | } | 274 | } |
@@ -397,8 +397,9 @@ static int clear_state_bit(struct extent_io_tree *tree, | |||
397 | if (delete || state->state == 0) { | 397 | if (delete || state->state == 0) { |
398 | if (state->tree) { | 398 | if (state->tree) { |
399 | clear_state_cb(tree, state, state->state); | 399 | clear_state_cb(tree, state, state->state); |
400 | if (tree->last == state) | 400 | if (tree->last == state) { |
401 | tree->last = NULL; | 401 | tree->last = extent_state_next(state); |
402 | } | ||
402 | rb_erase(&state->rb_node, &tree->state); | 403 | rb_erase(&state->rb_node, &tree->state); |
403 | state->tree = NULL; | 404 | state->tree = NULL; |
404 | free_extent_state(state); | 405 | free_extent_state(state); |
@@ -962,6 +963,35 @@ out: | |||
962 | } | 963 | } |
963 | EXPORT_SYMBOL(find_first_extent_bit); | 964 | EXPORT_SYMBOL(find_first_extent_bit); |
964 | 965 | ||
966 | struct extent_state *find_first_extent_bit_state(struct extent_io_tree *tree, | ||
967 | u64 start, int bits) | ||
968 | { | ||
969 | struct rb_node *node; | ||
970 | struct extent_state *state; | ||
971 | |||
972 | /* | ||
973 | * this search will find all the extents that end after | ||
974 | * our range starts. | ||
975 | */ | ||
976 | node = tree_search(tree, start); | ||
977 | if (!node || IS_ERR(node)) { | ||
978 | goto out; | ||
979 | } | ||
980 | |||
981 | while(1) { | ||
982 | state = rb_entry(node, struct extent_state, rb_node); | ||
983 | if (state->end >= start && (state->state & bits)) { | ||
984 | return state; | ||
985 | } | ||
986 | node = rb_next(node); | ||
987 | if (!node) | ||
988 | break; | ||
989 | } | ||
990 | out: | ||
991 | return NULL; | ||
992 | } | ||
993 | EXPORT_SYMBOL(find_first_extent_bit_state); | ||
994 | |||
965 | u64 find_lock_delalloc_range(struct extent_io_tree *tree, | 995 | u64 find_lock_delalloc_range(struct extent_io_tree *tree, |
966 | u64 *start, u64 *end, u64 max_bytes) | 996 | u64 *start, u64 *end, u64 max_bytes) |
967 | { | 997 | { |