aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
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/btrfs/extent-tree.c
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/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c28
1 files changed, 27 insertions, 1 deletions
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;