diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-12-04 13:18:24 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:58 -0400 |
commit | 1a2b2ac78a4151a49267a1e3f48a131f5810814e (patch) | |
tree | 8d20e751e7dcb9937585ebf4e0cbee4d9effaa84 /fs/btrfs/extent-tree.c | |
parent | 87ee04eb0f2f0c63314cef4a76bd1adac748425e (diff) |
Btrfs: Fix extent allocation for btree blocks as the disk fills
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 91397e989393..8ab4954f6ad0 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -172,9 +172,7 @@ static u64 find_search_start(struct btrfs_root *root, | |||
172 | int wrapped = 0; | 172 | int wrapped = 0; |
173 | 173 | ||
174 | if (!cache) { | 174 | if (!cache) { |
175 | cache = btrfs_lookup_block_group(root->fs_info, search_start); | 175 | goto out; |
176 | if (!cache) | ||
177 | return search_start; | ||
178 | } | 176 | } |
179 | again: | 177 | again: |
180 | ret = cache_block_group(root, cache); | 178 | ret = cache_block_group(root, cache); |
@@ -205,6 +203,13 @@ again: | |||
205 | return start; | 203 | return start; |
206 | } | 204 | } |
207 | out: | 205 | out: |
206 | cache = btrfs_lookup_block_group(root->fs_info, search_start); | ||
207 | if (!cache) { | ||
208 | printk("Unable to find block group for %Lu\n", | ||
209 | search_start); | ||
210 | WARN_ON(1); | ||
211 | return search_start; | ||
212 | } | ||
208 | return search_start; | 213 | return search_start; |
209 | 214 | ||
210 | new_group: | 215 | new_group: |
@@ -219,15 +224,14 @@ no_cache: | |||
219 | data = BTRFS_BLOCK_GROUP_MIXED; | 224 | data = BTRFS_BLOCK_GROUP_MIXED; |
220 | goto wrapped; | 225 | goto wrapped; |
221 | } | 226 | } |
222 | return search_start; | 227 | goto out; |
223 | } | 228 | } |
224 | if (cache_miss && !cache->cached) { | 229 | if (cache_miss && !cache->cached) { |
225 | cache_block_group(root, cache); | 230 | cache_block_group(root, cache); |
226 | last = cache_miss; | 231 | last = cache_miss; |
227 | cache = btrfs_lookup_block_group(root->fs_info, last); | 232 | cache = btrfs_lookup_block_group(root->fs_info, last); |
228 | } | 233 | } |
229 | if (!full_scan) | 234 | cache = btrfs_find_block_group(root, cache, last, data, 0); |
230 | cache = btrfs_find_block_group(root, cache, last, data, 0); | ||
231 | if (!cache) | 235 | if (!cache) |
232 | goto no_cache; | 236 | goto no_cache; |
233 | *cache_ret = cache; | 237 | *cache_ret = cache; |
@@ -985,12 +989,14 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
985 | search_end = btrfs_super_total_bytes(&info->super_copy); | 989 | search_end = btrfs_super_total_bytes(&info->super_copy); |
986 | if (hint_byte) { | 990 | if (hint_byte) { |
987 | block_group = btrfs_lookup_block_group(info, hint_byte); | 991 | block_group = btrfs_lookup_block_group(info, hint_byte); |
992 | if (!block_group) | ||
993 | hint_byte = search_start; | ||
988 | block_group = btrfs_find_block_group(root, block_group, | 994 | block_group = btrfs_find_block_group(root, block_group, |
989 | hint_byte, data, 1); | 995 | hint_byte, data, 1); |
990 | } else { | 996 | } else { |
991 | block_group = btrfs_find_block_group(root, | 997 | block_group = btrfs_find_block_group(root, |
992 | trans->block_group, 0, | 998 | trans->block_group, |
993 | data, 1); | 999 | search_start, data, 1); |
994 | } | 1000 | } |
995 | 1001 | ||
996 | total_needed += empty_size; | 1002 | total_needed += empty_size; |
@@ -1159,14 +1165,14 @@ enospc: | |||
1159 | if (!full_scan) | 1165 | if (!full_scan) |
1160 | total_needed -= empty_size; | 1166 | total_needed -= empty_size; |
1161 | full_scan = 1; | 1167 | full_scan = 1; |
1168 | data = BTRFS_BLOCK_GROUP_MIXED; | ||
1162 | } else | 1169 | } else |
1163 | wrapped = 1; | 1170 | wrapped = 1; |
1164 | } | 1171 | } |
1165 | block_group = btrfs_lookup_block_group(info, search_start); | 1172 | block_group = btrfs_lookup_block_group(info, search_start); |
1166 | cond_resched(); | 1173 | cond_resched(); |
1167 | if (!full_scan) | 1174 | block_group = btrfs_find_block_group(root, block_group, |
1168 | block_group = btrfs_find_block_group(root, block_group, | 1175 | search_start, data, 0); |
1169 | search_start, data, 0); | ||
1170 | goto check_failed; | 1176 | goto check_failed; |
1171 | 1177 | ||
1172 | error: | 1178 | error: |