diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/extent-tree.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 372fd224a11..980d6a3c342 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 | ||
583 | static 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 | |||
583 | u64 btrfs_find_block_group(struct btrfs_root *root, | 592 | u64 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 | ||
3221 | static int should_alloc_chunk(struct btrfs_space_info *sinfo, u64 alloc_bytes) | 3230 | static 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 | } |