diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-12-21 16:27:21 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:58 -0400 |
commit | 1832a6d5ee3b1af61001cadba9e10da9e91af4a4 (patch) | |
tree | 3a6dcb2a186c3623b0355b7e45d1b94ecae5e54d /fs/btrfs/extent_map.c | |
parent | 01f466580502c57001bf80fff709479fdb9e87a5 (diff) |
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.c | 20 |
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: | |||
1131 | } | 1131 | } |
1132 | 1132 | ||
1133 | u64 count_range_bits(struct extent_map_tree *tree, | 1133 | u64 count_range_bits(struct extent_map_tree *tree, |
1134 | u64 *start, u64 max_bytes, unsigned long bits) | 1134 | u64 *start, u64 search_end, u64 max_bytes, |
1135 | unsigned long bits) | ||
1135 | { | 1136 | { |
1136 | struct rb_node *node; | 1137 | struct rb_node *node; |
1137 | struct extent_state *state; | 1138 | struct extent_state *state; |
@@ -1139,9 +1140,14 @@ u64 count_range_bits(struct extent_map_tree *tree, | |||
1139 | u64 total_bytes = 0; | 1140 | u64 total_bytes = 0; |
1140 | int found = 0; | 1141 | int found = 0; |
1141 | 1142 | ||
1143 | if (search_end <= cur_start) { | ||
1144 | printk("search_end %Lu start %Lu\n", search_end, cur_start); | ||
1145 | WARN_ON(1); | ||
1146 | return 0; | ||
1147 | } | ||
1148 | |||
1142 | write_lock_irq(&tree->lock); | 1149 | write_lock_irq(&tree->lock); |
1143 | if (bits == EXTENT_DIRTY) { | 1150 | if (cur_start == 0 && bits == EXTENT_DIRTY) { |
1144 | *start = 0; | ||
1145 | total_bytes = tree->dirty_bytes; | 1151 | total_bytes = tree->dirty_bytes; |
1146 | goto out; | 1152 | goto out; |
1147 | } | 1153 | } |
@@ -1156,8 +1162,11 @@ u64 count_range_bits(struct extent_map_tree *tree, | |||
1156 | 1162 | ||
1157 | while(1) { | 1163 | while(1) { |
1158 | state = rb_entry(node, struct extent_state, rb_node); | 1164 | state = rb_entry(node, struct extent_state, rb_node); |
1159 | if ((state->state & bits)) { | 1165 | if (state->start > search_end) |
1160 | total_bytes += state->end - state->start + 1; | 1166 | break; |
1167 | if (state->end >= cur_start && (state->state & bits)) { | ||
1168 | total_bytes += min(search_end, state->end) + 1 - | ||
1169 | max(cur_start, state->start); | ||
1161 | if (total_bytes >= max_bytes) | 1170 | if (total_bytes >= max_bytes) |
1162 | break; | 1171 | break; |
1163 | if (!found) { | 1172 | if (!found) { |
@@ -1173,7 +1182,6 @@ out: | |||
1173 | write_unlock_irq(&tree->lock); | 1182 | write_unlock_irq(&tree->lock); |
1174 | return total_bytes; | 1183 | return total_bytes; |
1175 | } | 1184 | } |
1176 | |||
1177 | /* | 1185 | /* |
1178 | * helper function to lock both pages and extents in the tree. | 1186 | * helper function to lock both pages and extents in the tree. |
1179 | * pages must be locked first. | 1187 | * pages must be locked first. |