aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2012-09-11 16:57:25 -0400
committerChris Mason <chris.mason@fusionio.com>2012-10-01 15:19:21 -0400
commitea658badc47e614e38ab4d98510488474c7e6d4b (patch)
treebab3ed9faaab577332de89c5d967a8e17b2e4c30 /fs/btrfs/extent-tree.c
parentbe3940c0a90265654d778394cafe2e2cec674df8 (diff)
Btrfs: delay block group item insertion
So we have lots of places where we try to preallocate chunks in order to make sure we have enough space as we make our allocations. This has historically meant that we're constantly tweaking when we should allocate a new chunk, and historically we have gotten this horribly wrong so we way over allocate either metadata or data. To try and keep this from happening we are going to make it so that the block group item insertion is done out of band at the end of a transaction. This will allow us to create chunks even if we are trying to make an allocation for the extent tree. With this patch my enospc tests run faster (didn't expect this) and more efficiently use the disk space (this is what I wanted). Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c130
1 files changed, 63 insertions, 67 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index a8de1c30f21..254fd3289f4 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2361,10 +2361,6 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,
2361 } 2361 }
2362 2362
2363next: 2363next:
2364 do_chunk_alloc(trans, fs_info->extent_root,
2365 2 * 1024 * 1024,
2366 btrfs_get_alloc_profile(root, 0),
2367 CHUNK_ALLOC_NO_FORCE);
2368 cond_resched(); 2364 cond_resched();
2369 spin_lock(&delayed_refs->lock); 2365 spin_lock(&delayed_refs->lock);
2370 } 2366 }
@@ -2478,10 +2474,6 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
2478 if (root == root->fs_info->extent_root) 2474 if (root == root->fs_info->extent_root)
2479 root = root->fs_info->tree_root; 2475 root = root->fs_info->tree_root;
2480 2476
2481 do_chunk_alloc(trans, root->fs_info->extent_root,
2482 2 * 1024 * 1024, btrfs_get_alloc_profile(root, 0),
2483 CHUNK_ALLOC_NO_FORCE);
2484
2485 btrfs_delayed_refs_qgroup_accounting(trans, root->fs_info); 2477 btrfs_delayed_refs_qgroup_accounting(trans, root->fs_info);
2486 2478
2487 delayed_refs = &trans->transaction->delayed_refs; 2479 delayed_refs = &trans->transaction->delayed_refs;
@@ -2551,6 +2543,12 @@ again:
2551 } 2543 }
2552 2544
2553 if (run_all) { 2545 if (run_all) {
2546 if (!list_empty(&trans->new_bgs)) {
2547 spin_unlock(&delayed_refs->lock);
2548 btrfs_create_pending_block_groups(trans, root);
2549 spin_lock(&delayed_refs->lock);
2550 }
2551
2554 node = rb_first(&delayed_refs->root); 2552 node = rb_first(&delayed_refs->root);
2555 if (!node) 2553 if (!node)
2556 goto out; 2554 goto out;
@@ -3826,7 +3824,8 @@ enum flush_state {
3826 FLUSH_DELALLOC_WAIT = 2, 3824 FLUSH_DELALLOC_WAIT = 2,
3827 FLUSH_DELAYED_ITEMS_NR = 3, 3825 FLUSH_DELAYED_ITEMS_NR = 3,
3828 FLUSH_DELAYED_ITEMS = 4, 3826 FLUSH_DELAYED_ITEMS = 4,
3829 COMMIT_TRANS = 5, 3827 ALLOC_CHUNK = 5,
3828 COMMIT_TRANS = 6,
3830}; 3829};
3831 3830
3832static int flush_space(struct btrfs_root *root, 3831static int flush_space(struct btrfs_root *root,
@@ -3863,6 +3862,20 @@ static int flush_space(struct btrfs_root *root,
3863 ret = btrfs_run_delayed_items_nr(trans, root, nr); 3862 ret = btrfs_run_delayed_items_nr(trans, root, nr);
3864 btrfs_end_transaction(trans, root); 3863 btrfs_end_transaction(trans, root);
3865 break; 3864 break;
3865 case ALLOC_CHUNK:
3866 trans = btrfs_join_transaction(root);
3867 if (IS_ERR(trans)) {
3868 ret = PTR_ERR(trans);
3869 break;
3870 }
3871 ret = do_chunk_alloc(trans, root->fs_info->extent_root,
3872 num_bytes,
3873 btrfs_get_alloc_profile(root, 0),
3874 CHUNK_ALLOC_NO_FORCE);
3875 btrfs_end_transaction(trans, root);
3876 if (ret == -ENOSPC)
3877 ret = 0;
3878 break;
3866 case COMMIT_TRANS: 3879 case COMMIT_TRANS:
3867 ret = may_commit_transaction(root, space_info, orig_bytes, 0); 3880 ret = may_commit_transaction(root, space_info, orig_bytes, 0);
3868 break; 3881 break;
@@ -5515,8 +5528,6 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
5515 struct btrfs_block_group_cache *used_block_group; 5528 struct btrfs_block_group_cache *used_block_group;
5516 u64 search_start = 0; 5529 u64 search_start = 0;
5517 int empty_cluster = 2 * 1024 * 1024; 5530 int empty_cluster = 2 * 1024 * 1024;
5518 int allowed_chunk_alloc = 0;
5519 int done_chunk_alloc = 0;
5520 struct btrfs_space_info *space_info; 5531 struct btrfs_space_info *space_info;
5521 int loop = 0; 5532 int loop = 0;
5522 int index = 0; 5533 int index = 0;
@@ -5548,9 +5559,6 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
5548 if (btrfs_mixed_space_info(space_info)) 5559 if (btrfs_mixed_space_info(space_info))
5549 use_cluster = false; 5560 use_cluster = false;
5550 5561
5551 if (orig_root->ref_cows || empty_size)
5552 allowed_chunk_alloc = 1;
5553
5554 if (data & BTRFS_BLOCK_GROUP_METADATA && use_cluster) { 5562 if (data & BTRFS_BLOCK_GROUP_METADATA && use_cluster) {
5555 last_ptr = &root->fs_info->meta_alloc_cluster; 5563 last_ptr = &root->fs_info->meta_alloc_cluster;
5556 if (!btrfs_test_opt(root, SSD)) 5564 if (!btrfs_test_opt(root, SSD))
@@ -5860,34 +5868,18 @@ loop:
5860 index = 0; 5868 index = 0;
5861 loop++; 5869 loop++;
5862 if (loop == LOOP_ALLOC_CHUNK) { 5870 if (loop == LOOP_ALLOC_CHUNK) {
5863 if (allowed_chunk_alloc) { 5871 ret = do_chunk_alloc(trans, root, num_bytes +
5864 ret = do_chunk_alloc(trans, root, num_bytes + 5872 2 * 1024 * 1024, data,
5865 2 * 1024 * 1024, data, 5873 CHUNK_ALLOC_FORCE);
5866 CHUNK_ALLOC_LIMITED); 5874 /*
5867 /* 5875 * Do not bail out on ENOSPC since we
5868 * Do not bail out on ENOSPC since we 5876 * can do more things.
5869 * can do more things. 5877 */
5870 */ 5878 if (ret < 0 && ret != -ENOSPC) {
5871 if (ret < 0 && ret != -ENOSPC) { 5879 btrfs_abort_transaction(trans,
5872 btrfs_abort_transaction(trans, 5880 root, ret);
5873 root, ret); 5881 goto out;
5874 goto out;
5875 }
5876 allowed_chunk_alloc = 0;
5877 if (ret == 1)
5878 done_chunk_alloc = 1;
5879 } else if (!done_chunk_alloc &&
5880 space_info->force_alloc ==
5881 CHUNK_ALLOC_NO_FORCE) {
5882 space_info->force_alloc = CHUNK_ALLOC_LIMITED;
5883 } 5882 }
5884
5885 /*
5886 * We didn't allocate a chunk, go ahead and drop the
5887 * empty size and loop again.
5888 */
5889 if (!done_chunk_alloc)
5890 loop = LOOP_NO_EMPTY_SIZE;
5891 } 5883 }
5892 5884
5893 if (loop == LOOP_NO_EMPTY_SIZE) { 5885 if (loop == LOOP_NO_EMPTY_SIZE) {
@@ -5962,20 +5954,6 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans,
5962 5954
5963 data = btrfs_get_alloc_profile(root, data); 5955 data = btrfs_get_alloc_profile(root, data);
5964again: 5956again:
5965 /*
5966 * the only place that sets empty_size is btrfs_realloc_node, which
5967 * is not called recursively on allocations
5968 */
5969 if (empty_size || root->ref_cows) {
5970 ret = do_chunk_alloc(trans, root->fs_info->extent_root,
5971 num_bytes + 2 * 1024 * 1024, data,
5972 CHUNK_ALLOC_NO_FORCE);
5973 if (ret < 0 && ret != -ENOSPC) {
5974 btrfs_abort_transaction(trans, root, ret);
5975 return ret;
5976 }
5977 }
5978
5979 WARN_ON(num_bytes < root->sectorsize); 5957 WARN_ON(num_bytes < root->sectorsize);
5980 ret = find_free_extent(trans, root, num_bytes, empty_size, 5958 ret = find_free_extent(trans, root, num_bytes, empty_size,
5981 hint_byte, ins, data); 5959 hint_byte, ins, data);
@@ -5985,12 +5963,6 @@ again:
5985 num_bytes = num_bytes >> 1; 5963 num_bytes = num_bytes >> 1;
5986 num_bytes = num_bytes & ~(root->sectorsize - 1); 5964 num_bytes = num_bytes & ~(root->sectorsize - 1);
5987 num_bytes = max(num_bytes, min_alloc_size); 5965 num_bytes = max(num_bytes, min_alloc_size);
5988 ret = do_chunk_alloc(trans, root->fs_info->extent_root,
5989 num_bytes, data, CHUNK_ALLOC_FORCE);
5990 if (ret < 0 && ret != -ENOSPC) {
5991 btrfs_abort_transaction(trans, root, ret);
5992 return ret;
5993 }
5994 if (num_bytes == min_alloc_size) 5966 if (num_bytes == min_alloc_size)
5995 final_tried = true; 5967 final_tried = true;
5996 goto again; 5968 goto again;
@@ -7828,6 +7800,34 @@ error:
7828 return ret; 7800 return ret;
7829} 7801}
7830 7802
7803void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans,
7804 struct btrfs_root *root)
7805{
7806 struct btrfs_block_group_cache *block_group, *tmp;
7807 struct btrfs_root *extent_root = root->fs_info->extent_root;
7808 struct btrfs_block_group_item item;
7809 struct btrfs_key key;
7810 int ret = 0;
7811
7812 list_for_each_entry_safe(block_group, tmp, &trans->new_bgs,
7813 new_bg_list) {
7814 list_del_init(&block_group->new_bg_list);
7815
7816 if (ret)
7817 continue;
7818
7819 spin_lock(&block_group->lock);
7820 memcpy(&item, &block_group->item, sizeof(item));
7821 memcpy(&key, &block_group->key, sizeof(key));
7822 spin_unlock(&block_group->lock);
7823
7824 ret = btrfs_insert_item(trans, extent_root, &key, &item,
7825 sizeof(item));
7826 if (ret)
7827 btrfs_abort_transaction(trans, extent_root, ret);
7828 }
7829}
7830
7831int btrfs_make_block_group(struct btrfs_trans_handle *trans, 7831int btrfs_make_block_group(struct btrfs_trans_handle *trans,
7832 struct btrfs_root *root, u64 bytes_used, 7832 struct btrfs_root *root, u64 bytes_used,
7833 u64 type, u64 chunk_objectid, u64 chunk_offset, 7833 u64 type, u64 chunk_objectid, u64 chunk_offset,
@@ -7861,6 +7861,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
7861 spin_lock_init(&cache->lock); 7861 spin_lock_init(&cache->lock);
7862 INIT_LIST_HEAD(&cache->list); 7862 INIT_LIST_HEAD(&cache->list);
7863 INIT_LIST_HEAD(&cache->cluster_list); 7863 INIT_LIST_HEAD(&cache->cluster_list);
7864 INIT_LIST_HEAD(&cache->new_bg_list);
7864 7865
7865 btrfs_init_free_space_ctl(cache); 7866 btrfs_init_free_space_ctl(cache);
7866 7867
@@ -7892,12 +7893,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
7892 ret = btrfs_add_block_group_cache(root->fs_info, cache); 7893 ret = btrfs_add_block_group_cache(root->fs_info, cache);
7893 BUG_ON(ret); /* Logic error */ 7894 BUG_ON(ret); /* Logic error */
7894 7895
7895 ret = btrfs_insert_item(trans, extent_root, &cache->key, &cache->item, 7896 list_add_tail(&cache->new_bg_list, &trans->new_bgs);
7896 sizeof(cache->item));
7897 if (ret) {
7898 btrfs_abort_transaction(trans, extent_root, ret);
7899 return ret;
7900 }
7901 7897
7902 set_avail_alloc_bits(extent_root->fs_info, type); 7898 set_avail_alloc_bits(extent_root->fs_info, type);
7903 7899