diff options
author | Chris Mason | 2007-11-27 01:34:41 +0100 |
---|---|---|
committer | Chris Mason | 2008-09-25 17:03:58 +0200 |
commit | 793955bca66c99defdffc857ae6eb7e8431d6bbe (patch) | |
tree | 2f8376247033fced7289038b8d82e10a6cc55f22 /fs/btrfs/extent_map.c | |
parent | Btrfs: Handle writeback under high memory pressure better (diff) | |
download | kernel-qcow2-linux-793955bca66c99defdffc857ae6eb7e8431d6bbe.tar.gz kernel-qcow2-linux-793955bca66c99defdffc857ae6eb7e8431d6bbe.tar.xz kernel-qcow2-linux-793955bca66c99defdffc857ae6eb7e8431d6bbe.zip |
Btrfs: Limit btree writeback to prevent seeks
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent_map.c')
-rw-r--r-- | fs/btrfs/extent_map.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 55f272c335c6..b6a4974ecc23 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -1106,6 +1106,45 @@ out: return found; } +u64 count_range_bits(struct extent_map_tree *tree, + u64 *start, u64 max_bytes, unsigned long bits) +{ + struct rb_node *node; + struct extent_state *state; + u64 cur_start = *start; + u64 total_bytes = 0; + int found = 0; + + write_lock_irq(&tree->lock); + /* + * this search will find all the extents that end after + * our range starts. + */ + node = tree_search(&tree->state, cur_start); + if (!node || IS_ERR(node)) { + goto out; + } + + while(1) { + state = rb_entry(node, struct extent_state, rb_node); + if ((state->state & bits)) { + total_bytes += state->end - state->start + 1; + if (total_bytes >= max_bytes) + break; + if (!found) { + *start = state->start; + found = 1; + } + } + node = rb_next(node); + if (!node) + break; + } +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. |