diff options
-rw-r--r-- | fs/btrfs/ctree.h | 10 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 22 |
2 files changed, 28 insertions, 4 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 2c06b37cda75..b155a0e49eeb 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -397,12 +397,14 @@ struct btrfs_super_block { | |||
397 | */ | 397 | */ |
398 | #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0) | 398 | #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0) |
399 | #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1) | 399 | #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1) |
400 | #define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS (1ULL << 2) | ||
400 | 401 | ||
401 | #define BTRFS_FEATURE_COMPAT_SUPP 0ULL | 402 | #define BTRFS_FEATURE_COMPAT_SUPP 0ULL |
402 | #define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL | 403 | #define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL |
403 | #define BTRFS_FEATURE_INCOMPAT_SUPP \ | 404 | #define BTRFS_FEATURE_INCOMPAT_SUPP \ |
404 | (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \ | 405 | (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \ |
405 | BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL) | 406 | BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL | \ |
407 | BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) | ||
406 | 408 | ||
407 | /* | 409 | /* |
408 | * A leaf is full of items. offset and size tell us where to find | 410 | * A leaf is full of items. offset and size tell us where to find |
@@ -2046,6 +2048,12 @@ static inline struct dentry *fdentry(struct file *file) | |||
2046 | return file->f_path.dentry; | 2048 | return file->f_path.dentry; |
2047 | } | 2049 | } |
2048 | 2050 | ||
2051 | static inline bool btrfs_mixed_space_info(struct btrfs_space_info *space_info) | ||
2052 | { | ||
2053 | return ((space_info->flags & BTRFS_BLOCK_GROUP_METADATA) && | ||
2054 | (space_info->flags & BTRFS_BLOCK_GROUP_DATA)); | ||
2055 | } | ||
2056 | |||
2049 | /* extent-tree.c */ | 2057 | /* extent-tree.c */ |
2050 | void btrfs_put_block_group(struct btrfs_block_group_cache *cache); | 2058 | void btrfs_put_block_group(struct btrfs_block_group_cache *cache); |
2051 | int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, | 2059 | int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, |
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 | ||