aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.h3
-rw-r--r--fs/btrfs/disk-io.c1
-rw-r--r--fs/btrfs/extent-tree.c28
-rw-r--r--fs/btrfs/super.c12
4 files changed, 42 insertions, 2 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index ad96495dedc5..213535f45da2 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -881,6 +881,9 @@ struct btrfs_fs_info {
881 u64 metadata_alloc_profile; 881 u64 metadata_alloc_profile;
882 u64 system_alloc_profile; 882 u64 system_alloc_profile;
883 883
884 unsigned data_chunk_allocations;
885 unsigned metadata_ratio;
886
884 void *bdev_holder; 887 void *bdev_holder;
885}; 888};
886 889
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index a6b83744b05d..44c94d808e2b 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1604,6 +1604,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1604 fs_info->btree_inode = new_inode(sb); 1604 fs_info->btree_inode = new_inode(sb);
1605 fs_info->btree_inode->i_ino = 1; 1605 fs_info->btree_inode->i_ino = 1;
1606 fs_info->btree_inode->i_nlink = 1; 1606 fs_info->btree_inode->i_nlink = 1;
1607 fs_info->metadata_ratio = 8;
1607 1608
1608 fs_info->thread_pool_size = min_t(unsigned long, 1609 fs_info->thread_pool_size = min_t(unsigned long,
1609 num_online_cpus() + 2, 8); 1610 num_online_cpus() + 2, 8);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 178df4c67de4..2895a8373232 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1918,15 +1918,29 @@ void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode,
1918 spin_unlock(&info->lock); 1918 spin_unlock(&info->lock);
1919} 1919}
1920 1920
1921static void force_metadata_allocation(struct btrfs_fs_info *info)
1922{
1923 struct list_head *head = &info->space_info;
1924 struct btrfs_space_info *found;
1925
1926 rcu_read_lock();
1927 list_for_each_entry_rcu(found, head, list) {
1928 if (found->flags & BTRFS_BLOCK_GROUP_METADATA)
1929 found->force_alloc = 1;
1930 }
1931 rcu_read_unlock();
1932}
1933
1921static int do_chunk_alloc(struct btrfs_trans_handle *trans, 1934static int do_chunk_alloc(struct btrfs_trans_handle *trans,
1922 struct btrfs_root *extent_root, u64 alloc_bytes, 1935 struct btrfs_root *extent_root, u64 alloc_bytes,
1923 u64 flags, int force) 1936 u64 flags, int force)
1924{ 1937{
1925 struct btrfs_space_info *space_info; 1938 struct btrfs_space_info *space_info;
1939 struct btrfs_fs_info *fs_info = extent_root->fs_info;
1926 u64 thresh; 1940 u64 thresh;
1927 int ret = 0; 1941 int ret = 0;
1928 1942
1929 mutex_lock(&extent_root->fs_info->chunk_mutex); 1943 mutex_lock(&fs_info->chunk_mutex);
1930 1944
1931 flags = btrfs_reduce_alloc_profile(extent_root, flags); 1945 flags = btrfs_reduce_alloc_profile(extent_root, flags);
1932 1946
@@ -1958,6 +1972,18 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
1958 } 1972 }
1959 spin_unlock(&space_info->lock); 1973 spin_unlock(&space_info->lock);
1960 1974
1975 /*
1976 * if we're doing a data chunk, go ahead and make sure that
1977 * we keep a reasonable number of metadata chunks allocated in the
1978 * FS as well.
1979 */
1980 if (flags & BTRFS_BLOCK_GROUP_DATA) {
1981 fs_info->data_chunk_allocations++;
1982 if (!(fs_info->data_chunk_allocations %
1983 fs_info->metadata_ratio))
1984 force_metadata_allocation(fs_info);
1985 }
1986
1961 ret = btrfs_alloc_chunk(trans, extent_root, flags); 1987 ret = btrfs_alloc_chunk(trans, extent_root, flags);
1962 if (ret) 1988 if (ret)
1963 space_info->full = 1; 1989 space_info->full = 1;
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 9744af9d71e9..30c9a8ca2a54 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -68,7 +68,7 @@ enum {
68 Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow, 68 Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow,
69 Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, 69 Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier,
70 Opt_ssd, Opt_thread_pool, Opt_noacl, Opt_compress, Opt_notreelog, 70 Opt_ssd, Opt_thread_pool, Opt_noacl, Opt_compress, Opt_notreelog,
71 Opt_flushoncommit, Opt_err, 71 Opt_ratio, Opt_flushoncommit, Opt_err,
72}; 72};
73 73
74static match_table_t tokens = { 74static match_table_t tokens = {
@@ -87,6 +87,7 @@ static match_table_t tokens = {
87 {Opt_noacl, "noacl"}, 87 {Opt_noacl, "noacl"},
88 {Opt_notreelog, "notreelog"}, 88 {Opt_notreelog, "notreelog"},
89 {Opt_flushoncommit, "flushoncommit"}, 89 {Opt_flushoncommit, "flushoncommit"},
90 {Opt_ratio, "metadata_ratio=%d"},
90 {Opt_err, NULL}, 91 {Opt_err, NULL},
91}; 92};
92 93
@@ -234,6 +235,15 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
234 printk(KERN_INFO "btrfs: turning on flush-on-commit\n"); 235 printk(KERN_INFO "btrfs: turning on flush-on-commit\n");
235 btrfs_set_opt(info->mount_opt, FLUSHONCOMMIT); 236 btrfs_set_opt(info->mount_opt, FLUSHONCOMMIT);
236 break; 237 break;
238 case Opt_ratio:
239 intarg = 0;
240 match_int(&args[0], &intarg);
241 if (intarg) {
242 info->metadata_ratio = intarg;
243 printk(KERN_INFO "btrfs: metadata ratio %d\n",
244 info->metadata_ratio);
245 }
246 break;
237 default: 247 default:
238 break; 248 break;
239 } 249 }