btrfs: block group cleanups
cover btrfs: block group cleanups
I'm reworking our relocation and delete unused block group workqueues which require some cleanups of how we deal with flags on the block group. We've had a bit field for various flags on the block group for a while, but there's a subtle gotcha with this bitfield in that you have to protect every modification with bg->lock in order to not mess with the values, and there were a few places that we weren't holding the lock.
Rework these to be normal flags, and then go behind this conversion and cleanup some of the usage of the different flags. Additionally there's a cleanup around when to break out of the background workers. Thanks,
Josef
Josef Bacik (5):
btrfs: use btrfs_fs_closing for background bg work
btrfs: convert block group bit field to use bit helpers
btrfs: remove block_group->lock protection for TO_COPY
btrfs: simplify btrfs_put_block_group_cache
btrfs: remove BLOCK_GROUP_FLAG_HAS_CACHING_CTL
fs/btrfs/block-group.c | 95 ++++++++++++++++--------------------- fs/btrfs/block-group.h | 19 ++++---- fs/btrfs/dev-replace.c | 11 ++--- fs/btrfs/extent-tree.c | 7 ++- fs/btrfs/free-space-cache.c | 18 +++---- fs/btrfs/scrub.c | 16 +++---- fs/btrfs/volumes.c | 13 +++-- fs/btrfs/zoned.c | 30 ++++++++---- 8 files changed, 103 insertions(+), 106 deletions(-)
Signature · 1 line
2.26.3
PATCH 1/5 btrfs: use btrfs_fs_closing for background bg work
For both the deletion of unused block groups and the async balance work we'll only skip running if we don't have BTRFS_FS_OPEN set, however during teardown we park the cleaner kthread and cancel the reclaim work right away, effectively stopping the work from running.
Fix the condition to bail if btrfs_fs_closing() is true instead of if !BTRFS_FS_OPEN, which is cleared much further in the process.
--- fs/btrfs/block-group.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/btrfs/block-group.c +2 -2
@@ -1318,7 +1318,7 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)const bool async_trim_enabled =btrfs_test_opt (fs_info,DISCARD_ASYNC );int ret =0 ; -if (!test_bit (BTRFS_FS_OPEN , &fs_info->flags)) +if (btrfs_fs_closing (fs_info))return ;/*
@@ -1557,7 +1557,7 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)struct btrfs_block_group *bg;struct btrfs_space_info *space_info; -if (!test_bit (BTRFS_FS_OPEN , &fs_info->flags)) +if (btrfs_fs_closing (fs_info))return ;if (!btrfs_should_reclaim (fs_info))
Signature · 1 line
2.26.3
PATCH 2/5 btrfs: convert block group bit field to use bit helpers
In reply to Josef BacikWe use a bit field in the btrfs_block_group for different flags, however this is awkward because we have to hold the block_group->lock for any modification of any of these fields, and makes the code clunky for a few of these flags. Convert these to a properly flags setup so we can utilize the bit helpers.
--- fs/btrfs/block-group.c | 21 +++++++++++++-------- fs/btrfs/block-group.h | 20 ++++++++++++-------- fs/btrfs/dev-replace.c | 6 +++--- fs/btrfs/extent-tree.c | 7 +++++-- fs/btrfs/free-space-cache.c | 18 +++++++++--------- fs/btrfs/scrub.c | 13 +++++++------ fs/btrfs/volumes.c | 11 ++++++----- fs/btrfs/zoned.c | 30 ++++++++++++++++++++---------- 8 files changed, 75 insertions(+), 51 deletions(-)
fs/btrfs/block-group.c +13 -8
@@ -789,7 +789,7 @@ int btrfs_cache_block_group(struct btrfs_block_group *cache, int load_cache_only cache->cached =BTRFS_CACHE_FAST ; else cache->cached = BTRFS_CACHE_STARTED; - cache->has_caching_ctl =1 ; +set_bit (BLOCK_GROUP_FLAG_HAS_CACHING_CTL , &cache->runtime_flags);spin_unlock (&cache->lock);write_lock (&fs_info->block_group_cache_lock);
@@ -1005,11 +1005,13 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,kobject_put (kobj); } -if (block_group->has_caching_ctl) +if (test_bit (BLOCK_GROUP_FLAG_HAS_CACHING_CTL , + &block_group->runtime_flags)) caching_ctl =btrfs_get_caching_control (block_group);if (block_group->cached ==BTRFS_CACHE_STARTED )btrfs_wait_block_group_cache_done (block_group); -if (block_group->has_caching_ctl) { +if (test_bit (BLOCK_GROUP_FLAG_HAS_CACHING_CTL , + &block_group->runtime_flags)) {write_lock (&fs_info->block_group_cache_lock);if (!caching_ctl) {struct btrfs_caching_control *ctl;
@@ -1086,7 +1088,8 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, goto out;spin_lock (&block_group->lock); - block_group->removed =1 ; +set_bit (BLOCK_GROUP_FLAG_REMOVED , &block_group->runtime_flags); +/* * At this point trimming or scrub can't start on this block group, * because we removed the block group from the rbtree
@@ -2440,7 +2443,8 @@ void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans) ret =insert_block_group_item (trans, block_group);if (ret)btrfs_abort_transaction (trans, ret); -if (!block_group->chunk_item_inserted) { +if (!test_bit (BLOCK_GROUP_FLAG_CHUNK_ITEM_INSERTED , + &block_group->runtime_flags)) {mutex_lock (&fs_info->chunk_mutex); ret =btrfs_chunk_alloc_add_chunk_item (trans, block_group);mutex_unlock (&fs_info->chunk_mutex);
@@ -3989,7 +3993,8 @@ void btrfs_put_block_group_cache(struct btrfs_fs_info *info)while (block_group) {btrfs_wait_block_group_cache_done (block_group);spin_lock (&block_group->lock); -if (block_group->iref) +if (test_bit (BLOCK_GROUP_FLAG_IREF , + &block_group->runtime_flags))break ;spin_unlock (&block_group->lock); block_group =btrfs_next_block_group (block_group);
@@ -4002,7 +4007,7 @@ void btrfs_put_block_group_cache(struct btrfs_fs_info *info) } inode = block_group->inode; - block_group->iref =0 ; +clear_bit (BLOCK_GROUP_FLAG_IREF , &block_group->runtime_flags); block_group->inode =NULL ;spin_unlock (&block_group->lock);ASSERT (block_group->io_ctl.inode ==NULL );
@@ -4144,7 +4149,7 @@ void btrfs_unfreeze_block_group(struct btrfs_block_group *block_group)spin_lock (&block_group->lock); cleanup = (atomic_dec_and_test (&block_group->frozen) && - block_group->removed); +test_bit (BLOCK_GROUP_FLAG_REMOVED , &block_group->runtime_flags));spin_unlock (&block_group->lock);if (cleanup) {
fs/btrfs/block-group.h +12 -8
@@ -46,6 +46,17 @@ enum btrfs_chunk_alloc_enum { CHUNK_ALLOC_FORCE_FOR_EXTENT, }; +enum btrfs_block_group_flags { +BLOCK_GROUP_FLAG_IREF , +BLOCK_GROUP_FLAG_HAS_CACHING_CTL , +BLOCK_GROUP_FLAG_REMOVED , +BLOCK_GROUP_FLAG_TO_COPY , +BLOCK_GROUP_FLAG_RELOCATING_REPAIR , +BLOCK_GROUP_FLAG_CHUNK_ITEM_INSERTED , +BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE , +BLOCK_GROUP_FLAG_ZONED_DATA_RELOC , +}; +struct btrfs_caching_control {struct list_head list;struct mutex mutex;
@@ -95,16 +106,9 @@ struct btrfs_block_group {/* For raid56, this is a full stripe, without parity */ unsigned long full_stripe_len; +unsigned long runtime_flags;unsigned int ro; - unsigned int iref:1; - unsigned int has_caching_ctl:1; - unsigned int removed:1; - unsigned int to_copy:1; - unsigned int relocating_repair:1; - unsigned int chunk_item_inserted:1; - unsigned int zone_is_active:1; - unsigned int zoned_data_reloc_ongoing:1;int disk_cache_state;
fs/btrfs/dev-replace.c +3 -3
@@ -546,7 +546,7 @@ static int mark_block_group_to_copy(struct btrfs_fs_info *fs_info,continue ;spin_lock (&cache->lock); - cache->to_copy =1 ; +set_bit (BLOCK_GROUP_FLAG_TO_COPY , &cache->runtime_flags);spin_unlock (&cache->lock);btrfs_put_block_group (cache);
@@ -577,7 +577,7 @@ bool btrfs_finish_block_group_to_copy(struct btrfs_device *srcdev,return true;spin_lock (&cache->lock); -if (cache->removed) { +if (test_bit (BLOCK_GROUP_FLAG_REMOVED , &cache->runtime_flags)) {spin_unlock (&cache->lock);return true; }
@@ -611,7 +611,7 @@ bool btrfs_finish_block_group_to_copy(struct btrfs_device *srcdev,/* Last stripe on this device */ spin_lock (&cache->lock); - cache->to_copy =0 ; +clear_bit (BLOCK_GROUP_FLAG_TO_COPY , &cache->runtime_flags);spin_unlock (&cache->lock);return true;
fs/btrfs/extent-tree.c +5 -2
@@ -3816,7 +3816,9 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group, block_group->start == fs_info->data_reloc_bg || fs_info->data_reloc_bg == 0); -if (block_group->ro || block_group->zoned_data_reloc_ongoing) { +if (block_group->ro || +test_bit (BLOCK_GROUP_FLAG_ZONED_DATA_RELOC , + &block_group->runtime_flags)) { ret =1 ; goto out; }
@@ -3893,7 +3895,8 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group,* regular extents) at the same time to the same zone, which * easily break the write pointer. */ - block_group->zoned_data_reloc_ongoing =1 ; +set_bit (BLOCK_GROUP_FLAG_ZONED_DATA_RELOC , + &block_group->runtime_flags); fs_info->data_reloc_bg =0 ; }spin_unlock (&fs_info->relocation_bg_lock);
fs/btrfs/free-space-cache.c +9 -9
@@ -126,10 +126,9 @@ struct inode *lookup_free_space_inode(struct btrfs_block_group *block_group, block_group->disk_cache_state =BTRFS_DC_CLEAR ; } -if (!block_group->iref) { +if (!test_and_set_bit (BLOCK_GROUP_FLAG_IREF , + &block_group->runtime_flags)) block_group->inode =igrab (inode); - block_group->iref =1 ; - }spin_unlock (&block_group->lock);return inode;
@@ -241,8 +240,8 @@ int btrfs_remove_free_space_inode(struct btrfs_trans_handle *trans,clear_nlink (inode);/* One for the block groups ref */ spin_lock (&block_group->lock); -if (block_group->iref) { - block_group->iref =0 ; +if (test_and_clear_bit (BLOCK_GROUP_FLAG_IREF , + &block_group->runtime_flags)) { block_group->inode =NULL ;spin_unlock (&block_group->lock);iput (inode);
@@ -2860,7 +2859,8 @@ void btrfs_dump_free_space(struct btrfs_block_group *block_group,if (btrfs_is_zoned (fs_info)) {btrfs_info (fs_info,"free space %llu active %d" , block_group->zone_capacity - block_group->alloc_offset, - block_group->zone_is_active); +test_bit (BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE , + &block_group->runtime_flags));return ; }
@@ -3992,7 +3992,7 @@ int btrfs_trim_block_group(struct btrfs_block_group *block_group, *trimmed =0 ;spin_lock (&block_group->lock); -if (block_group->removed) { +if (test_bit (BLOCK_GROUP_FLAG_REMOVED , &block_group->runtime_flags)) {spin_unlock (&block_group->lock);return 0 ; }
@@ -4022,7 +4022,7 @@ int btrfs_trim_block_group_extents(struct btrfs_block_group *block_group, *trimmed =0 ;spin_lock (&block_group->lock); -if (block_group->removed) { +if (test_bit (BLOCK_GROUP_FLAG_REMOVED , &block_group->runtime_flags)) {spin_unlock (&block_group->lock);return 0 ; }
@@ -4044,7 +4044,7 @@ int btrfs_trim_block_group_bitmaps(struct btrfs_block_group *block_group, *trimmed =0 ;spin_lock (&block_group->lock); -if (block_group->removed) { +if (test_bit (BLOCK_GROUP_FLAG_REMOVED , &block_group->runtime_flags)) {spin_unlock (&block_group->lock);return 0 ; }
fs/btrfs/scrub.c +7 -6
@@ -3266,7 +3266,7 @@ static int scrub_simple_mirror(struct scrub_ctx *sctx, }/* Block group removed? */ spin_lock (&bg->lock); -if (bg->removed) { +if (test_bit (BLOCK_GROUP_FLAG_REMOVED , &bg->runtime_flags)) {spin_unlock (&bg->lock); ret =0 ;break ;
@@ -3606,7 +3606,7 @@ static noinline_for_stack int scrub_chunk(struct scrub_ctx *sctx,* kthread or relocation. */ spin_lock (&bg->lock); -if (!bg->removed) +if (!test_bit (BLOCK_GROUP_FLAG_REMOVED , &bg->runtime_flags)) ret = -EINVAL ;spin_unlock (&bg->lock);
@@ -3765,7 +3765,8 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,if (sctx->is_dev_replace &&btrfs_is_zoned (fs_info)) {spin_lock (&cache->lock); -if (!cache->to_copy) { +if (!test_bit (BLOCK_GROUP_FLAG_TO_COPY , + &cache->runtime_flags)) {spin_unlock (&cache->lock);btrfs_put_block_group (cache); goto skip;
@@ -3782,7 +3783,7 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,* repair extents. */ spin_lock (&cache->lock); -if (cache->removed) { +if (test_bit (BLOCK_GROUP_FLAG_REMOVED , &cache->runtime_flags)) {spin_unlock (&cache->lock);btrfs_put_block_group (cache); goto skip;
@@ -3942,8 +3943,8 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,* balance is triggered or it becomes used and unused again. */ spin_lock (&cache->lock); -if (!cache->removed && !cache->ro && cache->reserved ==0 && - cache->used ==0 ) { +if (!test_bit (BLOCK_GROUP_FLAG_REMOVED , &cache->runtime_flags) && + !cache->ro && cache->reserved ==0 && cache->used ==0 ) {spin_unlock (&cache->lock);if (btrfs_test_opt (fs_info,DISCARD_ASYNC )) btrfs_discard_queue_work(&fs_info->discard_ctl,
fs/btrfs/volumes.c +6 -5
@@ -5590,7 +5590,7 @@ int btrfs_chunk_alloc_add_chunk_item(struct btrfs_trans_handle *trans,if (ret) goto out; - bg->chunk_item_inserted =1 ; +set_bit (BLOCK_GROUP_FLAG_CHUNK_ITEM_INSERTED , &bg->runtime_flags);if (map->type &BTRFS_BLOCK_GROUP_SYSTEM ) { ret =btrfs_add_system_chunk (fs_info, &key, chunk, item_size);
@@ -6149,7 +6149,7 @@ static bool is_block_group_to_copy(struct btrfs_fs_info *fs_info, u64 logical) cache =btrfs_lookup_block_group (fs_info, logical);spin_lock (&cache->lock); - ret = cache->to_copy; + ret =test_bit (BLOCK_GROUP_FLAG_TO_COPY , &cache->runtime_flags);spin_unlock (&cache->lock);btrfs_put_block_group (cache);
@@ -8243,7 +8243,8 @@ static int relocating_repair_kthread(void *data)if (!cache) goto out; -if (!cache->relocating_repair) +if (!test_bit (BLOCK_GROUP_FLAG_RELOCATING_REPAIR , + &cache->runtime_flags)) goto out; ret =btrfs_may_alloc_data_chunk (fs_info, target);
@@ -8281,12 +8282,12 @@ bool btrfs_repair_one_zone(struct btrfs_fs_info *fs_info, u64 logical)return true;spin_lock (&cache->lock); -if (cache->relocating_repair) { +if (test_and_set_bit (BLOCK_GROUP_FLAG_RELOCATING_REPAIR , + &cache->runtime_flags)) {spin_unlock (&cache->lock);btrfs_put_block_group (cache);return true; } - cache->relocating_repair =1 ;spin_unlock (&cache->lock); kthread_run(relocating_repair_kthread, cache,
fs/btrfs/zoned.c +20 -10
@@ -1442,7 +1442,9 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new) } cache->alloc_offset = alloc_offsets[0 ]; cache->zone_capacity = caps[0 ]; - cache->zone_is_active =test_bit (0 , active); +if (test_bit (0 , active)) +set_bit (BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE , + &cache->runtime_flags);break ;case BTRFS_BLOCK_GROUP_DUP :if (map->type &BTRFS_BLOCK_GROUP_DATA ) {
@@ -1476,7 +1478,9 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new) goto out; } }else { - cache->zone_is_active =test_bit (0 , active); +if (test_bit (0 , active)) +set_bit (BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE , + &cache->runtime_flags); } cache->alloc_offset = alloc_offsets[0 ]; cache->zone_capacity =min (caps[0 ], caps[1 ]);
@@ -1494,7 +1498,7 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new) goto out; } -if (cache->zone_is_active) { +if (test_bit (BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE , &cache->runtime_flags)) {btrfs_get_block_group (cache);spin_lock (&fs_info->zone_active_bgs_lock);list_add_tail (&cache->active_bg_list, &fs_info->zone_active_bgs);
@@ -1862,7 +1866,8 @@ bool btrfs_zone_activate(struct btrfs_block_group *block_group)spin_lock (&space_info->lock);spin_lock (&block_group->lock); -if (block_group->zone_is_active) { +if (test_bit (BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE , + &block_group->runtime_flags)) { ret = true; goto out_unlock; }
@@ -1888,7 +1893,7 @@ bool btrfs_zone_activate(struct btrfs_block_group *block_group) }/* Successfully activated all the zones */ - block_group->zone_is_active =1 ; +set_bit (BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE , &block_group->runtime_flags); space_info->active_total_bytes += block_group->length;spin_unlock (&block_group->lock);btrfs_try_granting_tickets (fs_info, space_info);
@@ -1917,7 +1922,8 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writint i;spin_lock (&block_group->lock); -if (!block_group->zone_is_active) { +if (!test_bit (BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE , + &block_group->runtime_flags)) {spin_unlock (&block_group->lock);return 0 ; }
@@ -1956,7 +1962,8 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writ* Bail out if someone already deactivated the block group, or * allocated space is left in the block group. */ -if (!block_group->zone_is_active) { +if (!test_bit (BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE , + &block_group->runtime_flags)) {spin_unlock (&block_group->lock);btrfs_dec_block_group_ro (block_group);return 0 ;
@@ -1969,7 +1976,8 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writ } } - block_group->zone_is_active =0 ; +clear_bit (BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE , &block_group->runtime_flags); + block_group->alloc_offset = block_group->zone_capacity; block_group->free_space_ctl->free_space =0 ;btrfs_clear_treelog_bg (block_group);
@@ -2178,13 +2186,15 @@ void btrfs_zoned_release_data_reloc_bg(struct btrfs_fs_info *fs_info, u64 logicaASSERT (block_group && (block_group->flags &BTRFS_BLOCK_GROUP_DATA ));spin_lock (&block_group->lock); -if (!block_group->zoned_data_reloc_ongoing) +if (!test_bit (BLOCK_GROUP_FLAG_ZONED_DATA_RELOC , + &block_group->runtime_flags)) goto out;/* All relocation extents are written. */ if (block_group->start + block_group->alloc_offset == logical + length) {/* Now, release this block group for further allocations. */ - block_group->zoned_data_reloc_ongoing =0 ; +clear_bit (BLOCK_GROUP_FLAG_ZONED_DATA_RELOC , + &block_group->runtime_flags); } out:
Signature · 1 line
2.26.3
PATCH 3/5 btrfs: remove block_group->lock protection for TO_COPY
In reply to Josef BacikWe use this during device replace for zoned devices, we were simply taking the lock because it was in a bit field and we needed the lock to be safe with other modifications in the bitfield. With the bit helpers we no longer require that locking.
--- fs/btrfs/dev-replace.c | 5 ----- fs/btrfs/scrub.c | 3 --- fs/btrfs/volumes.c | 2 -- 3 files changed, 10 deletions(-)
fs/btrfs/dev-replace.c +0 -5
@@ -545,10 +545,7 @@ static int mark_block_group_to_copy(struct btrfs_fs_info *fs_info,if (!cache)continue ; -spin_lock (&cache->lock);set_bit (BLOCK_GROUP_FLAG_TO_COPY , &cache->runtime_flags); -spin_unlock (&cache->lock); -btrfs_put_block_group (cache); }if (iter_ret <0 )
@@ -610,9 +607,7 @@ bool btrfs_finish_block_group_to_copy(struct btrfs_device *srcdev, }/* Last stripe on this device */ -spin_lock (&cache->lock);clear_bit (BLOCK_GROUP_FLAG_TO_COPY , &cache->runtime_flags); -spin_unlock (&cache->lock);return true; }
fs/btrfs/scrub.c +0 -3
@@ -3764,14 +3764,11 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, }if (sctx->is_dev_replace &&btrfs_is_zoned (fs_info)) { -spin_lock (&cache->lock);if (!test_bit (BLOCK_GROUP_FLAG_TO_COPY , &cache->runtime_flags)) { -spin_unlock (&cache->lock);btrfs_put_block_group (cache); goto skip; } -spin_unlock (&cache->lock); }/*
fs/btrfs/volumes.c +0 -2
@@ -6148,9 +6148,7 @@ static bool is_block_group_to_copy(struct btrfs_fs_info *fs_info, u64 logical) cache =btrfs_lookup_block_group (fs_info, logical); -spin_lock (&cache->lock); ret =test_bit (BLOCK_GROUP_FLAG_TO_COPY , &cache->runtime_flags); -spin_unlock (&cache->lock);btrfs_put_block_group (cache);return ret;
Signature · 1 line
2.26.3
PATCH 4/5 btrfs: simplify btrfs_put_block_group_cache
In reply to Josef BacikWe're breaking out and re-searching for the next block group while evicting any of the block group cache inodes. This is not needed, the block groups aren't disappearing here, we can simply loop through the block groups like normal and iput any inode that we find.
--- fs/btrfs/block-group.c | 42 +++++++++++++++--------------------------- 1 file changed, 15 insertions(+), 27 deletions(-)
fs/btrfs/block-group.c +15 -27
@@ -3984,36 +3984,24 @@ void btrfs_reserve_chunk_metadata(struct btrfs_trans_handle *trans,void btrfs_put_block_group_cache (struct btrfs_fs_info *info) {struct btrfs_block_group *block_group; -u64 last =0 ; -while (1 ) { -struct inode *inode; - - block_group =btrfs_lookup_first_block_group (info, last); -while (block_group) { -btrfs_wait_block_group_cache_done (block_group); -spin_lock (&block_group->lock); -if (test_bit (BLOCK_GROUP_FLAG_IREF , - &block_group->runtime_flags)) -break ; + block_group =btrfs_lookup_first_block_group (info,0 ); +while (block_group) { +btrfs_wait_block_group_cache_done (block_group); +spin_lock (&block_group->lock); +if (test_and_clear_bit (BLOCK_GROUP_FLAG_IREF , + &block_group->runtime_flags)) { +struct inode *inode = block_group->inode; + + block_group->inode =NULL ;spin_unlock (&block_group->lock); - block_group =btrfs_next_block_group (block_group); - } -if (!block_group) { -if (last ==0 ) -break ; - last =0 ; -continue ; - } - inode = block_group->inode; -clear_bit (BLOCK_GROUP_FLAG_IREF , &block_group->runtime_flags); - block_group->inode =NULL ; -spin_unlock (&block_group->lock); -ASSERT (block_group->io_ctl.inode ==NULL ); -iput (inode); - last = block_group->start + block_group->length; -btrfs_put_block_group (block_group); +ASSERT (block_group->io_ctl.inode ==NULL ); +iput (inode); + }else { +spin_unlock (&block_group->lock); + } + block_group =btrfs_next_block_group (block_group); } }
Signature · 1 line
2.26.3
PATCH 5/5 btrfs: remove BLOCK_GROUP_FLAG_HAS_CACHING_CTL
In reply to Josef BacikThis is used mostly to determine if we need to look at the caching ctl list and clean up any references to this block group. However we never clear this flag, specifically because we need to know if we have to remove a caching ctl we have for this block group still. This is in the remove block group path which isn't a fast path, so the optimization doesn't really matter, simplify this logic and remove the flag.
--- fs/btrfs/block-group.c | 46 +++++++++++++++++++----------------------- fs/btrfs/block-group.h | 1 - 2 files changed, 21 insertions(+), 26 deletions(-)
fs/btrfs/block-group.c +21 -25
@@ -789,7 +789,6 @@ int btrfs_cache_block_group(struct btrfs_block_group *cache, int load_cache_only cache->cached =BTRFS_CACHE_FAST ; else cache->cached = BTRFS_CACHE_STARTED; -set_bit (BLOCK_GROUP_FLAG_HAS_CACHING_CTL , &cache->runtime_flags);spin_unlock (&cache->lock);write_lock (&fs_info->block_group_cache_lock);
@@ -1005,34 +1004,31 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,kobject_put (kobj); } -if (test_bit (BLOCK_GROUP_FLAG_HAS_CACHING_CTL , - &block_group->runtime_flags)) - caching_ctl =btrfs_get_caching_control (block_group);if (block_group->cached ==BTRFS_CACHE_STARTED )btrfs_wait_block_group_cache_done (block_group); -if (test_bit (BLOCK_GROUP_FLAG_HAS_CACHING_CTL , - &block_group->runtime_flags)) { -write_lock (&fs_info->block_group_cache_lock); -if (!caching_ctl) { -struct btrfs_caching_control *ctl; - -list_for_each_entry (ctl, - &fs_info->caching_block_groups, list) -if (ctl->block_group == block_group) { - caching_ctl = ctl; -refcount_inc (&caching_ctl->count); -break ; - } - } -if (caching_ctl) -list_del_init (&caching_ctl->list); -write_unlock (&fs_info->block_group_cache_lock); -if (caching_ctl) { -/* Once for the caching bgs list and once for us. */ -btrfs_put_caching_control (caching_ctl); -btrfs_put_caching_control (caching_ctl); + +write_lock (&fs_info->block_group_cache_lock); + caching_ctl =btrfs_get_caching_control (block_group); +if (!caching_ctl) { +struct btrfs_caching_control *ctl; + +list_for_each_entry (ctl, &fs_info->caching_block_groups, list) { +if (ctl->block_group == block_group) { + caching_ctl = ctl; +refcount_inc (&caching_ctl->count); +break ; + } } } +if (caching_ctl) +list_del_init (&caching_ctl->list); +write_unlock (&fs_info->block_group_cache_lock); + +if (caching_ctl) { +/* Once for the caching bgs list and once for us. */ +btrfs_put_caching_control (caching_ctl); +btrfs_put_caching_control (caching_ctl); + }spin_lock (&trans->transaction->dirty_bgs_lock);WARN_ON (!list_empty (&block_group->dirty_list));
fs/btrfs/block-group.h +0 -1
@@ -48,7 +48,6 @@ enum btrfs_chunk_alloc_enum {enum btrfs_block_group_flags {BLOCK_GROUP_FLAG_IREF , -BLOCK_GROUP_FLAG_HAS_CACHING_CTL ,BLOCK_GROUP_FLAG_REMOVED ,BLOCK_GROUP_FLAG_TO_COPY ,BLOCK_GROUP_FLAG_RELOCATING_REPAIR ,
Signature · 1 line
2.26.3
Re: [PATCH 1/5] btrfs: use btrfs_fs_closing for background bg work
In reply to Josef BacikLooks good,
Re: [PATCH 2/5] btrfs: convert block group bit field to use bit helpers
In reply to Josef BacikLooks good,
Re: [PATCH 3/5] btrfs: remove block_group->lock protection for TO_COPY
In reply to Josef BacikLooks good,
Re: [PATCH 4/5] btrfs: simplify btrfs_put_block_group_cache
In reply to Josef BacikLooks good,
kernel test robot
build botRe: [PATCH 2/5] btrfs: convert block group bit field to use bit helpers
In reply to Josef BacikI love your patch! Yet something to improve:
Hi Josef,
I love your patch! Yet something to improve:
[auto build test ERROR on kdave/for-next]
[also build test ERROR on next-20220714]
[cannot apply to linus/master v5.19-rc6]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Josef-Bacik/btrfs-block-group-cleanups/20220714-083606 base: https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-next config: hexagon-randconfig-r045-20220714 (https://download.01.org/0day-ci/archive/20220715/[email protected]/config) compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 5e61b9c556267086ef9b743a0b57df302eef831b)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/d82c8630686065ad13f9a0a3b73284f9aa3beb2d
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Josef-Bacik/btrfs-block-group-cleanups/20220714-083606
git checkout d82c8630686065ad13f9a0a3b73284f9aa3beb2d
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash fs/btrfs/
If you fix the issue, kindly add following tag where applicable
All errors (new ones prefixed by >>):
>> fs/btrfs/block-group.c:1056:24: error: no member named 'zone_is_active' in 'struct btrfs_block_group'
WARN_ON(block_group->zone_is_active &&
~~~~~~~~~~~ ^
include/asm-generic/bug.h:122:25: note: expanded from macro 'WARN_ON'
int __ret_warn_on = !!(condition); \
^~~~~~~~~
fs/btrfs/block-group.c:1061:19: error: no member named 'zone_is_active' in 'struct btrfs_block_group'
if (block_group->zone_is_active)
~~~~~~~~~~~ ^
fs/btrfs/block-group.c:2118:34: error: no member named 'zone_is_active' in 'struct btrfs_block_group'
cache->zone_unusable, cache->zone_is_active,
~~~~~ ^
fs/btrfs/block-group.c:2571:12: error: no member named 'zone_is_active' in 'struct btrfs_block_group'
cache->zone_is_active, &cache->space_info);
~~~~~ ^
4 errors generated.
--
>> fs/btrfs/zoned.c:2269:43: error: no member named 'zone_is_active' in 'struct btrfs_block_group'
if (btrfs_zoned_bg_is_full(bg) || bg->zone_is_active) {
~~ ^1 error generated.
vim +1056 fs/btrfs/block-group.c
7357623a7f4beb4 Qu Wenruo 2020-05-05 888
e3e0520b32bc3db Josef Bacik 2019-06-20 889 int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
e3e0520b32bc3db Josef Bacik 2019-06-20 890 u64 group_start, struct extent_map *em)
e3e0520b32bc3db Josef Bacik 2019-06-20 891 {
e3e0520b32bc3db Josef Bacik 2019-06-20 892 struct btrfs_fs_info *fs_info = trans->fs_info;
e3e0520b32bc3db Josef Bacik 2019-06-20 893 struct btrfs_path *path;
32da5386d9a4fd5 David Sterba 2019-10-29 894 struct btrfs_block_group *block_group;
e3e0520b32bc3db Josef Bacik 2019-06-20 895 struct btrfs_free_cluster *cluster;
e3e0520b32bc3db Josef Bacik 2019-06-20 896 struct inode *inode;
e3e0520b32bc3db Josef Bacik 2019-06-20 897 struct kobject *kobj = NULL;
e3e0520b32bc3db Josef Bacik 2019-06-20 898 int ret;
e3e0520b32bc3db Josef Bacik 2019-06-20 899 int index;
e3e0520b32bc3db Josef Bacik 2019-06-20 900 int factor;
e3e0520b32bc3db Josef Bacik 2019-06-20 901 struct btrfs_caching_control *caching_ctl = NULL;
e3e0520b32bc3db Josef Bacik 2019-06-20 902 bool remove_em;
e3e0520b32bc3db Josef Bacik 2019-06-20 903 bool remove_rsv = false;
e3e0520b32bc3db Josef Bacik 2019-06-20 904
e3e0520b32bc3db Josef Bacik 2019-06-20 905 block_group = btrfs_lookup_block_group(fs_info, group_start);
e3e0520b32bc3db Josef Bacik 2019-06-20 906 BUG_ON(!block_group);
e3e0520b32bc3db Josef Bacik 2019-06-20 907 BUG_ON(!block_group->ro);
e3e0520b32bc3db Josef Bacik 2019-06-20 908
e3e0520b32bc3db Josef Bacik 2019-06-20 909 trace_btrfs_remove_block_group(block_group);
e3e0520b32bc3db Josef Bacik 2019-06-20 910 /*
e3e0520b32bc3db Josef Bacik 2019-06-20 911 * Free the reserved super bytes from this block group before
e3e0520b32bc3db Josef Bacik 2019-06-20 912 * remove it.
e3e0520b32bc3db Josef Bacik 2019-06-20 913 */
e3e0520b32bc3db Josef Bacik 2019-06-20 914 btrfs_free_excluded_extents(block_group);
b3470b5dbe1300d David Sterba 2019-10-23 915 btrfs_free_ref_tree_range(fs_info, block_group->start,
b3470b5dbe1300d David Sterba 2019-10-23 916 block_group->length);
e3e0520b32bc3db Josef Bacik 2019-06-20 917
e3e0520b32bc3db Josef Bacik 2019-06-20 918 index = btrfs_bg_flags_to_raid_index(block_group->flags);
e3e0520b32bc3db Josef Bacik 2019-06-20 919 factor = btrfs_bg_type_to_factor(block_group->flags);
e3e0520b32bc3db Josef Bacik 2019-06-20 920
e3e0520b32bc3db Josef Bacik 2019-06-20 921 /* make sure this block group isn't part of an allocation cluster */
e3e0520b32bc3db Josef Bacik 2019-06-20 922 cluster = &fs_info->data_alloc_cluster;
e3e0520b32bc3db Josef Bacik 2019-06-20 923 spin_lock(&cluster->refill_lock);
e3e0520b32bc3db Josef Bacik 2019-06-20 924 btrfs_return_cluster_to_free_space(block_group, cluster);
e3e0520b32bc3db Josef Bacik 2019-06-20 925 spin_unlock(&cluster->refill_lock);
e3e0520b32bc3db Josef Bacik 2019-06-20 926
e3e0520b32bc3db Josef Bacik 2019-06-20 927 /*
e3e0520b32bc3db Josef Bacik 2019-06-20 928 * make sure this block group isn't part of a metadata
e3e0520b32bc3db Josef Bacik 2019-06-20 929 * allocation cluster
e3e0520b32bc3db Josef Bacik 2019-06-20 930 */
e3e0520b32bc3db Josef Bacik 2019-06-20 931 cluster = &fs_info->meta_alloc_cluster;
e3e0520b32bc3db Josef Bacik 2019-06-20 932 spin_lock(&cluster->refill_lock);
e3e0520b32bc3db Josef Bacik 2019-06-20 933 btrfs_return_cluster_to_free_space(block_group, cluster);
e3e0520b32bc3db Josef Bacik 2019-06-20 934 spin_unlock(&cluster->refill_lock);
e3e0520b32bc3db Josef Bacik 2019-06-20 935
40ab3be102f0a61 Naohiro Aota 2021-02-04 936 btrfs_clear_treelog_bg(block_group);
c2707a255623435 Johannes Thumshirn 2021-09-09 937 btrfs_clear_data_reloc_bg(block_group);
40ab3be102f0a61 Naohiro Aota 2021-02-04 938
e3e0520b32bc3db Josef Bacik 2019-06-20 939 path = btrfs_alloc_path();
e3e0520b32bc3db Josef Bacik 2019-06-20 940 if (!path) {
e3e0520b32bc3db Josef Bacik 2019-06-20 941 ret = -ENOMEM;
9fecd13202f520f Filipe Manana 2020-06-01 942 goto out;
e3e0520b32bc3db Josef Bacik 2019-06-20 943 }
e3e0520b32bc3db Josef Bacik 2019-06-20 944
e3e0520b32bc3db Josef Bacik 2019-06-20 945 /*
e3e0520b32bc3db Josef Bacik 2019-06-20 946 * get the inode first so any iput calls done for the io_list
e3e0520b32bc3db Josef Bacik 2019-06-20 947 * aren't the final iput (no unlinks allowed now)
e3e0520b32bc3db Josef Bacik 2019-06-20 948 */
e3e0520b32bc3db Josef Bacik 2019-06-20 949 inode = lookup_free_space_inode(block_group, path);
e3e0520b32bc3db Josef Bacik 2019-06-20 950
e3e0520b32bc3db Josef Bacik 2019-06-20 951 mutex_lock(&trans->transaction->cache_write_mutex);
e3e0520b32bc3db Josef Bacik 2019-06-20 952 /*
e3e0520b32bc3db Josef Bacik 2019-06-20 953 * Make sure our free space cache IO is done before removing the
e3e0520b32bc3db Josef Bacik 2019-06-20 954 * free space inode
e3e0520b32bc3db Josef Bacik 2019-06-20 955 */
e3e0520b32bc3db Josef Bacik 2019-06-20 956 spin_lock(&trans->transaction->dirty_bgs_lock);
e3e0520b32bc3db Josef Bacik 2019-06-20 957 if (!list_empty(&block_group->io_list)) {
e3e0520b32bc3db Josef Bacik 2019-06-20 958 list_del_init(&block_group->io_list);
e3e0520b32bc3db Josef Bacik 2019-06-20 959
e3e0520b32bc3db Josef Bacik 2019-06-20 960 WARN_ON(!IS_ERR(inode) && inode != block_group->io_ctl.inode);
e3e0520b32bc3db Josef Bacik 2019-06-20 961
e3e0520b32bc3db Josef Bacik 2019-06-20 962 spin_unlock(&trans->transaction->dirty_bgs_lock);
e3e0520b32bc3db Josef Bacik 2019-06-20 963 btrfs_wait_cache_io(trans, block_group, path);
e3e0520b32bc3db Josef Bacik 2019-06-20 964 btrfs_put_block_group(block_group);
e3e0520b32bc3db Josef Bacik 2019-06-20 965 spin_lock(&trans->transaction->dirty_bgs_lock);
e3e0520b32bc3db Josef Bacik 2019-06-20 966 }
e3e0520b32bc3db Josef Bacik 2019-06-20 967
e3e0520b32bc3db Josef Bacik 2019-06-20 968 if (!list_empty(&block_group->dirty_list)) {
e3e0520b32bc3db Josef Bacik 2019-06-20 969 list_del_init(&block_group->dirty_list);
e3e0520b32bc3db Josef Bacik 2019-06-20 970 remove_rsv = true;
e3e0520b32bc3db Josef Bacik 2019-06-20 971 btrfs_put_block_group(block_group);
e3e0520b32bc3db Josef Bacik 2019-06-20 972 }
e3e0520b32bc3db Josef Bacik 2019-06-20 973 spin_unlock(&trans->transaction->dirty_bgs_lock);
e3e0520b32bc3db Josef Bacik 2019-06-20 974 mutex_unlock(&trans->transaction->cache_write_mutex);
e3e0520b32bc3db Josef Bacik 2019-06-20 975
36b216c85eb9d7f Boris Burkov 2020-11-18 976 ret = btrfs_remove_free_space_inode(trans, inode, block_group);
e3e0520b32bc3db Josef Bacik 2019-06-20 977 if (ret)
9fecd13202f520f Filipe Manana 2020-06-01 978 goto out;
e3e0520b32bc3db Josef Bacik 2019-06-20 979
16b0c2581e3a81e Filipe Manana 2022-04-13 980 write_lock(&fs_info->block_group_cache_lock);
08dddb2951c96b5 Filipe Manana 2022-04-13 981 rb_erase_cached(&block_group->cache_node,
e3e0520b32bc3db Josef Bacik 2019-06-20 982 &fs_info->block_group_cache_tree);
e3e0520b32bc3db Josef Bacik 2019-06-20 983 RB_CLEAR_NODE(&block_group->cache_node);
e3e0520b32bc3db Josef Bacik 2019-06-20 984
9fecd13202f520f Filipe Manana 2020-06-01 985 /* Once for the block groups rbtree */
9fecd13202f520f Filipe Manana 2020-06-01 986 btrfs_put_block_group(block_group);
9fecd13202f520f Filipe Manana 2020-06-01 987
16b0c2581e3a81e Filipe Manana 2022-04-13 988 write_unlock(&fs_info->block_group_cache_lock);
e3e0520b32bc3db Josef Bacik 2019-06-20 989
e3e0520b32bc3db Josef Bacik 2019-06-20 990 down_write(&block_group->space_info->groups_sem);
e3e0520b32bc3db Josef Bacik 2019-06-20 991 /*
e3e0520b32bc3db Josef Bacik 2019-06-20 992 * we must use list_del_init so people can check to see if they
e3e0520b32bc3db Josef Bacik 2019-06-20 993 * are still on the list after taking the semaphore
e3e0520b32bc3db Josef Bacik 2019-06-20 994 */
e3e0520b32bc3db Josef Bacik 2019-06-20 995 list_del_init(&block_group->list);
e3e0520b32bc3db Josef Bacik 2019-06-20 996 if (list_empty(&block_group->space_info->block_groups[index])) {
e3e0520b32bc3db Josef Bacik 2019-06-20 997 kobj = block_group->space_info->block_group_kobjs[index];
e3e0520b32bc3db Josef Bacik 2019-06-20 998 block_group->space_info->block_group_kobjs[index] = NULL;
e3e0520b32bc3db Josef Bacik 2019-06-20 999 clear_avail_alloc_bits(fs_info, block_group->flags);
e3e0520b32bc3db Josef Bacik 2019-06-20 1000 }
e3e0520b32bc3db Josef Bacik 2019-06-20 1001 up_write(&block_group->space_info->groups_sem);
e3e0520b32bc3db Josef Bacik 2019-06-20 1002 clear_incompat_bg_bits(fs_info, block_group->flags);
e3e0520b32bc3db Josef Bacik 2019-06-20 1003 if (kobj) {
e3e0520b32bc3db Josef Bacik 2019-06-20 1004 kobject_del(kobj);
e3e0520b32bc3db Josef Bacik 2019-06-20 1005 kobject_put(kobj);
e3e0520b32bc3db Josef Bacik 2019-06-20 1006 }
e3e0520b32bc3db Josef Bacik 2019-06-20 1007
d82c8630686065a Josef Bacik 2022-07-13 1008 if (test_bit(BLOCK_GROUP_FLAG_HAS_CACHING_CTL,
d82c8630686065a Josef Bacik 2022-07-13 1009 &block_group->runtime_flags))
e3e0520b32bc3db Josef Bacik 2019-06-20 1010 caching_ctl = btrfs_get_caching_control(block_group);
e3e0520b32bc3db Josef Bacik 2019-06-20 1011 if (block_group->cached == BTRFS_CACHE_STARTED)
e3e0520b32bc3db Josef Bacik 2019-06-20 1012 btrfs_wait_block_group_cache_done(block_group);
d82c8630686065a Josef Bacik 2022-07-13 1013 if (test_bit(BLOCK_GROUP_FLAG_HAS_CACHING_CTL,
d82c8630686065a Josef Bacik 2022-07-13 1014 &block_group->runtime_flags)) {
16b0c2581e3a81e Filipe Manana 2022-04-13 1015 write_lock(&fs_info->block_group_cache_lock);
e3e0520b32bc3db Josef Bacik 2019-06-20 1016 if (!caching_ctl) {
e3e0520b32bc3db Josef Bacik 2019-06-20 1017 struct btrfs_caching_control *ctl;
e3e0520b32bc3db Josef Bacik 2019-06-20 1018
e3e0520b32bc3db Josef Bacik 2019-06-20 1019 list_for_each_entry(ctl,
e3e0520b32bc3db Josef Bacik 2019-06-20 1020 &fs_info->caching_block_groups, list)
e3e0520b32bc3db Josef Bacik 2019-06-20 1021 if (ctl->block_group == block_group) {
e3e0520b32bc3db Josef Bacik 2019-06-20 1022 caching_ctl = ctl;
e3e0520b32bc3db Josef Bacik 2019-06-20 1023 refcount_inc(&caching_ctl->count);
e3e0520b32bc3db Josef Bacik 2019-06-20 1024 break;
e3e0520b32bc3db Josef Bacik 2019-06-20 1025 }
e3e0520b32bc3db Josef Bacik 2019-06-20 1026 }
e3e0520b32bc3db Josef Bacik 2019-06-20 1027 if (caching_ctl)
e3e0520b32bc3db Josef Bacik 2019-06-20 1028 list_del_init(&caching_ctl->list);
16b0c2581e3a81e Filipe Manana 2022-04-13 1029 write_unlock(&fs_info->block_group_cache_lock);
e3e0520b32bc3db Josef Bacik 2019-06-20 1030 if (caching_ctl) {
e3e0520b32bc3db Josef Bacik 2019-06-20 1031 /* Once for the caching bgs list and once for us. */
e3e0520b32bc3db Josef Bacik 2019-06-20 1032 btrfs_put_caching_control(caching_ctl);
e3e0520b32bc3db Josef Bacik 2019-06-20 1033 btrfs_put_caching_control(caching_ctl);
e3e0520b32bc3db Josef Bacik 2019-06-20 1034 }
e3e0520b32bc3db Josef Bacik 2019-06-20 1035 }
e3e0520b32bc3db Josef Bacik 2019-06-20 1036
e3e0520b32bc3db Josef Bacik 2019-06-20 1037 spin_lock(&trans->transaction->dirty_bgs_lock);
e3e0520b32bc3db Josef Bacik 2019-06-20 1038 WARN_ON(!list_empty(&block_group->dirty_list));
e3e0520b32bc3db Josef Bacik 2019-06-20 1039 WARN_ON(!list_empty(&block_group->io_list));
e3e0520b32bc3db Josef Bacik 2019-06-20 1040 spin_unlock(&trans->transaction->dirty_bgs_lock);
e3e0520b32bc3db Josef Bacik 2019-06-20 1041
e3e0520b32bc3db Josef Bacik 2019-06-20 1042 btrfs_remove_free_space_cache(block_group);
e3e0520b32bc3db Josef Bacik 2019-06-20 1043
e3e0520b32bc3db Josef Bacik 2019-06-20 1044 spin_lock(&block_group->space_info->lock);
e3e0520b32bc3db Josef Bacik 2019-06-20 1045 list_del_init(&block_group->ro_list);
e3e0520b32bc3db Josef Bacik 2019-06-20 1046
e3e0520b32bc3db Josef Bacik 2019-06-20 1047 if (btrfs_test_opt(fs_info, ENOSPC_DEBUG)) {
e3e0520b32bc3db Josef Bacik 2019-06-20 1048 WARN_ON(block_group->space_info->total_bytes
b3470b5dbe1300d David Sterba 2019-10-23 1049 < block_group->length);
e3e0520b32bc3db Josef Bacik 2019-06-20 1050 WARN_ON(block_group->space_info->bytes_readonly
169e0da91a21a57 Naohiro Aota 2021-02-04 1051 < block_group->length - block_group->zone_unusable);
169e0da91a21a57 Naohiro Aota 2021-02-04 1052 WARN_ON(block_group->space_info->bytes_zone_unusable
169e0da91a21a57 Naohiro Aota 2021-02-04 1053 < block_group->zone_unusable);
e3e0520b32bc3db Josef Bacik 2019-06-20 1054 WARN_ON(block_group->space_info->disk_total
b3470b5dbe1300d David Sterba 2019-10-23 1055 < block_group->length * factor);
5c21202df2c7336 Naohiro Aota 2022-07-09 @1056 WARN_ON(block_group->zone_is_active &&
5c21202df2c7336 Naohiro Aota 2022-07-09 1057 block_group->space_info->active_total_bytes
5c21202df2c7336 Naohiro Aota 2022-07-09 1058 < block_group->length);
e3e0520b32bc3db Josef Bacik 2019-06-20 1059 }
b3470b5dbe1300d David Sterba 2019-10-23 1060 block_group->space_info->total_bytes -= block_group->length;
5c21202df2c7336 Naohiro Aota 2022-07-09 1061 if (block_group->zone_is_active)
5c21202df2c7336 Naohiro Aota 2022-07-09 1062 block_group->space_info->active_total_bytes -= block_group->length;
169e0da91a21a57 Naohiro Aota 2021-02-04 1063 block_group->space_info->bytes_readonly -=
169e0da91a21a57 Naohiro Aota 2021-02-04 1064 (block_group->length - block_group->zone_unusable);
169e0da91a21a57 Naohiro Aota 2021-02-04 1065 block_group->space_info->bytes_zone_unusable -=
169e0da91a21a57 Naohiro Aota 2021-02-04 1066 block_group->zone_unusable;
b3470b5dbe1300d David Sterba 2019-10-23 1067 block_group->space_info->disk_total -= block_group->length * factor;
e3e0520b32bc3db Josef Bacik 2019-06-20 1068
e3e0520b32bc3db Josef Bacik 2019-06-20 1069 spin_unlock(&block_group->space_info->lock);
e3e0520b32bc3db Josef Bacik 2019-06-20 1070
ffcb9d44572afba Filipe Manana 2020-06-01 1071 /*
ffcb9d44572afba Filipe Manana 2020-06-01 1072 * Remove the free space for the block group from the free space tree
ffcb9d44572afba Filipe Manana 2020-06-01 1073 * and the block group's item from the extent tree before marking the
ffcb9d44572afba Filipe Manana 2020-06-01 1074 * block group as removed. This is to prevent races with tasks that
ffcb9d44572afba Filipe Manana 2020-06-01 1075 * freeze and unfreeze a block group, this task and another task
ffcb9d44572afba Filipe Manana 2020-06-01 1076 * allocating a new block group - the unfreeze task ends up removing
ffcb9d44572afba Filipe Manana 2020-06-01 1077 * the block group's extent map before the task calling this function
ffcb9d44572afba Filipe Manana 2020-06-01 1078 * deletes the block group item from the extent tree, allowing for
ffcb9d44572afba Filipe Manana 2020-06-01 1079 * another task to attempt to create another block group with the same
ffcb9d44572afba Filipe Manana 2020-06-01 1080 * item key (and failing with -EEXIST and a transaction abort).
ffcb9d44572afba Filipe Manana 2020-06-01 1081 */
ffcb9d44572afba Filipe Manana 2020-06-01 1082 ret = remove_block_group_free_space(trans, block_group);
ffcb9d44572afba Filipe Manana 2020-06-01 1083 if (ret)
ffcb9d44572afba Filipe Manana 2020-06-01 1084 goto out;
ffcb9d44572afba Filipe Manana 2020-06-01 1085
ffcb9d44572afba Filipe Manana 2020-06-01 1086 ret = remove_block_group_item(trans, path, block_group);
ffcb9d44572afba Filipe Manana 2020-06-01 1087 if (ret < 0)
ffcb9d44572afba Filipe Manana 2020-06-01 1088 goto out;
ffcb9d44572afba Filipe Manana 2020-06-01 1089
e3e0520b32bc3db Josef Bacik 2019-06-20 1090 spin_lock(&block_group->lock);
d82c8630686065a Josef Bacik 2022-07-13 1091 set_bit(BLOCK_GROUP_FLAG_REMOVED, &block_group->runtime_flags);
d82c8630686065a Josef Bacik 2022-07-13 1092
e3e0520b32bc3db Josef Bacik 2019-06-20 1093 /*
6b7304af62d02d7 Filipe Manana 2020-05-08 1094 * At this point trimming or scrub can't start on this block group,
6b7304af62d02d7 Filipe Manana 2020-05-08 1095 * because we removed the block group from the rbtree
6b7304af62d02d7 Filipe Manana 2020-05-08 1096 * fs_info->block_group_cache_tree so no one can't find it anymore and
6b7304af62d02d7 Filipe Manana 2020-05-08 1097 * even if someone already got this block group before we removed it
6b7304af62d02d7 Filipe Manana 2020-05-08 1098 * from the rbtree, they have already incremented block_group->frozen -
6b7304af62d02d7 Filipe Manana 2020-05-08 1099 * if they didn't, for the trimming case they won't find any free space
6b7304af62d02d7 Filipe Manana 2020-05-08 1100 * entries because we already removed them all when we called
6b7304af62d02d7 Filipe Manana 2020-05-08 1101 * btrfs_remove_free_space_cache().
e3e0520b32bc3db Josef Bacik 2019-06-20 1102 *
e3e0520b32bc3db Josef Bacik 2019-06-20 1103 * And we must not remove the extent map from the fs_info->mapping_tree
e3e0520b32bc3db Josef Bacik 2019-06-20 1104 * to prevent the same logical address range and physical device space
6b7304af62d02d7 Filipe Manana 2020-05-08 1105 * ranges from being reused for a new block group. This is needed to
6b7304af62d02d7 Filipe Manana 2020-05-08 1106 * avoid races with trimming and scrub.
6b7304af62d02d7 Filipe Manana 2020-05-08 1107 *
6b7304af62d02d7 Filipe Manana 2020-05-08 1108 * An fs trim operation (btrfs_trim_fs() / btrfs_ioctl_fitrim()) is
e3e0520b32bc3db Josef Bacik 2019-06-20 1109 * completely transactionless, so while it is trimming a range the
e3e0520b32bc3db Josef Bacik 2019-06-20 1110 * currently running transaction might finish and a new one start,
e3e0520b32bc3db Josef Bacik 2019-06-20 1111 * allowing for new block groups to be created that can reuse the same
e3e0520b32bc3db Josef Bacik 2019-06-20 1112 * physical device locations unless we take this special care.
e3e0520b32bc3db Josef Bacik 2019-06-20 1113 *
e3e0520b32bc3db Josef Bacik 2019-06-20 1114 * There may also be an implicit trim operation if the file system
e3e0520b32bc3db Josef Bacik 2019-06-20 1115 * is mounted with -odiscard. The same protections must remain
e3e0520b32bc3db Josef Bacik 2019-06-20 1116 * in place until the extents have been discarded completely when
e3e0520b32bc3db Josef Bacik 2019-06-20 1117 * the transaction commit has completed.
e3e0520b32bc3db Josef Bacik 2019-06-20 1118 */
6b7304af62d02d7 Filipe Manana 2020-05-08 1119 remove_em = (atomic_read(&block_group->frozen) == 0);
e3e0520b32bc3db Josef Bacik 2019-06-20 1120 spin_unlock(&block_group->lock);
e3e0520b32bc3db Josef Bacik 2019-06-20 1121
e3e0520b32bc3db Josef Bacik 2019-06-20 1122 if (remove_em) {
e3e0520b32bc3db Josef Bacik 2019-06-20 1123 struct extent_map_tree *em_tree;
e3e0520b32bc3db Josef Bacik 2019-06-20 1124
e3e0520b32bc3db Josef Bacik 2019-06-20 1125 em_tree = &fs_info->mapping_tree;
e3e0520b32bc3db Josef Bacik 2019-06-20 1126 write_lock(&em_tree->lock);
e3e0520b32bc3db Josef Bacik 2019-06-20 1127 remove_extent_mapping(em_tree, em);
e3e0520b32bc3db Josef Bacik 2019-06-20 1128 write_unlock(&em_tree->lock);
e3e0520b32bc3db Josef Bacik 2019-06-20 1129 /* once for the tree */
e3e0520b32bc3db Josef Bacik 2019-06-20 1130 free_extent_map(em);
e3e0520b32bc3db Josef Bacik 2019-06-20 1131 }
f6033c5e333238f Xiyu Yang 2020-04-21 1132
9fecd13202f520f Filipe Manana 2020-06-01 1133 out:
f6033c5e333238f Xiyu Yang 2020-04-21 1134 /* Once for the lookup reference */
f6033c5e333238f Xiyu Yang 2020-04-21 1135 btrfs_put_block_group(block_group);
e3e0520b32bc3db Josef Bacik 2019-06-20 1136 if (remove_rsv)
e3e0520b32bc3db Josef Bacik 2019-06-20 1137 btrfs_delayed_refs_rsv_release(fs_info, 1);
e3e0520b32bc3db Josef Bacik 2019-06-20 1138 btrfs_free_path(path);
e3e0520b32bc3db Josef Bacik 2019-06-20 1139 return ret;
e3e0520b32bc3db Josef Bacik 2019-06-20 1140 }
e3e0520b32bc3db Josef Bacik 2019-06-20 1141 Signature · 2 lines
0-DAY CI Kernel Test Service https://01.org/lkp