free-space-cache.c (1f422417945d08731e2915e0addb976f11b3a85a) | free-space-cache.c (6b7304af62d02d77d740defd4cfddf2ef3188067) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2008 Red Hat. All rights reserved. 4 */ 5 6#include <linux/pagemap.h> 7#include <linux/sched.h> 8#include <linux/sched/signal.h> --- 3748 unchanged lines hidden (view full) --- 3757 3758 if (offset >= end) 3759 block_group->discard_cursor = end; 3760 3761out: 3762 return ret; 3763} 3764 | 1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2008 Red Hat. All rights reserved. 4 */ 5 6#include <linux/pagemap.h> 7#include <linux/sched.h> 8#include <linux/sched/signal.h> --- 3748 unchanged lines hidden (view full) --- 3757 3758 if (offset >= end) 3759 block_group->discard_cursor = end; 3760 3761out: 3762 return ret; 3763} 3764 |
3765void btrfs_get_block_group_trimming(struct btrfs_block_group *cache) | 3765void btrfs_freeze_block_group(struct btrfs_block_group *cache) |
3766{ | 3766{ |
3767 atomic_inc(&cache->trimming); | 3767 atomic_inc(&cache->frozen); |
3768} 3769 | 3768} 3769 |
3770void btrfs_put_block_group_trimming(struct btrfs_block_group *block_group) | 3770void btrfs_unfreeze_block_group(struct btrfs_block_group *block_group) |
3771{ 3772 struct btrfs_fs_info *fs_info = block_group->fs_info; 3773 struct extent_map_tree *em_tree; 3774 struct extent_map *em; 3775 bool cleanup; 3776 3777 spin_lock(&block_group->lock); | 3771{ 3772 struct btrfs_fs_info *fs_info = block_group->fs_info; 3773 struct extent_map_tree *em_tree; 3774 struct extent_map *em; 3775 bool cleanup; 3776 3777 spin_lock(&block_group->lock); |
3778 cleanup = (atomic_dec_and_test(&block_group->trimming) && | 3778 cleanup = (atomic_dec_and_test(&block_group->frozen) && |
3779 block_group->removed); 3780 spin_unlock(&block_group->lock); 3781 3782 if (cleanup) { 3783 mutex_lock(&fs_info->chunk_mutex); 3784 em_tree = &fs_info->mapping_tree; 3785 write_lock(&em_tree->lock); 3786 em = lookup_extent_mapping(em_tree, block_group->start, 3787 1); 3788 BUG_ON(!em); /* logic error, can't happen */ 3789 remove_extent_mapping(em_tree, em); 3790 write_unlock(&em_tree->lock); 3791 mutex_unlock(&fs_info->chunk_mutex); 3792 3793 /* once for us and once for the tree */ 3794 free_extent_map(em); 3795 free_extent_map(em); 3796 3797 /* | 3779 block_group->removed); 3780 spin_unlock(&block_group->lock); 3781 3782 if (cleanup) { 3783 mutex_lock(&fs_info->chunk_mutex); 3784 em_tree = &fs_info->mapping_tree; 3785 write_lock(&em_tree->lock); 3786 em = lookup_extent_mapping(em_tree, block_group->start, 3787 1); 3788 BUG_ON(!em); /* logic error, can't happen */ 3789 remove_extent_mapping(em_tree, em); 3790 write_unlock(&em_tree->lock); 3791 mutex_unlock(&fs_info->chunk_mutex); 3792 3793 /* once for us and once for the tree */ 3794 free_extent_map(em); 3795 free_extent_map(em); 3796 3797 /* |
3798 * We've left one free space entry and other tasks trimming 3799 * this block group have left 1 entry each one. Free them. | 3798 * We may have left one free space entry and other possible 3799 * tasks trimming this block group have left 1 entry each one. 3800 * Free them if any. |
3800 */ 3801 __btrfs_remove_free_space_cache(block_group->free_space_ctl); 3802 } 3803} 3804 3805int btrfs_trim_block_group(struct btrfs_block_group *block_group, 3806 u64 *trimmed, u64 start, u64 end, u64 minlen) 3807{ 3808 struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 3809 int ret; 3810 u64 rem = 0; 3811 3812 *trimmed = 0; 3813 3814 spin_lock(&block_group->lock); 3815 if (block_group->removed) { 3816 spin_unlock(&block_group->lock); 3817 return 0; 3818 } | 3801 */ 3802 __btrfs_remove_free_space_cache(block_group->free_space_ctl); 3803 } 3804} 3805 3806int btrfs_trim_block_group(struct btrfs_block_group *block_group, 3807 u64 *trimmed, u64 start, u64 end, u64 minlen) 3808{ 3809 struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 3810 int ret; 3811 u64 rem = 0; 3812 3813 *trimmed = 0; 3814 3815 spin_lock(&block_group->lock); 3816 if (block_group->removed) { 3817 spin_unlock(&block_group->lock); 3818 return 0; 3819 } |
3819 btrfs_get_block_group_trimming(block_group); | 3820 btrfs_freeze_block_group(block_group); |
3820 spin_unlock(&block_group->lock); 3821 3822 ret = trim_no_bitmap(block_group, trimmed, start, end, minlen, false); 3823 if (ret) 3824 goto out; 3825 3826 ret = trim_bitmaps(block_group, trimmed, start, end, minlen, 0, false); 3827 div64_u64_rem(end, BITS_PER_BITMAP * ctl->unit, &rem); 3828 /* If we ended in the middle of a bitmap, reset the trimming flag */ 3829 if (rem) 3830 reset_trimming_bitmap(ctl, offset_to_bitmap(ctl, end)); 3831out: | 3821 spin_unlock(&block_group->lock); 3822 3823 ret = trim_no_bitmap(block_group, trimmed, start, end, minlen, false); 3824 if (ret) 3825 goto out; 3826 3827 ret = trim_bitmaps(block_group, trimmed, start, end, minlen, 0, false); 3828 div64_u64_rem(end, BITS_PER_BITMAP * ctl->unit, &rem); 3829 /* If we ended in the middle of a bitmap, reset the trimming flag */ 3830 if (rem) 3831 reset_trimming_bitmap(ctl, offset_to_bitmap(ctl, end)); 3832out: |
3832 btrfs_put_block_group_trimming(block_group); | 3833 btrfs_unfreeze_block_group(block_group); |
3833 return ret; 3834} 3835 3836int btrfs_trim_block_group_extents(struct btrfs_block_group *block_group, 3837 u64 *trimmed, u64 start, u64 end, u64 minlen, 3838 bool async) 3839{ 3840 int ret; 3841 3842 *trimmed = 0; 3843 3844 spin_lock(&block_group->lock); 3845 if (block_group->removed) { 3846 spin_unlock(&block_group->lock); 3847 return 0; 3848 } | 3834 return ret; 3835} 3836 3837int btrfs_trim_block_group_extents(struct btrfs_block_group *block_group, 3838 u64 *trimmed, u64 start, u64 end, u64 minlen, 3839 bool async) 3840{ 3841 int ret; 3842 3843 *trimmed = 0; 3844 3845 spin_lock(&block_group->lock); 3846 if (block_group->removed) { 3847 spin_unlock(&block_group->lock); 3848 return 0; 3849 } |
3849 btrfs_get_block_group_trimming(block_group); | 3850 btrfs_freeze_block_group(block_group); |
3850 spin_unlock(&block_group->lock); 3851 3852 ret = trim_no_bitmap(block_group, trimmed, start, end, minlen, async); | 3851 spin_unlock(&block_group->lock); 3852 3853 ret = trim_no_bitmap(block_group, trimmed, start, end, minlen, async); |
3853 btrfs_put_block_group_trimming(block_group); | 3854 btrfs_unfreeze_block_group(block_group); |
3854 3855 return ret; 3856} 3857 3858int btrfs_trim_block_group_bitmaps(struct btrfs_block_group *block_group, 3859 u64 *trimmed, u64 start, u64 end, u64 minlen, 3860 u64 maxlen, bool async) 3861{ 3862 int ret; 3863 3864 *trimmed = 0; 3865 3866 spin_lock(&block_group->lock); 3867 if (block_group->removed) { 3868 spin_unlock(&block_group->lock); 3869 return 0; 3870 } | 3855 3856 return ret; 3857} 3858 3859int btrfs_trim_block_group_bitmaps(struct btrfs_block_group *block_group, 3860 u64 *trimmed, u64 start, u64 end, u64 minlen, 3861 u64 maxlen, bool async) 3862{ 3863 int ret; 3864 3865 *trimmed = 0; 3866 3867 spin_lock(&block_group->lock); 3868 if (block_group->removed) { 3869 spin_unlock(&block_group->lock); 3870 return 0; 3871 } |
3871 btrfs_get_block_group_trimming(block_group); | 3872 btrfs_freeze_block_group(block_group); |
3872 spin_unlock(&block_group->lock); 3873 3874 ret = trim_bitmaps(block_group, trimmed, start, end, minlen, maxlen, 3875 async); 3876 | 3873 spin_unlock(&block_group->lock); 3874 3875 ret = trim_bitmaps(block_group, trimmed, start, end, minlen, maxlen, 3876 async); 3877 |
3877 btrfs_put_block_group_trimming(block_group); | 3878 btrfs_unfreeze_block_group(block_group); |
3878 3879 return ret; 3880} 3881 3882/* 3883 * Find the left-most item in the cache tree, and then return the 3884 * smallest inode number in the item. 3885 * --- 319 unchanged lines hidden --- | 3879 3880 return ret; 3881} 3882 3883/* 3884 * Find the left-most item in the cache tree, and then return the 3885 * smallest inode number in the item. 3886 * --- 319 unchanged lines hidden --- |