aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2010-10-26 13:37:56 -0400
committerChris Mason <chris.mason@oracle.com>2010-10-29 11:25:35 -0400
commite5bc2458293b2af6c0b94435965c68cc70974b56 (patch)
treed4b79f61f2ff236b080583345b4dfd617b0fca07
parent3259f8bed2f0f57c2fdcdac1b510c3fa319ef97e (diff)
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: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/extent-tree.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 372fd224a11d..980d6a3c342c 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -580,6 +580,15 @@ static u64 div_factor(u64 num, int factor)
580 return num; 580 return num;
581} 581}
582 582
583static u64 div_factor_fine(u64 num, int factor)
584{
585 if (factor == 100)
586 return num;
587 num *= factor;
588 do_div(num, 100);
589 return num;
590}
591
583u64 btrfs_find_block_group(struct btrfs_root *root, 592u64 btrfs_find_block_group(struct btrfs_root *root,
584 u64 search_start, u64 search_hint, int owner) 593 u64 search_start, u64 search_hint, int owner)
585{ 594{
@@ -3218,9 +3227,11 @@ static void force_metadata_allocation(struct btrfs_fs_info *info)
3218 rcu_read_unlock(); 3227 rcu_read_unlock();
3219} 3228}
3220 3229
3221static int should_alloc_chunk(struct btrfs_space_info *sinfo, u64 alloc_bytes) 3230static int should_alloc_chunk(struct btrfs_root *root,
3231 struct btrfs_space_info *sinfo, u64 alloc_bytes)
3222{ 3232{
3223 u64 num_bytes = sinfo->total_bytes - sinfo->bytes_readonly; 3233 u64 num_bytes = sinfo->total_bytes - sinfo->bytes_readonly;
3234 u64 thresh;
3224 3235
3225 if (sinfo->bytes_used + sinfo->bytes_reserved + 3236 if (sinfo->bytes_used + sinfo->bytes_reserved +
3226 alloc_bytes + 256 * 1024 * 1024 < num_bytes) 3237 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 alloc_bytes < div_factor(num_bytes, 8)) 3241 alloc_bytes < div_factor(num_bytes, 8))
3231 return 0; 3242 return 0;
3232 3243
3233 if (num_bytes > 256 * 1024 * 1024 && 3244 thresh = btrfs_super_total_bytes(&root->fs_info->super_copy);
3234 sinfo->bytes_used < div_factor(num_bytes, 3)) 3245 thresh = max_t(u64, 256 * 1024 * 1024, div_factor_fine(thresh, 5));
3246
3247 if (num_bytes > thresh && sinfo->bytes_used < div_factor(num_bytes, 3))
3235 return 0; 3248 return 0;
3236 3249
3237 return 1; 3250 return 1;
@@ -3265,7 +3278,8 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
3265 goto out; 3278 goto out;
3266 } 3279 }
3267 3280
3268 if (!force && !should_alloc_chunk(space_info, alloc_bytes)) { 3281 if (!force && !should_alloc_chunk(extent_root, space_info,
3282 alloc_bytes)) {
3269 spin_unlock(&space_info->lock); 3283 spin_unlock(&space_info->lock);
3270 goto out; 3284 goto out;
3271 } 3285 }