[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220418121212.221607002@linuxfoundation.org>
Date: Mon, 18 Apr 2022 14:12:40 +0200
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org,
Johannes Thumshirn <johannes.thumshirn@....com>,
Naohiro Aota <naohiro.aota@....com>,
David Sterba <dsterba@...e.com>
Subject: [PATCH 5.17 191/219] btrfs: zoned: activate block group only for extent allocation
From: Naohiro Aota <naohiro.aota@....com>
commit 760e69c4c2e2f475a812bdd414b62758215ce9cb upstream.
In btrfs_make_block_group(), we activate the allocated block group,
expecting that the block group is soon used for allocation. However, the
chunk allocation from flush_space() context broke the assumption. There
can be a large time gap between the chunk allocation time and the extent
allocation time from the chunk.
Activating the empty block groups pre-allocated from flush_space()
context can exhaust the active zone counter of a device. Once we use all
the active zone counts for empty pre-allocated block groups, we cannot
activate new block group for the other things: metadata, tree-log, or
data relocation block group. That failure results in a fake -ENOSPC.
This patch introduces CHUNK_ALLOC_FORCE_FOR_EXTENT to distinguish the
chunk allocation from find_free_extent(). Now, the new block group is
activated only in that context.
Fixes: eb66a010d518 ("btrfs: zoned: activate new block group")
CC: stable@...r.kernel.org # 5.16+
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@....com>
Tested-by: Johannes Thumshirn <johannes.thumshirn@....com>
Signed-off-by: Naohiro Aota <naohiro.aota@....com>
Signed-off-by: David Sterba <dsterba@...e.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
fs/btrfs/block-group.c | 24 ++++++++++++++++--------
fs/btrfs/block-group.h | 4 ++++
fs/btrfs/extent-tree.c | 2 +-
3 files changed, 21 insertions(+), 9 deletions(-)
--- a/fs/btrfs/block-group.c
+++ b/fs/btrfs/block-group.c
@@ -2479,12 +2479,6 @@ struct btrfs_block_group *btrfs_make_blo
return ERR_PTR(ret);
}
- /*
- * New block group is likely to be used soon. Try to activate it now.
- * Failure is OK for now.
- */
- btrfs_zone_activate(cache);
-
ret = exclude_super_stripes(cache);
if (ret) {
/* We may have excluded something, so call this just in case */
@@ -3636,8 +3630,14 @@ int btrfs_chunk_alloc(struct btrfs_trans
struct btrfs_block_group *ret_bg;
bool wait_for_alloc = false;
bool should_alloc = false;
+ bool from_extent_allocation = false;
int ret = 0;
+ if (force == CHUNK_ALLOC_FORCE_FOR_EXTENT) {
+ from_extent_allocation = true;
+ force = CHUNK_ALLOC_FORCE;
+ }
+
/* Don't re-enter if we're already allocating a chunk */
if (trans->allocating_chunk)
return -ENOSPC;
@@ -3730,9 +3730,17 @@ int btrfs_chunk_alloc(struct btrfs_trans
ret_bg = do_chunk_alloc(trans, flags);
trans->allocating_chunk = false;
- if (IS_ERR(ret_bg))
+ if (IS_ERR(ret_bg)) {
ret = PTR_ERR(ret_bg);
- else
+ } else if (from_extent_allocation) {
+ /*
+ * New block group is likely to be used soon. Try to activate
+ * it now. Failure is OK for now.
+ */
+ btrfs_zone_activate(ret_bg);
+ }
+
+ if (!ret)
btrfs_put_block_group(ret_bg);
spin_lock(&space_info->lock);
--- a/fs/btrfs/block-group.h
+++ b/fs/btrfs/block-group.h
@@ -35,11 +35,15 @@ enum btrfs_discard_state {
* the FS with empty chunks
*
* CHUNK_ALLOC_FORCE means it must try to allocate one
+ *
+ * CHUNK_ALLOC_FORCE_FOR_EXTENT like CHUNK_ALLOC_FORCE but called from
+ * find_free_extent() that also activaes the zone
*/
enum btrfs_chunk_alloc_enum {
CHUNK_ALLOC_NO_FORCE,
CHUNK_ALLOC_LIMITED,
CHUNK_ALLOC_FORCE,
+ CHUNK_ALLOC_FORCE_FOR_EXTENT,
};
struct btrfs_caching_control {
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -4087,7 +4087,7 @@ static int find_free_extent_update_loop(
}
ret = btrfs_chunk_alloc(trans, ffe_ctl->flags,
- CHUNK_ALLOC_FORCE);
+ CHUNK_ALLOC_FORCE_FOR_EXTENT);
/* Do not bail out on ENOSPC since we can do more. */
if (ret == -ENOSPC)
Powered by blists - more mailing lists