aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.h10
-rw-r--r--fs/btrfs/extent-tree.c22
2 files changed, 28 insertions, 4 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 2c06b37cda7..b155a0e49ee 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
2051static 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 */
2050void btrfs_put_block_group(struct btrfs_block_group_cache *cache); 2058void btrfs_put_block_group(struct btrfs_block_group_cache *cache);
2051int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, 2059int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 5c9ef3ac25e..137833e1fc2 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