aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/extent-tree.c21
-rw-r--r--fs/btrfs/free-space-cache.c73
-rw-r--r--fs/btrfs/inode.c3
-rw-r--r--fs/btrfs/relocation.c9
-rw-r--r--fs/btrfs/zlib.c6
5 files changed, 92 insertions, 20 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index dc84daee6bc..72a2b9c28e9 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -265,10 +265,6 @@ static int caching_kthread(void *data)
265 265
266 atomic_inc(&block_group->space_info->caching_threads); 266 atomic_inc(&block_group->space_info->caching_threads);
267 last = max_t(u64, block_group->key.objectid, BTRFS_SUPER_INFO_OFFSET); 267 last = max_t(u64, block_group->key.objectid, BTRFS_SUPER_INFO_OFFSET);
268again:
269 /* need to make sure the commit_root doesn't disappear */
270 down_read(&fs_info->extent_commit_sem);
271
272 /* 268 /*
273 * We don't want to deadlock with somebody trying to allocate a new 269 * We don't want to deadlock with somebody trying to allocate a new
274 * extent for the extent root while also trying to search the extent 270 * extent for the extent root while also trying to search the extent
@@ -282,6 +278,10 @@ again:
282 key.objectid = last; 278 key.objectid = last;
283 key.offset = 0; 279 key.offset = 0;
284 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); 280 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
281again:
282 /* need to make sure the commit_root doesn't disappear */
283 down_read(&fs_info->extent_commit_sem);
284
285 ret = btrfs_search_slot(NULL, fs_info->extent_root, &key, path, 0, 0); 285 ret = btrfs_search_slot(NULL, fs_info->extent_root, &key, path, 0, 0);
286 if (ret < 0) 286 if (ret < 0)
287 goto err; 287 goto err;
@@ -304,6 +304,19 @@ again:
304 304
305 if (need_resched() || 305 if (need_resched() ||
306 btrfs_transaction_in_commit(fs_info)) { 306 btrfs_transaction_in_commit(fs_info)) {
307 leaf = path->nodes[0];
308
309 /* this shouldn't happen, but if the
310 * leaf is empty just move on.
311 */
312 if (btrfs_header_nritems(leaf) == 0)
313 break;
314 /*
315 * we need to copy the key out so that
316 * we are sure the next search advances
317 * us forward in the btree.
318 */
319 btrfs_item_key_to_cpu(leaf, &key, 0);
307 btrfs_release_path(fs_info->extent_root, path); 320 btrfs_release_path(fs_info->extent_root, path);
308 up_read(&fs_info->extent_commit_sem); 321 up_read(&fs_info->extent_commit_sem);
309 schedule_timeout(1); 322 schedule_timeout(1);
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index af99b78b288..5edcee3a617 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -414,11 +414,29 @@ static noinline int remove_from_bitmap(struct btrfs_block_group_cache *block_gro
414 u64 *offset, u64 *bytes) 414 u64 *offset, u64 *bytes)
415{ 415{
416 u64 end; 416 u64 end;
417 u64 search_start, search_bytes;
418 int ret;
417 419
418again: 420again:
419 end = bitmap_info->offset + 421 end = bitmap_info->offset +
420 (u64)(BITS_PER_BITMAP * block_group->sectorsize) - 1; 422 (u64)(BITS_PER_BITMAP * block_group->sectorsize) - 1;
421 423
424 /*
425 * XXX - this can go away after a few releases.
426 *
427 * since the only user of btrfs_remove_free_space is the tree logging
428 * stuff, and the only way to test that is under crash conditions, we
429 * want to have this debug stuff here just in case somethings not
430 * working. Search the bitmap for the space we are trying to use to
431 * make sure its actually there. If its not there then we need to stop
432 * because something has gone wrong.
433 */
434 search_start = *offset;
435 search_bytes = *bytes;
436 ret = search_bitmap(block_group, bitmap_info, &search_start,
437 &search_bytes);
438 BUG_ON(ret < 0 || search_start != *offset);
439
422 if (*offset > bitmap_info->offset && *offset + *bytes > end) { 440 if (*offset > bitmap_info->offset && *offset + *bytes > end) {
423 bitmap_clear_bits(block_group, bitmap_info, *offset, 441 bitmap_clear_bits(block_group, bitmap_info, *offset,
424 end - *offset + 1); 442 end - *offset + 1);
@@ -430,6 +448,7 @@ again:
430 } 448 }
431 449
432 if (*bytes) { 450 if (*bytes) {
451 struct rb_node *next = rb_next(&bitmap_info->offset_index);
433 if (!bitmap_info->bytes) { 452 if (!bitmap_info->bytes) {
434 unlink_free_space(block_group, bitmap_info); 453 unlink_free_space(block_group, bitmap_info);
435 kfree(bitmap_info->bitmap); 454 kfree(bitmap_info->bitmap);
@@ -438,16 +457,36 @@ again:
438 recalculate_thresholds(block_group); 457 recalculate_thresholds(block_group);
439 } 458 }
440 459
441 bitmap_info = tree_search_offset(block_group, 460 /*
442 offset_to_bitmap(block_group, 461 * no entry after this bitmap, but we still have bytes to
443 *offset), 462 * remove, so something has gone wrong.
444 1, 0); 463 */
445 if (!bitmap_info) 464 if (!next)
446 return -EINVAL; 465 return -EINVAL;
447 466
467 bitmap_info = rb_entry(next, struct btrfs_free_space,
468 offset_index);
469
470 /*
471 * if the next entry isn't a bitmap we need to return to let the
472 * extent stuff do its work.
473 */
448 if (!bitmap_info->bitmap) 474 if (!bitmap_info->bitmap)
449 return -EAGAIN; 475 return -EAGAIN;
450 476
477 /*
478 * Ok the next item is a bitmap, but it may not actually hold
479 * the information for the rest of this free space stuff, so
480 * look for it, and if we don't find it return so we can try
481 * everything over again.
482 */
483 search_start = *offset;
484 search_bytes = *bytes;
485 ret = search_bitmap(block_group, bitmap_info, &search_start,
486 &search_bytes);
487 if (ret < 0 || search_start != *offset)
488 return -EAGAIN;
489
451 goto again; 490 goto again;
452 } else if (!bitmap_info->bytes) { 491 } else if (!bitmap_info->bytes) {
453 unlink_free_space(block_group, bitmap_info); 492 unlink_free_space(block_group, bitmap_info);
@@ -644,8 +683,17 @@ int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
644again: 683again:
645 info = tree_search_offset(block_group, offset, 0, 0); 684 info = tree_search_offset(block_group, offset, 0, 0);
646 if (!info) { 685 if (!info) {
647 WARN_ON(1); 686 /*
648 goto out_lock; 687 * oops didn't find an extent that matched the space we wanted
688 * to remove, look for a bitmap instead
689 */
690 info = tree_search_offset(block_group,
691 offset_to_bitmap(block_group, offset),
692 1, 0);
693 if (!info) {
694 WARN_ON(1);
695 goto out_lock;
696 }
649 } 697 }
650 698
651 if (info->bytes < bytes && rb_next(&info->offset_index)) { 699 if (info->bytes < bytes && rb_next(&info->offset_index)) {
@@ -957,8 +1005,15 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group,
957 if (cluster->block_group != block_group) 1005 if (cluster->block_group != block_group)
958 goto out; 1006 goto out;
959 1007
960 entry = tree_search_offset(block_group, search_start, 0, 0); 1008 /*
961 1009 * search_start is the beginning of the bitmap, but at some point it may
1010 * be a good idea to point to the actual start of the free area in the
1011 * bitmap, so do the offset_to_bitmap trick anyway, and set bitmap_only
1012 * to 1 to make sure we get the bitmap entry
1013 */
1014 entry = tree_search_offset(block_group,
1015 offset_to_bitmap(block_group, search_start),
1016 1, 0);
962 if (!entry || !entry->bitmap) 1017 if (!entry || !entry->bitmap)
963 goto out; 1018 goto out;
964 1019
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 56fe83fa60c..272b9b2bea8 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -4785,8 +4785,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
4785 * and the replacement file is large. Start IO on it now so 4785 * and the replacement file is large. Start IO on it now so
4786 * we don't add too much work to the end of the transaction 4786 * we don't add too much work to the end of the transaction
4787 */ 4787 */
4788 if (new_inode && old_inode && S_ISREG(old_inode->i_mode) && 4788 if (new_inode && S_ISREG(old_inode->i_mode) && new_inode->i_size &&
4789 new_inode->i_size &&
4790 old_inode->i_size > BTRFS_ORDERED_OPERATIONS_FLUSH_LIMIT) 4789 old_inode->i_size > BTRFS_ORDERED_OPERATIONS_FLUSH_LIMIT)
4791 filemap_flush(old_inode->i_mapping); 4790 filemap_flush(old_inode->i_mapping);
4792 4791
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index e71264d1c2c..c04f7f21260 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -2553,8 +2553,13 @@ int relocate_inode_pages(struct inode *inode, u64 start, u64 len)
2553 last_index = (start + len - 1) >> PAGE_CACHE_SHIFT; 2553 last_index = (start + len - 1) >> PAGE_CACHE_SHIFT;
2554 2554
2555 /* make sure the dirty trick played by the caller work */ 2555 /* make sure the dirty trick played by the caller work */
2556 ret = invalidate_inode_pages2_range(inode->i_mapping, 2556 while (1) {
2557 first_index, last_index); 2557 ret = invalidate_inode_pages2_range(inode->i_mapping,
2558 first_index, last_index);
2559 if (ret != -EBUSY)
2560 break;
2561 schedule_timeout(HZ/10);
2562 }
2558 if (ret) 2563 if (ret)
2559 goto out_unlock; 2564 goto out_unlock;
2560 2565
diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c
index ecfbce836d3..3e2b90eaa23 100644
--- a/fs/btrfs/zlib.c
+++ b/fs/btrfs/zlib.c
@@ -208,7 +208,7 @@ int btrfs_zlib_compress_pages(struct address_space *mapping,
208 *total_in = 0; 208 *total_in = 0;
209 209
210 workspace = find_zlib_workspace(); 210 workspace = find_zlib_workspace();
211 if (!workspace) 211 if (IS_ERR(workspace))
212 return -1; 212 return -1;
213 213
214 if (Z_OK != zlib_deflateInit(&workspace->def_strm, 3)) { 214 if (Z_OK != zlib_deflateInit(&workspace->def_strm, 3)) {
@@ -366,7 +366,7 @@ int btrfs_zlib_decompress_biovec(struct page **pages_in,
366 char *kaddr; 366 char *kaddr;
367 367
368 workspace = find_zlib_workspace(); 368 workspace = find_zlib_workspace();
369 if (!workspace) 369 if (IS_ERR(workspace))
370 return -ENOMEM; 370 return -ENOMEM;
371 371
372 data_in = kmap(pages_in[page_in_index]); 372 data_in = kmap(pages_in[page_in_index]);
@@ -547,7 +547,7 @@ int btrfs_zlib_decompress(unsigned char *data_in,
547 return -ENOMEM; 547 return -ENOMEM;
548 548
549 workspace = find_zlib_workspace(); 549 workspace = find_zlib_workspace();
550 if (!workspace) 550 if (IS_ERR(workspace))
551 return -ENOMEM; 551 return -ENOMEM;
552 552
553 workspace->inf_strm.next_in = data_in; 553 workspace->inf_strm.next_in = data_in;