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 | ||
