diff options
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/extent-tree.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 1cae6631b3d8..ef4ce2c026d6 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3673,6 +3673,11 @@ static void force_metadata_allocation(struct btrfs_fs_info *info) | |||
3673 | rcu_read_unlock(); | 3673 | rcu_read_unlock(); |
3674 | } | 3674 | } |
3675 | 3675 | ||
3676 | static inline u64 calc_global_rsv_need_space(struct btrfs_block_rsv *global) | ||
3677 | { | ||
3678 | return (global->size << 1); | ||
3679 | } | ||
3680 | |||
3676 | static int should_alloc_chunk(struct btrfs_root *root, | 3681 | static int should_alloc_chunk(struct btrfs_root *root, |
3677 | struct btrfs_space_info *sinfo, int force) | 3682 | struct btrfs_space_info *sinfo, int force) |
3678 | { | 3683 | { |
@@ -3690,7 +3695,7 @@ static int should_alloc_chunk(struct btrfs_root *root, | |||
3690 | * global_rsv, it doesn't change except when the transaction commits. | 3695 | * global_rsv, it doesn't change except when the transaction commits. |
3691 | */ | 3696 | */ |
3692 | if (sinfo->flags & BTRFS_BLOCK_GROUP_METADATA) | 3697 | if (sinfo->flags & BTRFS_BLOCK_GROUP_METADATA) |
3693 | num_allocated += global_rsv->size; | 3698 | num_allocated += calc_global_rsv_need_space(global_rsv); |
3694 | 3699 | ||
3695 | /* | 3700 | /* |
3696 | * in limited mode, we want to have some free space up to | 3701 | * in limited mode, we want to have some free space up to |
@@ -3862,7 +3867,7 @@ static int can_overcommit(struct btrfs_root *root, | |||
3862 | { | 3867 | { |
3863 | struct btrfs_block_rsv *global_rsv = &root->fs_info->global_block_rsv; | 3868 | struct btrfs_block_rsv *global_rsv = &root->fs_info->global_block_rsv; |
3864 | u64 profile = btrfs_get_alloc_profile(root, 0); | 3869 | u64 profile = btrfs_get_alloc_profile(root, 0); |
3865 | u64 rsv_size = 0; | 3870 | u64 space_size; |
3866 | u64 avail; | 3871 | u64 avail; |
3867 | u64 used; | 3872 | u64 used; |
3868 | u64 to_add; | 3873 | u64 to_add; |
@@ -3870,18 +3875,16 @@ static int can_overcommit(struct btrfs_root *root, | |||
3870 | used = space_info->bytes_used + space_info->bytes_reserved + | 3875 | used = space_info->bytes_used + space_info->bytes_reserved + |
3871 | space_info->bytes_pinned + space_info->bytes_readonly; | 3876 | space_info->bytes_pinned + space_info->bytes_readonly; |
3872 | 3877 | ||
3873 | spin_lock(&global_rsv->lock); | ||
3874 | rsv_size = global_rsv->size; | ||
3875 | spin_unlock(&global_rsv->lock); | ||
3876 | |||
3877 | /* | 3878 | /* |
3878 | * We only want to allow over committing if we have lots of actual space | 3879 | * We only want to allow over committing if we have lots of actual space |
3879 | * free, but if we don't have enough space to handle the global reserve | 3880 | * free, but if we don't have enough space to handle the global reserve |
3880 | * space then we could end up having a real enospc problem when trying | 3881 | * space then we could end up having a real enospc problem when trying |
3881 | * to allocate a chunk or some other such important allocation. | 3882 | * to allocate a chunk or some other such important allocation. |
3882 | */ | 3883 | */ |
3883 | rsv_size <<= 1; | 3884 | spin_lock(&global_rsv->lock); |
3884 | if (used + rsv_size >= space_info->total_bytes) | 3885 | space_size = calc_global_rsv_need_space(global_rsv); |
3886 | spin_unlock(&global_rsv->lock); | ||
3887 | if (used + space_size >= space_info->total_bytes) | ||
3885 | return 0; | 3888 | return 0; |
3886 | 3889 | ||
3887 | used += space_info->bytes_may_use; | 3890 | used += space_info->bytes_may_use; |