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 ---