diff options
| -rw-r--r-- | fs/btrfs/ctree.h | 3 | ||||
| -rw-r--r-- | fs/btrfs/disk-io.c | 1 | ||||
| -rw-r--r-- | fs/btrfs/extent-tree.c | 28 | ||||
| -rw-r--r-- | fs/btrfs/super.c | 12 |
4 files changed, 42 insertions, 2 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index ad96495dedc..213535f45da 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 a6b83744b05..44c94d808e2 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 178df4c67de..2895a837323 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 | ||
| 1921 | static 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 | |||
| 1921 | static int do_chunk_alloc(struct btrfs_trans_handle *trans, | 1934 | static 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 9744af9d71e..30c9a8ca2a5 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 | ||
| 74 | static match_table_t tokens = { | 74 | static 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 | } |
