aboutsummaryrefslogtreecommitdiff
path: root/fs/btrfs/extent_map.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/extent_map.c')
-rw-r--r--fs/btrfs/extent_map.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index a0dff34dd43..2b92f107027 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -1131,7 +1131,8 @@ out:
}
u64 count_range_bits(struct extent_map_tree *tree,
- u64 *start, u64 max_bytes, unsigned long bits)
+ u64 *start, u64 search_end, u64 max_bytes,
+ unsigned long bits)
{
struct rb_node *node;
struct extent_state *state;
@@ -1139,9 +1140,14 @@ u64 count_range_bits(struct extent_map_tree *tree,
u64 total_bytes = 0;
int found = 0;
+ if (search_end <= cur_start) {
+ printk("search_end %Lu start %Lu\n", search_end, cur_start);
+ WARN_ON(1);
+ return 0;
+ }
+
write_lock_irq(&tree->lock);
- if (bits == EXTENT_DIRTY) {
- *start = 0;
+ if (cur_start == 0 && bits == EXTENT_DIRTY) {
total_bytes = tree->dirty_bytes;
goto out;
}
@@ -1156,8 +1162,11 @@ u64 count_range_bits(struct extent_map_tree *tree,
while(1) {
state = rb_entry(node, struct extent_state, rb_node);
- if ((state->state & bits)) {
- total_bytes += state->end - state->start + 1;
+ if (state->start > search_end)
+ break;
+ if (state->end >= cur_start && (state->state & bits)) {
+ total_bytes += min(search_end, state->end) + 1 -
+ max(cur_start, state->start);
if (total_bytes >= max_bytes)
break;
if (!found) {
@@ -1173,7 +1182,6 @@ out:
write_unlock_irq(&tree->lock);
return total_bytes;
}
-
/*
* helper function to lock both pages and extents in the tree.
* pages must be locked first.