diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 71 |
1 files changed, 42 insertions, 29 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 06369d588f27..a8de1c30f21c 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3663,6 +3663,46 @@ out: | |||
3663 | return ret; | 3663 | return ret; |
3664 | } | 3664 | } |
3665 | 3665 | ||
3666 | static int can_overcommit(struct btrfs_root *root, | ||
3667 | struct btrfs_space_info *space_info, u64 bytes, | ||
3668 | int flush) | ||
3669 | { | ||
3670 | u64 profile = btrfs_get_alloc_profile(root, 0); | ||
3671 | u64 avail; | ||
3672 | u64 used; | ||
3673 | |||
3674 | used = space_info->bytes_used + space_info->bytes_reserved + | ||
3675 | space_info->bytes_pinned + space_info->bytes_readonly + | ||
3676 | space_info->bytes_may_use; | ||
3677 | |||
3678 | spin_lock(&root->fs_info->free_chunk_lock); | ||
3679 | avail = root->fs_info->free_chunk_space; | ||
3680 | spin_unlock(&root->fs_info->free_chunk_lock); | ||
3681 | |||
3682 | /* | ||
3683 | * If we have dup, raid1 or raid10 then only half of the free | ||
3684 | * space is actually useable. | ||
3685 | */ | ||
3686 | if (profile & (BTRFS_BLOCK_GROUP_DUP | | ||
3687 | BTRFS_BLOCK_GROUP_RAID1 | | ||
3688 | BTRFS_BLOCK_GROUP_RAID10)) | ||
3689 | avail >>= 1; | ||
3690 | |||
3691 | /* | ||
3692 | * If we aren't flushing don't let us overcommit too much, say | ||
3693 | * 1/8th of the space. If we can flush, let it overcommit up to | ||
3694 | * 1/2 of the space. | ||
3695 | */ | ||
3696 | if (flush) | ||
3697 | avail >>= 3; | ||
3698 | else | ||
3699 | avail >>= 1; | ||
3700 | |||
3701 | if (used + bytes < space_info->total_bytes + avail) | ||
3702 | return 1; | ||
3703 | return 0; | ||
3704 | } | ||
3705 | |||
3666 | /* | 3706 | /* |
3667 | * shrink metadata reservation for delalloc | 3707 | * shrink metadata reservation for delalloc |
3668 | */ | 3708 | */ |
@@ -3705,10 +3745,7 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig, | |||
3705 | !atomic_read(&root->fs_info->async_delalloc_pages)); | 3745 | !atomic_read(&root->fs_info->async_delalloc_pages)); |
3706 | 3746 | ||
3707 | spin_lock(&space_info->lock); | 3747 | spin_lock(&space_info->lock); |
3708 | if (space_info->bytes_used + space_info->bytes_reserved + | 3748 | if (can_overcommit(root, space_info, orig, !trans)) { |
3709 | space_info->bytes_pinned + space_info->bytes_readonly + | ||
3710 | space_info->bytes_may_use + orig <= | ||
3711 | space_info->total_bytes) { | ||
3712 | spin_unlock(&space_info->lock); | 3749 | spin_unlock(&space_info->lock); |
3713 | break; | 3750 | break; |
3714 | } | 3751 | } |
@@ -3924,7 +3961,6 @@ again: | |||
3924 | } | 3961 | } |
3925 | 3962 | ||
3926 | if (ret) { | 3963 | if (ret) { |
3927 | u64 profile = btrfs_get_alloc_profile(root, 0); | ||
3928 | u64 avail; | 3964 | u64 avail; |
3929 | 3965 | ||
3930 | /* | 3966 | /* |
@@ -3945,30 +3981,7 @@ again: | |||
3945 | goto again; | 3981 | goto again; |
3946 | } | 3982 | } |
3947 | 3983 | ||
3948 | spin_lock(&root->fs_info->free_chunk_lock); | 3984 | if (can_overcommit(root, space_info, orig_bytes, flush)) { |
3949 | avail = root->fs_info->free_chunk_space; | ||
3950 | |||
3951 | /* | ||
3952 | * If we have dup, raid1 or raid10 then only half of the free | ||
3953 | * space is actually useable. | ||
3954 | */ | ||
3955 | if (profile & (BTRFS_BLOCK_GROUP_DUP | | ||
3956 | BTRFS_BLOCK_GROUP_RAID1 | | ||
3957 | BTRFS_BLOCK_GROUP_RAID10)) | ||
3958 | avail >>= 1; | ||
3959 | |||
3960 | /* | ||
3961 | * If we aren't flushing don't let us overcommit too much, say | ||
3962 | * 1/8th of the space. If we can flush, let it overcommit up to | ||
3963 | * 1/2 of the space. | ||
3964 | */ | ||
3965 | if (flush) | ||
3966 | avail >>= 3; | ||
3967 | else | ||
3968 | avail >>= 1; | ||
3969 | spin_unlock(&root->fs_info->free_chunk_lock); | ||
3970 | |||
3971 | if (used + num_bytes < space_info->total_bytes + avail) { | ||
3972 | space_info->bytes_may_use += orig_bytes; | 3985 | space_info->bytes_may_use += orig_bytes; |
3973 | trace_btrfs_space_reservation(root->fs_info, | 3986 | trace_btrfs_space_reservation(root->fs_info, |
3974 | "space_info", space_info->flags, orig_bytes, 1); | 3987 | "space_info", space_info->flags, orig_bytes, 1); |