aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2010-09-16 16:19:09 -0400
committerChris Mason <chris.mason@oracle.com>2010-10-29 09:26:36 -0400
commit67377734fd24c32cbdfeb697c2e2bd7fed519e75 (patch)
tree5b295333ab943d24b190bd3fef2486dfffa7de47 /fs/btrfs
parentdde5abee12327d59f968bbfc8151e1b04082a2c4 (diff)
Btrfs: add support for mixed data+metadata block groups
There are just a few things that need to be fixed in the kernel to support mixed data+metadata block groups. Mostly we just need to make sure that if we are using mixed block groups that we continue to allocate mixed block groups as we need them. Also we need to make sure __find_space_info will find our space info if we search for DATA or METADATA only. Tested this with xfstests and it works nicely. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com>
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 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
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 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