diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
| -rw-r--r-- | fs/btrfs/extent-tree.c | 103 |
1 files changed, 68 insertions, 35 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 169bd62ce776..5b9b6b6df242 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -348,7 +348,7 @@ static int caching_kthread(void *data) | |||
| 348 | */ | 348 | */ |
| 349 | path->skip_locking = 1; | 349 | path->skip_locking = 1; |
| 350 | path->search_commit_root = 1; | 350 | path->search_commit_root = 1; |
| 351 | path->reada = 2; | 351 | path->reada = 1; |
| 352 | 352 | ||
| 353 | key.objectid = last; | 353 | key.objectid = last; |
| 354 | key.offset = 0; | 354 | key.offset = 0; |
| @@ -366,8 +366,7 @@ again: | |||
| 366 | nritems = btrfs_header_nritems(leaf); | 366 | nritems = btrfs_header_nritems(leaf); |
| 367 | 367 | ||
| 368 | while (1) { | 368 | while (1) { |
| 369 | smp_mb(); | 369 | if (btrfs_fs_closing(fs_info) > 1) { |
| 370 | if (fs_info->closing > 1) { | ||
| 371 | last = (u64)-1; | 370 | last = (u64)-1; |
| 372 | break; | 371 | break; |
| 373 | } | 372 | } |
| @@ -379,15 +378,18 @@ again: | |||
| 379 | if (ret) | 378 | if (ret) |
| 380 | break; | 379 | break; |
| 381 | 380 | ||
| 382 | caching_ctl->progress = last; | 381 | if (need_resched() || |
| 383 | btrfs_release_path(path); | 382 | btrfs_next_leaf(extent_root, path)) { |
| 384 | up_read(&fs_info->extent_commit_sem); | 383 | caching_ctl->progress = last; |
| 385 | mutex_unlock(&caching_ctl->mutex); | 384 | btrfs_release_path(path); |
| 386 | if (btrfs_transaction_in_commit(fs_info)) | 385 | up_read(&fs_info->extent_commit_sem); |
| 387 | schedule_timeout(1); | 386 | mutex_unlock(&caching_ctl->mutex); |
| 388 | else | ||
| 389 | cond_resched(); | 387 | cond_resched(); |
| 390 | goto again; | 388 | goto again; |
| 389 | } | ||
| 390 | leaf = path->nodes[0]; | ||
| 391 | nritems = btrfs_header_nritems(leaf); | ||
| 392 | continue; | ||
| 391 | } | 393 | } |
| 392 | 394 | ||
| 393 | if (key.objectid < block_group->key.objectid) { | 395 | if (key.objectid < block_group->key.objectid) { |
| @@ -3065,7 +3067,7 @@ again: | |||
| 3065 | spin_unlock(&data_sinfo->lock); | 3067 | spin_unlock(&data_sinfo->lock); |
| 3066 | alloc: | 3068 | alloc: |
| 3067 | alloc_target = btrfs_get_alloc_profile(root, 1); | 3069 | alloc_target = btrfs_get_alloc_profile(root, 1); |
| 3068 | trans = btrfs_join_transaction(root, 1); | 3070 | trans = btrfs_join_transaction(root); |
| 3069 | if (IS_ERR(trans)) | 3071 | if (IS_ERR(trans)) |
| 3070 | return PTR_ERR(trans); | 3072 | return PTR_ERR(trans); |
| 3071 | 3073 | ||
| @@ -3091,9 +3093,10 @@ alloc: | |||
| 3091 | 3093 | ||
| 3092 | /* commit the current transaction and try again */ | 3094 | /* commit the current transaction and try again */ |
| 3093 | commit_trans: | 3095 | commit_trans: |
| 3094 | if (!committed && !root->fs_info->open_ioctl_trans) { | 3096 | if (!committed && |
| 3097 | !atomic_read(&root->fs_info->open_ioctl_trans)) { | ||
| 3095 | committed = 1; | 3098 | committed = 1; |
| 3096 | trans = btrfs_join_transaction(root, 1); | 3099 | trans = btrfs_join_transaction(root); |
| 3097 | if (IS_ERR(trans)) | 3100 | if (IS_ERR(trans)) |
| 3098 | return PTR_ERR(trans); | 3101 | return PTR_ERR(trans); |
| 3099 | ret = btrfs_commit_transaction(trans, root); | 3102 | ret = btrfs_commit_transaction(trans, root); |
| @@ -3472,7 +3475,7 @@ again: | |||
| 3472 | goto out; | 3475 | goto out; |
| 3473 | 3476 | ||
| 3474 | ret = -ENOSPC; | 3477 | ret = -ENOSPC; |
| 3475 | trans = btrfs_join_transaction(root, 1); | 3478 | trans = btrfs_join_transaction(root); |
| 3476 | if (IS_ERR(trans)) | 3479 | if (IS_ERR(trans)) |
| 3477 | goto out; | 3480 | goto out; |
| 3478 | ret = btrfs_commit_transaction(trans, root); | 3481 | ret = btrfs_commit_transaction(trans, root); |
| @@ -3699,7 +3702,7 @@ int btrfs_block_rsv_check(struct btrfs_trans_handle *trans, | |||
| 3699 | if (trans) | 3702 | if (trans) |
| 3700 | return -EAGAIN; | 3703 | return -EAGAIN; |
| 3701 | 3704 | ||
| 3702 | trans = btrfs_join_transaction(root, 1); | 3705 | trans = btrfs_join_transaction(root); |
| 3703 | BUG_ON(IS_ERR(trans)); | 3706 | BUG_ON(IS_ERR(trans)); |
| 3704 | ret = btrfs_commit_transaction(trans, root); | 3707 | ret = btrfs_commit_transaction(trans, root); |
| 3705 | return 0; | 3708 | return 0; |
| @@ -3837,6 +3840,37 @@ static void release_global_block_rsv(struct btrfs_fs_info *fs_info) | |||
| 3837 | WARN_ON(fs_info->chunk_block_rsv.reserved > 0); | 3840 | WARN_ON(fs_info->chunk_block_rsv.reserved > 0); |
| 3838 | } | 3841 | } |
| 3839 | 3842 | ||
| 3843 | int btrfs_truncate_reserve_metadata(struct btrfs_trans_handle *trans, | ||
| 3844 | struct btrfs_root *root, | ||
| 3845 | struct btrfs_block_rsv *rsv) | ||
| 3846 | { | ||
| 3847 | struct btrfs_block_rsv *trans_rsv = &root->fs_info->trans_block_rsv; | ||
| 3848 | u64 num_bytes; | ||
| 3849 | int ret; | ||
| 3850 | |||
| 3851 | /* | ||
| 3852 | * Truncate should be freeing data, but give us 2 items just in case it | ||
| 3853 | * needs to use some space. We may want to be smarter about this in the | ||
| 3854 | * future. | ||
| 3855 | */ | ||
| 3856 | num_bytes = btrfs_calc_trans_metadata_size(root, 2); | ||
| 3857 | |||
| 3858 | /* We already have enough bytes, just return */ | ||
| 3859 | if (rsv->reserved >= num_bytes) | ||
| 3860 | return 0; | ||
| 3861 | |||
| 3862 | num_bytes -= rsv->reserved; | ||
| 3863 | |||
| 3864 | /* | ||
| 3865 | * You should have reserved enough space before hand to do this, so this | ||
| 3866 | * should not fail. | ||
| 3867 | */ | ||
| 3868 | ret = block_rsv_migrate_bytes(trans_rsv, rsv, num_bytes); | ||
| 3869 | BUG_ON(ret); | ||
| 3870 | |||
| 3871 | return 0; | ||
| 3872 | } | ||
| 3873 | |||
| 3840 | int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans, | 3874 | int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans, |
| 3841 | struct btrfs_root *root, | 3875 | struct btrfs_root *root, |
| 3842 | int num_items) | 3876 | int num_items) |
| @@ -3877,23 +3911,18 @@ int btrfs_orphan_reserve_metadata(struct btrfs_trans_handle *trans, | |||
| 3877 | struct btrfs_block_rsv *dst_rsv = root->orphan_block_rsv; | 3911 | struct btrfs_block_rsv *dst_rsv = root->orphan_block_rsv; |
| 3878 | 3912 | ||
| 3879 | /* | 3913 | /* |
| 3880 | * one for deleting orphan item, one for updating inode and | 3914 | * We need to hold space in order to delete our orphan item once we've |
| 3881 | * two for calling btrfs_truncate_inode_items. | 3915 | * added it, so this takes the reservation so we can release it later |
| 3882 | * | 3916 | * when we are truly done with the orphan item. |
| 3883 | * btrfs_truncate_inode_items is a delete operation, it frees | ||
| 3884 | * more space than it uses in most cases. So two units of | ||
| 3885 | * metadata space should be enough for calling it many times. | ||
| 3886 | * If all of the metadata space is used, we can commit | ||
| 3887 | * transaction and use space it freed. | ||
| 3888 | */ | 3917 | */ |
| 3889 | u64 num_bytes = btrfs_calc_trans_metadata_size(root, 4); | 3918 | u64 num_bytes = btrfs_calc_trans_metadata_size(root, 1); |
| 3890 | return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes); | 3919 | return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes); |
| 3891 | } | 3920 | } |
| 3892 | 3921 | ||
| 3893 | void btrfs_orphan_release_metadata(struct inode *inode) | 3922 | void btrfs_orphan_release_metadata(struct inode *inode) |
| 3894 | { | 3923 | { |
| 3895 | struct btrfs_root *root = BTRFS_I(inode)->root; | 3924 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 3896 | u64 num_bytes = btrfs_calc_trans_metadata_size(root, 4); | 3925 | u64 num_bytes = btrfs_calc_trans_metadata_size(root, 1); |
| 3897 | btrfs_block_rsv_release(root, root->orphan_block_rsv, num_bytes); | 3926 | btrfs_block_rsv_release(root, root->orphan_block_rsv, num_bytes); |
| 3898 | } | 3927 | } |
| 3899 | 3928 | ||
| @@ -4987,6 +5016,15 @@ have_block_group: | |||
| 4987 | if (unlikely(block_group->ro)) | 5016 | if (unlikely(block_group->ro)) |
| 4988 | goto loop; | 5017 | goto loop; |
| 4989 | 5018 | ||
| 5019 | spin_lock(&block_group->free_space_ctl->tree_lock); | ||
| 5020 | if (cached && | ||
| 5021 | block_group->free_space_ctl->free_space < | ||
| 5022 | num_bytes + empty_size) { | ||
| 5023 | spin_unlock(&block_group->free_space_ctl->tree_lock); | ||
| 5024 | goto loop; | ||
| 5025 | } | ||
| 5026 | spin_unlock(&block_group->free_space_ctl->tree_lock); | ||
| 5027 | |||
| 4990 | /* | 5028 | /* |
| 4991 | * Ok we want to try and use the cluster allocator, so lets look | 5029 | * Ok we want to try and use the cluster allocator, so lets look |
| 4992 | * there, unless we are on LOOP_NO_EMPTY_SIZE, since we will | 5030 | * there, unless we are on LOOP_NO_EMPTY_SIZE, since we will |
| @@ -5150,6 +5188,7 @@ checks: | |||
| 5150 | btrfs_add_free_space(block_group, offset, | 5188 | btrfs_add_free_space(block_group, offset, |
| 5151 | search_start - offset); | 5189 | search_start - offset); |
| 5152 | BUG_ON(offset > search_start); | 5190 | BUG_ON(offset > search_start); |
| 5191 | btrfs_put_block_group(block_group); | ||
| 5153 | break; | 5192 | break; |
| 5154 | loop: | 5193 | loop: |
| 5155 | failed_cluster_refill = false; | 5194 | failed_cluster_refill = false; |
| @@ -5242,14 +5281,7 @@ loop: | |||
| 5242 | ret = -ENOSPC; | 5281 | ret = -ENOSPC; |
| 5243 | } else if (!ins->objectid) { | 5282 | } else if (!ins->objectid) { |
| 5244 | ret = -ENOSPC; | 5283 | ret = -ENOSPC; |
| 5245 | } | 5284 | } else if (ins->objectid) { |
| 5246 | |||
| 5247 | /* we found what we needed */ | ||
| 5248 | if (ins->objectid) { | ||
| 5249 | if (!(data & BTRFS_BLOCK_GROUP_DATA)) | ||
| 5250 | trans->block_group = block_group->key.objectid; | ||
| 5251 | |||
| 5252 | btrfs_put_block_group(block_group); | ||
| 5253 | ret = 0; | 5285 | ret = 0; |
| 5254 | } | 5286 | } |
| 5255 | 5287 | ||
| @@ -6526,7 +6558,7 @@ int btrfs_set_block_group_ro(struct btrfs_root *root, | |||
| 6526 | 6558 | ||
| 6527 | BUG_ON(cache->ro); | 6559 | BUG_ON(cache->ro); |
| 6528 | 6560 | ||
| 6529 | trans = btrfs_join_transaction(root, 1); | 6561 | trans = btrfs_join_transaction(root); |
| 6530 | BUG_ON(IS_ERR(trans)); | 6562 | BUG_ON(IS_ERR(trans)); |
| 6531 | 6563 | ||
| 6532 | alloc_flags = update_block_group_flags(root, cache->flags); | 6564 | alloc_flags = update_block_group_flags(root, cache->flags); |
| @@ -6882,6 +6914,7 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
| 6882 | path = btrfs_alloc_path(); | 6914 | path = btrfs_alloc_path(); |
| 6883 | if (!path) | 6915 | if (!path) |
| 6884 | return -ENOMEM; | 6916 | return -ENOMEM; |
| 6917 | path->reada = 1; | ||
| 6885 | 6918 | ||
| 6886 | cache_gen = btrfs_super_cache_generation(&root->fs_info->super_copy); | 6919 | cache_gen = btrfs_super_cache_generation(&root->fs_info->super_copy); |
| 6887 | if (cache_gen != 0 && | 6920 | if (cache_gen != 0 && |
