Commit e5bc2458 authored by Chris Mason's avatar Chris Mason

Btrfs: tune the chunk allocation to 5% of the FS as metadata

An earlier commit tried to keep us from allocating too many
empty metadata chunks.  It was somewhat too restrictive and could
lead to ENOSPC errors on empty filesystems.

This increases the limits to about 5% of the FS size, allowing more
metadata chunks to be preallocated.
Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent 3259f8be
...@@ -580,6 +580,15 @@ static u64 div_factor(u64 num, int factor) ...@@ -580,6 +580,15 @@ static u64 div_factor(u64 num, int factor)
return num; return num;
} }
static u64 div_factor_fine(u64 num, int factor)
{
if (factor == 100)
return num;
num *= factor;
do_div(num, 100);
return num;
}
u64 btrfs_find_block_group(struct btrfs_root *root, u64 btrfs_find_block_group(struct btrfs_root *root,
u64 search_start, u64 search_hint, int owner) u64 search_start, u64 search_hint, int owner)
{ {
...@@ -3218,9 +3227,11 @@ static void force_metadata_allocation(struct btrfs_fs_info *info) ...@@ -3218,9 +3227,11 @@ static void force_metadata_allocation(struct btrfs_fs_info *info)
rcu_read_unlock(); rcu_read_unlock();
} }
static int should_alloc_chunk(struct btrfs_space_info *sinfo, u64 alloc_bytes) static int should_alloc_chunk(struct btrfs_root *root,
struct btrfs_space_info *sinfo, u64 alloc_bytes)
{ {
u64 num_bytes = sinfo->total_bytes - sinfo->bytes_readonly; u64 num_bytes = sinfo->total_bytes - sinfo->bytes_readonly;
u64 thresh;
if (sinfo->bytes_used + sinfo->bytes_reserved + if (sinfo->bytes_used + sinfo->bytes_reserved +
alloc_bytes + 256 * 1024 * 1024 < num_bytes) alloc_bytes + 256 * 1024 * 1024 < num_bytes)
...@@ -3230,8 +3241,10 @@ static int should_alloc_chunk(struct btrfs_space_info *sinfo, u64 alloc_bytes) ...@@ -3230,8 +3241,10 @@ static int should_alloc_chunk(struct btrfs_space_info *sinfo, u64 alloc_bytes)
alloc_bytes < div_factor(num_bytes, 8)) alloc_bytes < div_factor(num_bytes, 8))
return 0; return 0;
if (num_bytes > 256 * 1024 * 1024 && thresh = btrfs_super_total_bytes(&root->fs_info->super_copy);
sinfo->bytes_used < div_factor(num_bytes, 3)) thresh = max_t(u64, 256 * 1024 * 1024, div_factor_fine(thresh, 5));
if (num_bytes > thresh && sinfo->bytes_used < div_factor(num_bytes, 3))
return 0; return 0;
return 1; return 1;
...@@ -3265,7 +3278,8 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, ...@@ -3265,7 +3278,8 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
goto out; goto out;
} }
if (!force && !should_alloc_chunk(space_info, alloc_bytes)) { if (!force && !should_alloc_chunk(extent_root, space_info,
alloc_bytes)) {
spin_unlock(&space_info->lock); spin_unlock(&space_info->lock);
goto out; goto out;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment