aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@redhat.com>2009-04-21 17:40:57 -0400
committerChris Mason <chris.mason@oracle.com>2009-04-24 15:46:02 -0400
commit97e728d4353f38c87bf0804cdfd79a9b13fc2c3e (patch)
tree853d3317ff1476e4ad28921265e28b4919196304 /fs
parent546888da82082555a56528730a83f0afd12f33bf (diff)
Btrfs: try to keep a healthy ratio of metadata vs data block groups
This patch makes the chunk allocator keep a good ratio of metadata vs data block groups. By default for every 8 data block groups, we'll allocate 1 metadata chunk, or about 12% of the disk will be allocated for metadata. This can be changed by specifying the metadata_ratio mount option. This is simply the number of data block groups that have to be allocated to force a metadata chunk allocation. By making sure we allocate metadata chunks more often, we are less likely to get into situations where the whole disk has been allocated as data block groups. Signed-off-by: Josef Bacik <jbacik@redhat.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-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 }