* [PATCH 0/5] btrfs: block group cleanups
@ 2022-07-14 0:34 Josef Bacik
2022-07-14 0:34 ` [PATCH 1/5] btrfs: use btrfs_fs_closing for background bg work Josef Bacik
` (4 more replies)
0 siblings, 5 replies; 11+ messages in thread
From: Josef Bacik @ 2022-07-14 0:34 UTC (permalink / raw)
To: linux-btrfs, kernel-team
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(-)
--
2.26.3
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/5] btrfs: use btrfs_fs_closing for background bg work
2022-07-14 0:34 [PATCH 0/5] btrfs: block group cleanups Josef Bacik
@ 2022-07-14 0:34 ` Josef Bacik
2022-07-14 7:18 ` Johannes Thumshirn
2022-07-14 0:34 ` [PATCH 2/5] btrfs: convert block group bit field to use bit helpers Josef Bacik
` (3 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Josef Bacik @ 2022-07-14 0:34 UTC (permalink / raw)
To: linux-btrfs, kernel-team
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.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
fs/btrfs/block-group.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
index c3aecfb0a71d..1e61d967d8be 100644
--- a/fs/btrfs/block-group.c
+++ b/fs/btrfs/block-group.c
@@ -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))
--
2.26.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/5] btrfs: convert block group bit field to use bit helpers
2022-07-14 0:34 [PATCH 0/5] btrfs: block group cleanups Josef Bacik
2022-07-14 0:34 ` [PATCH 1/5] btrfs: use btrfs_fs_closing for background bg work Josef Bacik
@ 2022-07-14 0:34 ` Josef Bacik
2022-07-14 7:21 ` Johannes Thumshirn
2022-07-14 22:40 ` kernel test robot
2022-07-14 0:34 ` [PATCH 3/5] btrfs: remove block_group->lock protection for TO_COPY Josef Bacik
` (2 subsequent siblings)
4 siblings, 2 replies; 11+ messages in thread
From: Josef Bacik @ 2022-07-14 0:34 UTC (permalink / raw)
To: linux-btrfs, kernel-team
We 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.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
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(-)
diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
index 1e61d967d8be..e27098571011 100644
--- a/fs/btrfs/block-group.c
+++ b/fs/btrfs/block-group.c
@@ -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) {
diff --git a/fs/btrfs/block-group.h b/fs/btrfs/block-group.h
index 35e0e860cc0b..8008a391ed8c 100644
--- a/fs/btrfs/block-group.h
+++ b/fs/btrfs/block-group.h
@@ -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;
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index f43196a893ca..f85bbd99230b 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -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;
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index c6a9237b31b9..151f254d5c11 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -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);
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index 996da650ecdc..fd73327134ac 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -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;
}
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 3afe5fa50a63..b7be62f1cd8e 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -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,
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index bf4e140f6bfc..7637eae1a699 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -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,
diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
index 96836dd5de78..02e26e8f8ab2 100644
--- a/fs/btrfs/zoned.c
+++ b/fs/btrfs/zoned.c
@@ -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_writ
int 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 logica
ASSERT(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:
--
2.26.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/5] btrfs: remove block_group->lock protection for TO_COPY
2022-07-14 0:34 [PATCH 0/5] btrfs: block group cleanups Josef Bacik
2022-07-14 0:34 ` [PATCH 1/5] btrfs: use btrfs_fs_closing for background bg work Josef Bacik
2022-07-14 0:34 ` [PATCH 2/5] btrfs: convert block group bit field to use bit helpers Josef Bacik
@ 2022-07-14 0:34 ` Josef Bacik
2022-07-14 7:23 ` Johannes Thumshirn
2022-07-14 0:34 ` [PATCH 4/5] btrfs: simplify btrfs_put_block_group_cache Josef Bacik
2022-07-14 0:34 ` [PATCH 5/5] btrfs: remove BLOCK_GROUP_FLAG_HAS_CACHING_CTL Josef Bacik
4 siblings, 1 reply; 11+ messages in thread
From: Josef Bacik @ 2022-07-14 0:34 UTC (permalink / raw)
To: linux-btrfs, kernel-team
We 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.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
fs/btrfs/dev-replace.c | 5 -----
fs/btrfs/scrub.c | 3 ---
fs/btrfs/volumes.c | 2 --
3 files changed, 10 deletions(-)
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index f85bbd99230b..488f2105c5d0 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -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;
}
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index b7be62f1cd8e..14af085fe868 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -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);
}
/*
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 7637eae1a699..83c9bae144c7 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -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;
--
2.26.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 4/5] btrfs: simplify btrfs_put_block_group_cache
2022-07-14 0:34 [PATCH 0/5] btrfs: block group cleanups Josef Bacik
` (2 preceding siblings ...)
2022-07-14 0:34 ` [PATCH 3/5] btrfs: remove block_group->lock protection for TO_COPY Josef Bacik
@ 2022-07-14 0:34 ` Josef Bacik
2022-07-14 9:04 ` Johannes Thumshirn
2022-07-14 0:34 ` [PATCH 5/5] btrfs: remove BLOCK_GROUP_FLAG_HAS_CACHING_CTL Josef Bacik
4 siblings, 1 reply; 11+ messages in thread
From: Josef Bacik @ 2022-07-14 0:34 UTC (permalink / raw)
To: linux-btrfs, kernel-team
We'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.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
fs/btrfs/block-group.c | 42 +++++++++++++++---------------------------
1 file changed, 15 insertions(+), 27 deletions(-)
diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
index e27098571011..51096f88b8d3 100644
--- a/fs/btrfs/block-group.c
+++ b/fs/btrfs/block-group.c
@@ -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);
}
}
--
2.26.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 5/5] btrfs: remove BLOCK_GROUP_FLAG_HAS_CACHING_CTL
2022-07-14 0:34 [PATCH 0/5] btrfs: block group cleanups Josef Bacik
` (3 preceding siblings ...)
2022-07-14 0:34 ` [PATCH 4/5] btrfs: simplify btrfs_put_block_group_cache Josef Bacik
@ 2022-07-14 0:34 ` Josef Bacik
4 siblings, 0 replies; 11+ messages in thread
From: Josef Bacik @ 2022-07-14 0:34 UTC (permalink / raw)
To: linux-btrfs, kernel-team
This 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.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
fs/btrfs/block-group.c | 46 +++++++++++++++++++-----------------------
fs/btrfs/block-group.h | 1 -
2 files changed, 21 insertions(+), 26 deletions(-)
diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
index 51096f88b8d3..26202918bc9f 100644
--- a/fs/btrfs/block-group.c
+++ b/fs/btrfs/block-group.c
@@ -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));
diff --git a/fs/btrfs/block-group.h b/fs/btrfs/block-group.h
index 8008a391ed8c..fffcc7789fa7 100644
--- a/fs/btrfs/block-group.h
+++ b/fs/btrfs/block-group.h
@@ -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,
--
2.26.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 1/5] btrfs: use btrfs_fs_closing for background bg work
2022-07-14 0:34 ` [PATCH 1/5] btrfs: use btrfs_fs_closing for background bg work Josef Bacik
@ 2022-07-14 7:18 ` Johannes Thumshirn
0 siblings, 0 replies; 11+ messages in thread
From: Johannes Thumshirn @ 2022-07-14 7:18 UTC (permalink / raw)
To: Josef Bacik, linux-btrfs, kernel-team
Looks good,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/5] btrfs: convert block group bit field to use bit helpers
2022-07-14 0:34 ` [PATCH 2/5] btrfs: convert block group bit field to use bit helpers Josef Bacik
@ 2022-07-14 7:21 ` Johannes Thumshirn
2022-07-14 22:40 ` kernel test robot
1 sibling, 0 replies; 11+ messages in thread
From: Johannes Thumshirn @ 2022-07-14 7:21 UTC (permalink / raw)
To: Josef Bacik, linux-btrfs, kernel-team
Looks good,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 3/5] btrfs: remove block_group->lock protection for TO_COPY
2022-07-14 0:34 ` [PATCH 3/5] btrfs: remove block_group->lock protection for TO_COPY Josef Bacik
@ 2022-07-14 7:23 ` Johannes Thumshirn
0 siblings, 0 replies; 11+ messages in thread
From: Johannes Thumshirn @ 2022-07-14 7:23 UTC (permalink / raw)
To: Josef Bacik, linux-btrfs, kernel-team
Looks good,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 4/5] btrfs: simplify btrfs_put_block_group_cache
2022-07-14 0:34 ` [PATCH 4/5] btrfs: simplify btrfs_put_block_group_cache Josef Bacik
@ 2022-07-14 9:04 ` Johannes Thumshirn
0 siblings, 0 replies; 11+ messages in thread
From: Johannes Thumshirn @ 2022-07-14 9:04 UTC (permalink / raw)
To: Josef Bacik, linux-btrfs, kernel-team
Looks good,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/5] btrfs: convert block group bit field to use bit helpers
2022-07-14 0:34 ` [PATCH 2/5] btrfs: convert block group bit field to use bit helpers Josef Bacik
2022-07-14 7:21 ` Johannes Thumshirn
@ 2022-07-14 22:40 ` kernel test robot
1 sibling, 0 replies; 11+ messages in thread
From: kernel test robot @ 2022-07-14 22:40 UTC (permalink / raw)
To: Josef Bacik, linux-btrfs, kernel-team; +Cc: llvm, kbuild-all
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/202207150643.6MYJm2hT-lkp@intel.com/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
Reported-by: kernel test robot <lkp@intel.com>
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
--
0-DAY CI Kernel Test Service
https://01.org/lkp
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2022-07-14 22:41 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-14 0:34 [PATCH 0/5] btrfs: block group cleanups Josef Bacik
2022-07-14 0:34 ` [PATCH 1/5] btrfs: use btrfs_fs_closing for background bg work Josef Bacik
2022-07-14 7:18 ` Johannes Thumshirn
2022-07-14 0:34 ` [PATCH 2/5] btrfs: convert block group bit field to use bit helpers Josef Bacik
2022-07-14 7:21 ` Johannes Thumshirn
2022-07-14 22:40 ` kernel test robot
2022-07-14 0:34 ` [PATCH 3/5] btrfs: remove block_group->lock protection for TO_COPY Josef Bacik
2022-07-14 7:23 ` Johannes Thumshirn
2022-07-14 0:34 ` [PATCH 4/5] btrfs: simplify btrfs_put_block_group_cache Josef Bacik
2022-07-14 9:04 ` Johannes Thumshirn
2022-07-14 0:34 ` [PATCH 5/5] btrfs: remove BLOCK_GROUP_FLAG_HAS_CACHING_CTL Josef Bacik
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).