diff options
author | Filipe Manana <fdmanana@suse.com> | 2014-10-13 07:28:38 -0400 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2014-11-20 20:14:29 -0500 |
commit | e38e2ed701ff5f3d889c8dda5fe863e165e60d61 (patch) | |
tree | 315b8703ca6c3317996de05a55ceb252257cbcff /fs/btrfs/extent_io.c | |
parent | 663dfbb07774e0fe1049e8db3054a08500122f18 (diff) |
Btrfs: make find_first_extent_bit be able to cache any state
Right now the only caller of find_first_extent_bit() that is interested
in caching extent states (transaction or log commit), never gets an extent
state cached. This is because find_first_extent_bit() only caches states
that have at least one of the flags EXTENT_IOBITS or EXTENT_BOUNDARY, and
the transaction/log commit caller always passes a tree that doesn't have
ever extent states with any of those flags (they can only have one of the
following flags: EXTENT_DIRTY, EXTENT_NEW or EXTENT_NEED_WAIT).
This change together with the following one in the patch series (titled
"Btrfs: avoid returning -ENOMEM in convert_extent_bit() too early") will
help reduce significantly the chances of calls to convert_extent_bit()
fail with -ENOMEM when called from the transaction/log commit code.
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r-- | fs/btrfs/extent_io.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 420fe26d32d5..0d931b143c00 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -796,17 +796,25 @@ static void set_state_bits(struct extent_io_tree *tree, | |||
796 | state->state |= bits_to_set; | 796 | state->state |= bits_to_set; |
797 | } | 797 | } |
798 | 798 | ||
799 | static void cache_state(struct extent_state *state, | 799 | static void cache_state_if_flags(struct extent_state *state, |
800 | struct extent_state **cached_ptr) | 800 | struct extent_state **cached_ptr, |
801 | const u64 flags) | ||
801 | { | 802 | { |
802 | if (cached_ptr && !(*cached_ptr)) { | 803 | if (cached_ptr && !(*cached_ptr)) { |
803 | if (state->state & (EXTENT_IOBITS | EXTENT_BOUNDARY)) { | 804 | if (!flags || (state->state & flags)) { |
804 | *cached_ptr = state; | 805 | *cached_ptr = state; |
805 | atomic_inc(&state->refs); | 806 | atomic_inc(&state->refs); |
806 | } | 807 | } |
807 | } | 808 | } |
808 | } | 809 | } |
809 | 810 | ||
811 | static void cache_state(struct extent_state *state, | ||
812 | struct extent_state **cached_ptr) | ||
813 | { | ||
814 | return cache_state_if_flags(state, cached_ptr, | ||
815 | EXTENT_IOBITS | EXTENT_BOUNDARY); | ||
816 | } | ||
817 | |||
810 | /* | 818 | /* |
811 | * set some bits on a range in the tree. This may require allocations or | 819 | * set some bits on a range in the tree. This may require allocations or |
812 | * sleeping, so the gfp mask is used to indicate what is allowed. | 820 | * sleeping, so the gfp mask is used to indicate what is allowed. |
@@ -1482,7 +1490,7 @@ int find_first_extent_bit(struct extent_io_tree *tree, u64 start, | |||
1482 | state = find_first_extent_bit_state(tree, start, bits); | 1490 | state = find_first_extent_bit_state(tree, start, bits); |
1483 | got_it: | 1491 | got_it: |
1484 | if (state) { | 1492 | if (state) { |
1485 | cache_state(state, cached_state); | 1493 | cache_state_if_flags(state, cached_state, 0); |
1486 | *start_ret = state->start; | 1494 | *start_ret = state->start; |
1487 | *end_ret = state->end; | 1495 | *end_ret = state->end; |
1488 | ret = 0; | 1496 | ret = 0; |