aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/extent-tree.c32
-rw-r--r--fs/btrfs/inode.c15
2 files changed, 36 insertions, 11 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 660b05a4baf5..99a8b0f0d318 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -192,11 +192,13 @@ static u64 noinline find_search_start(struct btrfs_root *root,
192 u64 start = 0; 192 u64 start = 0;
193 u64 end = 0; 193 u64 end = 0;
194 u64 cache_miss = 0; 194 u64 cache_miss = 0;
195 u64 total_fs_bytes;
195 int wrapped = 0; 196 int wrapped = 0;
196 197
197 if (!cache) { 198 if (!cache) {
198 goto out; 199 goto out;
199 } 200 }
201 total_fs_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy);
200again: 202again:
201 ret = cache_block_group(root, cache); 203 ret = cache_block_group(root, cache);
202 if (ret) 204 if (ret)
@@ -223,6 +225,8 @@ again:
223 if (data != BTRFS_BLOCK_GROUP_MIXED && 225 if (data != BTRFS_BLOCK_GROUP_MIXED &&
224 start + num > cache->key.objectid + cache->key.offset) 226 start + num > cache->key.objectid + cache->key.offset)
225 goto new_group; 227 goto new_group;
228 if (start + num > total_fs_bytes)
229 goto new_group;
226 return start; 230 return start;
227 } 231 }
228out: 232out:
@@ -239,7 +243,7 @@ new_group:
239 last = cache->key.objectid + cache->key.offset; 243 last = cache->key.objectid + cache->key.offset;
240wrapped: 244wrapped:
241 cache = btrfs_lookup_block_group(root->fs_info, last); 245 cache = btrfs_lookup_block_group(root->fs_info, last);
242 if (!cache) { 246 if (!cache || cache->key.objectid >= total_fs_bytes) {
243no_cache: 247no_cache:
244 if (!wrapped) { 248 if (!wrapped) {
245 wrapped = 1; 249 wrapped = 1;
@@ -287,6 +291,7 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
287 u64 end; 291 u64 end;
288 u64 free_check; 292 u64 free_check;
289 u64 ptr; 293 u64 ptr;
294 u64 total_fs_bytes;
290 int bit; 295 int bit;
291 int ret; 296 int ret;
292 int full_search = 0; 297 int full_search = 0;
@@ -294,6 +299,7 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
294 int data_swap = 0; 299 int data_swap = 0;
295 300
296 block_group_cache = &info->block_group_cache; 301 block_group_cache = &info->block_group_cache;
302 total_fs_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy);
297 303
298 if (!owner) 304 if (!owner)
299 factor = 8; 305 factor = 8;
@@ -306,7 +312,7 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
306 else 312 else
307 bit = BLOCK_GROUP_METADATA; 313 bit = BLOCK_GROUP_METADATA;
308 314
309 if (search_start) { 315 if (search_start && search_start < total_fs_bytes) {
310 struct btrfs_block_group_cache *shint; 316 struct btrfs_block_group_cache *shint;
311 shint = btrfs_lookup_block_group(info, search_start); 317 shint = btrfs_lookup_block_group(info, search_start);
312 if (shint && (shint->data == data || 318 if (shint && (shint->data == data ||
@@ -318,8 +324,8 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
318 } 324 }
319 } 325 }
320 } 326 }
321 if (hint && (hint->data == data || 327 if (hint && hint->key.objectid < total_fs_bytes &&
322 hint->data == BTRFS_BLOCK_GROUP_MIXED)) { 328 (hint->data == data || hint->data == BTRFS_BLOCK_GROUP_MIXED)) {
323 used = btrfs_block_group_used(&hint->item); 329 used = btrfs_block_group_used(&hint->item);
324 if (used + hint->pinned < 330 if (used + hint->pinned <
325 div_factor(hint->key.offset, factor)) { 331 div_factor(hint->key.offset, factor)) {
@@ -333,6 +339,8 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
333 else 339 else
334 hint_last = search_start; 340 hint_last = search_start;
335 341
342 if (hint_last >= total_fs_bytes)
343 hint_last = search_start;
336 last = hint_last; 344 last = hint_last;
337 } 345 }
338again: 346again:
@@ -350,6 +358,9 @@ again:
350 last = cache->key.objectid + cache->key.offset; 358 last = cache->key.objectid + cache->key.offset;
351 used = btrfs_block_group_used(&cache->item); 359 used = btrfs_block_group_used(&cache->item);
352 360
361 if (cache->key.objectid > total_fs_bytes)
362 break;
363
353 if (full_search) 364 if (full_search)
354 free_check = cache->key.offset; 365 free_check = cache->key.offset;
355 else 366 else
@@ -1420,8 +1431,8 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
1420 data = BTRFS_BLOCK_GROUP_MIXED; 1431 data = BTRFS_BLOCK_GROUP_MIXED;
1421 } 1432 }
1422 1433
1423 if (search_end == (u64)-1) 1434 search_end = min(search_end,
1424 search_end = btrfs_super_total_bytes(&info->super_copy); 1435 btrfs_super_total_bytes(&info->super_copy));
1425 if (hint_byte) { 1436 if (hint_byte) {
1426 block_group = btrfs_lookup_block_group(info, hint_byte); 1437 block_group = btrfs_lookup_block_group(info, hint_byte);
1427 if (!block_group) 1438 if (!block_group)
@@ -1617,7 +1628,8 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1617{ 1628{
1618 int ret; 1629 int ret;
1619 int pending_ret; 1630 int pending_ret;
1620 u64 super_used, root_used; 1631 u64 super_used;
1632 u64 root_used;
1621 u64 search_start = 0; 1633 u64 search_start = 0;
1622 u64 new_hint; 1634 u64 new_hint;
1623 struct btrfs_fs_info *info = root->fs_info; 1635 struct btrfs_fs_info *info = root->fs_info;
@@ -1636,6 +1648,8 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1636 search_start, search_end, hint_byte, ins, 1648 search_start, search_end, hint_byte, ins,
1637 trans->alloc_exclude_start, 1649 trans->alloc_exclude_start,
1638 trans->alloc_exclude_nr, data); 1650 trans->alloc_exclude_nr, data);
1651if (ret)
1652printk("find free extent returns %d\n", ret);
1639 BUG_ON(ret); 1653 BUG_ON(ret);
1640 if (ret) 1654 if (ret)
1641 return ret; 1655 return ret;
@@ -2292,8 +2306,6 @@ static int noinline relocate_one_extent(struct btrfs_root *extent_root,
2292 while(1) { 2306 while(1) {
2293 ret = btrfs_search_slot(NULL, extent_root, &key, path, 0, 0); 2307 ret = btrfs_search_slot(NULL, extent_root, &key, path, 0, 0);
2294 2308
2295 BUG_ON(ret == 0);
2296
2297 if (ret < 0) 2309 if (ret < 0)
2298 goto out; 2310 goto out;
2299 2311
@@ -2340,6 +2352,8 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 new_size)
2340 int progress = 0; 2352 int progress = 0;
2341 2353
2342 btrfs_set_super_total_bytes(&info->super_copy, new_size); 2354 btrfs_set_super_total_bytes(&info->super_copy, new_size);
2355 clear_extent_dirty(&info->free_space_cache, new_size, (u64)-1,
2356 GFP_NOFS);
2343 block_group_cache = &info->block_group_cache; 2357 block_group_cache = &info->block_group_cache;
2344 path = btrfs_alloc_path(); 2358 path = btrfs_alloc_path();
2345 root = root->fs_info->extent_root; 2359 root = root->fs_info->extent_root;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 2cb2dd32407e..281757007ddb 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -148,6 +148,7 @@ static int run_delalloc_nocow(struct inode *inode, u64 start, u64 end)
148 u64 bytenr; 148 u64 bytenr;
149 u64 cow_end; 149 u64 cow_end;
150 u64 loops = 0; 150 u64 loops = 0;
151 u64 total_fs_bytes;
151 struct btrfs_root *root = BTRFS_I(inode)->root; 152 struct btrfs_root *root = BTRFS_I(inode)->root;
152 struct extent_buffer *leaf; 153 struct extent_buffer *leaf;
153 int found_type; 154 int found_type;
@@ -157,6 +158,7 @@ static int run_delalloc_nocow(struct inode *inode, u64 start, u64 end)
157 int err; 158 int err;
158 struct btrfs_key found_key; 159 struct btrfs_key found_key;
159 160
161 total_fs_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy);
160 path = btrfs_alloc_path(); 162 path = btrfs_alloc_path();
161 BUG_ON(!path); 163 BUG_ON(!path);
162again: 164again:
@@ -189,8 +191,10 @@ again:
189 found_type = btrfs_file_extent_type(leaf, item); 191 found_type = btrfs_file_extent_type(leaf, item);
190 extent_start = found_key.offset; 192 extent_start = found_key.offset;
191 if (found_type == BTRFS_FILE_EXTENT_REG) { 193 if (found_type == BTRFS_FILE_EXTENT_REG) {
192 extent_end = extent_start + 194 u64 extent_num_bytes;
193 btrfs_file_extent_num_bytes(leaf, item); 195
196 extent_num_bytes = btrfs_file_extent_num_bytes(leaf, item);
197 extent_end = extent_start + extent_num_bytes;
194 err = 0; 198 err = 0;
195 199
196 if (loops && start != extent_start) 200 if (loops && start != extent_start)
@@ -204,6 +208,13 @@ again:
204 if (bytenr == 0) 208 if (bytenr == 0)
205 goto not_found; 209 goto not_found;
206 210
211 /*
212 * we may be called by the resizer, make sure we're inside
213 * the limits of the FS
214 */
215 if (bytenr + extent_num_bytes > total_fs_bytes)
216 goto not_found;
217
207 if (btrfs_count_snapshots_in_path(root, path, bytenr) != 1) { 218 if (btrfs_count_snapshots_in_path(root, path, bytenr) != 1) {
208 goto not_found; 219 goto not_found;
209 } 220 }