diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
| -rw-r--r-- | fs/btrfs/extent-tree.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 5c9ef3ac25e1..137833e1fc26 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -547,7 +547,7 @@ static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info, | |||
| 547 | 547 | ||
| 548 | rcu_read_lock(); | 548 | rcu_read_lock(); |
| 549 | list_for_each_entry_rcu(found, head, list) { | 549 | list_for_each_entry_rcu(found, head, list) { |
| 550 | if (found->flags == flags) { | 550 | if (found->flags & flags) { |
| 551 | rcu_read_unlock(); | 551 | rcu_read_unlock(); |
| 552 | return found; | 552 | return found; |
| 553 | } | 553 | } |
| @@ -3267,6 +3267,13 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, | |||
| 3267 | spin_unlock(&space_info->lock); | 3267 | spin_unlock(&space_info->lock); |
| 3268 | 3268 | ||
| 3269 | /* | 3269 | /* |
| 3270 | * If we have mixed data/metadata chunks we want to make sure we keep | ||
| 3271 | * allocating mixed chunks instead of individual chunks. | ||
| 3272 | */ | ||
| 3273 | if (btrfs_mixed_space_info(space_info)) | ||
| 3274 | flags |= (BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA); | ||
| 3275 | |||
| 3276 | /* | ||
| 3270 | * if we're doing a data chunk, go ahead and make sure that | 3277 | * if we're doing a data chunk, go ahead and make sure that |
| 3271 | * we keep a reasonable number of metadata chunks allocated in the | 3278 | * we keep a reasonable number of metadata chunks allocated in the |
| 3272 | * FS as well. | 3279 | * FS as well. |
| @@ -4787,6 +4794,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
| 4787 | bool found_uncached_bg = false; | 4794 | bool found_uncached_bg = false; |
| 4788 | bool failed_cluster_refill = false; | 4795 | bool failed_cluster_refill = false; |
| 4789 | bool failed_alloc = false; | 4796 | bool failed_alloc = false; |
| 4797 | bool use_cluster = true; | ||
| 4790 | u64 ideal_cache_percent = 0; | 4798 | u64 ideal_cache_percent = 0; |
| 4791 | u64 ideal_cache_offset = 0; | 4799 | u64 ideal_cache_offset = 0; |
| 4792 | 4800 | ||
| @@ -4801,16 +4809,24 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
| 4801 | return -ENOSPC; | 4809 | return -ENOSPC; |
| 4802 | } | 4810 | } |
| 4803 | 4811 | ||
| 4812 | /* | ||
| 4813 | * If the space info is for both data and metadata it means we have a | ||
| 4814 | * small filesystem and we can't use the clustering stuff. | ||
| 4815 | */ | ||
| 4816 | if (btrfs_mixed_space_info(space_info)) | ||
| 4817 | use_cluster = false; | ||
| 4818 | |||
| 4804 | if (orig_root->ref_cows || empty_size) | 4819 | if (orig_root->ref_cows || empty_size) |
| 4805 | allowed_chunk_alloc = 1; | 4820 | allowed_chunk_alloc = 1; |
| 4806 | 4821 | ||
| 4807 | if (data & BTRFS_BLOCK_GROUP_METADATA) { | 4822 | if (data & BTRFS_BLOCK_GROUP_METADATA && use_cluster) { |
| 4808 | last_ptr = &root->fs_info->meta_alloc_cluster; | 4823 | last_ptr = &root->fs_info->meta_alloc_cluster; |
| 4809 | if (!btrfs_test_opt(root, SSD)) | 4824 | if (!btrfs_test_opt(root, SSD)) |
| 4810 | empty_cluster = 64 * 1024; | 4825 | empty_cluster = 64 * 1024; |
| 4811 | } | 4826 | } |
| 4812 | 4827 | ||
| 4813 | if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD)) { | 4828 | if ((data & BTRFS_BLOCK_GROUP_DATA) && use_cluster && |
| 4829 | btrfs_test_opt(root, SSD)) { | ||
| 4814 | last_ptr = &root->fs_info->data_alloc_cluster; | 4830 | last_ptr = &root->fs_info->data_alloc_cluster; |
| 4815 | } | 4831 | } |
| 4816 | 4832 | ||
