summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent_map.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-12-21 22:27:21 +0100
committerChris Mason <chris.mason@oracle.com>2008-09-25 17:03:58 +0200
commit1832a6d5ee3b1af61001cadba9e10da9e91af4a4 (patch)
tree3a6dcb2a186c3623b0355b7e45d1b94ecae5e54d /fs/btrfs/extent_map.c
parentBtrfs: Less aggressive readahead on deletes (diff)
downloadlinux-1832a6d5ee3b1af61001cadba9e10da9e91af4a4.tar.xz
linux-1832a6d5ee3b1af61001cadba9e10da9e91af4a4.zip
Btrfs: Implement basic support for -ENOSPC
This is intended to prevent accidentally filling the drive. A determined user can still make things oops. It includes some accounting of the current bytes under delayed allocation, but this will change as things get optimized Signed-off-by: Chris Mason <chris.mason@oracle.com>
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 a0dff34dd437..2b92f1070274 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.