* [PATCH v2 0/2] btrfs: zoned: fix removing of unwritten non-data block group
@ 2025-07-11 7:11 Naohiro Aota
2025-07-11 7:11 ` [PATCH v2 1/2] btrfs: zoned: do not remove " Naohiro Aota
2025-07-11 7:11 ` [PATCH v2 2/2] btrfs: zoned: requeue to unused block group list if zone finish failed Naohiro Aota
0 siblings, 2 replies; 5+ messages in thread
From: Naohiro Aota @ 2025-07-11 7:11 UTC (permalink / raw)
To: linux-btrfs; +Cc: Naohiro Aota
There are some reports of "unable to find chunk map for logical 2147483648
length 16384" error message appears in the dmesg. This means some IOs are
occurring after a block group is removed.
The IOs are coming from unused dirty tree nodes. When a metadata tree
node is cleaned on the zoned setup, we keep that node still dirty and
write it out not to create a write hole. When user operation e.g,
fsync() is fast enough, we can have a block group full of "unused dirty"
tree nodes. Such block group has its used count == 0, making it "unused"
block group and candidate for removal.
Removing the block group keeps the dirty nodes unsent until next sync or
umount operation. At that time, such nodes will cause the "unable to
find chunk map" failures.
This sympton can happen relatively easy on SMR, whose zone size ==
256MB, but it is hidden coincidently hitting a check in
do_zone_finish(). Hitting the check remove the block group from the
unused list and let it never reclaimed, which itself is a problem.
Fix them adding an extra check in the BG removal process and put a block
group in the retry list when btrfs_zone_finish() returns -EAGAIN.
Changes:
- v2
- Refine has_unwritten_metadata() structure.
- Add message when hitting the WARN_ON.
Naohiro Aota (2):
btrfs: zoned: do not remove unwritten non-data block group
btrfs: zoned: requeue to unused block group list if zone finish failed
fs/btrfs/block-group.c | 31 ++++++++++++++++++++++++++++---
1 file changed, 28 insertions(+), 3 deletions(-)
--
2.50.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 1/2] btrfs: zoned: do not remove unwritten non-data block group
2025-07-11 7:11 [PATCH v2 0/2] btrfs: zoned: fix removing of unwritten non-data block group Naohiro Aota
@ 2025-07-11 7:11 ` Naohiro Aota
2025-07-11 8:10 ` Johannes Thumshirn
2025-07-11 7:11 ` [PATCH v2 2/2] btrfs: zoned: requeue to unused block group list if zone finish failed Naohiro Aota
1 sibling, 1 reply; 5+ messages in thread
From: Naohiro Aota @ 2025-07-11 7:11 UTC (permalink / raw)
To: linux-btrfs; +Cc: Naohiro Aota
There are some reports of "unable to find chunk map for logical 2147483648
length 16384" error message appears in the dmesg. This means some IOs are
occurring after a block group is removed.
When a metadata tree node is cleaned on the zoned setup, we keep that node
still dirty and write it out not to create a write hole. However, this can
make a block group's used bytes == 0 while there is dirty region left.
Such unused block group is moved into the unused_bg list and processed for
the removal. When the removal succeeds, the block group is removed from the
transaction->dirty_bgs list, so the unused dirty nodes in the block group
are not sent at the transaction commit time. It will be written at some
later time e.g, sync or umount, and causes the "unable to find chunk map"
errors.
This can happen relatively easier on SMR whose zone size is 256MB. However,
calling do_zone_finish() on such block group returns -EAGAIN and keep that
block group intact, which is why the issue is hidden until now.
Fixes: afba2bc036b0 ("btrfs: zoned: implement active zone tracking")
CC: stable@vger.kernel.org # 6.1+
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
---
fs/btrfs/block-group.c | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
index 3e895427c773..d93982aac5b6 100644
--- a/fs/btrfs/block-group.c
+++ b/fs/btrfs/block-group.c
@@ -34,6 +34,19 @@ int btrfs_should_fragment_free_space(const struct btrfs_block_group *block_group
}
#endif
+static inline bool has_unwritten_metadata(struct btrfs_block_group *block_group)
+{
+ /* The meta_write_pointer is available only on the zoned setup. */
+ if (!btrfs_is_zoned(block_group->fs_info))
+ return false;
+
+ if (block_group->flags & BTRFS_BLOCK_GROUP_DATA)
+ return false;
+
+ return block_group->start + block_group->alloc_offset >
+ block_group->meta_write_pointer;
+}
+
/*
* Return target flags in extended format or 0 if restripe for this chunk_type
* is not in progress
@@ -1244,6 +1257,15 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
goto out;
spin_lock(&block_group->lock);
+ /*
+ * Hitting this WARN means we removed a block group with an unwritten
+ * region. It will cause "unable to find chunk map for logical" errors.
+ */
+ if (WARN_ON(has_unwritten_metadata(block_group)))
+ btrfs_warn(fs_info,
+ "block group %llu is removed before metadata write out",
+ block_group->start);
+
set_bit(BLOCK_GROUP_FLAG_REMOVED, &block_group->runtime_flags);
/*
@@ -1586,8 +1608,9 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
* needing to allocate extents from the block group.
*/
used = btrfs_space_info_used(space_info, true);
- if (space_info->total_bytes - block_group->length < used &&
- block_group->zone_unusable < block_group->length) {
+ if ((space_info->total_bytes - block_group->length < used &&
+ block_group->zone_unusable < block_group->length) ||
+ has_unwritten_metadata(block_group)) {
/*
* Add a reference for the list, compensate for the ref
* drop under the "next" label for the
--
2.50.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH v2 1/2] btrfs: zoned: do not remove unwritten non-data block group
2025-07-11 7:11 ` [PATCH v2 1/2] btrfs: zoned: do not remove " Naohiro Aota
@ 2025-07-11 8:10 ` Johannes Thumshirn
0 siblings, 0 replies; 5+ messages in thread
From: Johannes Thumshirn @ 2025-07-11 8:10 UTC (permalink / raw)
To: Naohiro Aota, linux-btrfs@vger.kernel.org
On 11.07.25 09:12, Naohiro Aota wrote:
> There are some reports of "unable to find chunk map for logical 2147483648
> length 16384" error message appears in the dmesg. This means some IOs are
s/the// ~^
> occurring after a block group is removed.
>
> When a metadata tree node is cleaned on the zoned setup, we keep that node
s/the/a ~^
> still dirty and write it out not to create a write hole. However, this can
> make a block group's used bytes == 0 while there is dirty region left.
a dirty region ~^
>
> Such unused block group is moved into the unused_bg list and processed for
Such an unused
> the removal. When the removal succeeds, the block group is removed from the
^~ s/the//
> transaction->dirty_bgs list, so the unused dirty nodes in the block group
> are not sent at the transaction commit time. It will be written at some
> later time e.g, sync or umount, and causes the "unable to find chunk map"
s/the// ~^
> errors.
>
> This can happen relatively easier on SMR whose zone size is 256MB. However,
s/easier/easy/
> calling do_zone_finish() on such block group returns -EAGAIN and keep that
> block group intact, which is why the issue is hidden until now.
>
> Fixes: afba2bc036b0 ("btrfs: zoned: implement active zone tracking")
> CC: stable@vger.kernel.org # 6.1+
> Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Sorry for not spotting these in v1. But I think they can be fixed up
when applying.
Otherwise looks good,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 2/2] btrfs: zoned: requeue to unused block group list if zone finish failed
2025-07-11 7:11 [PATCH v2 0/2] btrfs: zoned: fix removing of unwritten non-data block group Naohiro Aota
2025-07-11 7:11 ` [PATCH v2 1/2] btrfs: zoned: do not remove " Naohiro Aota
@ 2025-07-11 7:11 ` Naohiro Aota
2025-07-11 8:12 ` Johannes Thumshirn
1 sibling, 1 reply; 5+ messages in thread
From: Naohiro Aota @ 2025-07-11 7:11 UTC (permalink / raw)
To: linux-btrfs; +Cc: Naohiro Aota
btrfs_zone_finish() can fail for several reason. If it is -EAGAIN, we need
to try it again later. So, put the block group to the retry list properly.
Failed to do so will keep the removable block group intact until remount
and can causes unnecessary ENOSPC.
Fixes: 74e91b12b115 ("btrfs: zoned: zone finish unused block group")
CC: stable@vger.kernel.org # 6.1+
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
---
fs/btrfs/block-group.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
index d93982aac5b6..c085d3782fef 100644
--- a/fs/btrfs/block-group.c
+++ b/fs/btrfs/block-group.c
@@ -1639,8 +1639,10 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
ret = btrfs_zone_finish(block_group);
if (ret < 0) {
btrfs_dec_block_group_ro(block_group);
- if (ret == -EAGAIN)
+ if (ret == -EAGAIN) {
+ btrfs_link_bg_list(block_group, &retry_list);
ret = 0;
+ }
goto next;
}
--
2.50.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH v2 2/2] btrfs: zoned: requeue to unused block group list if zone finish failed
2025-07-11 7:11 ` [PATCH v2 2/2] btrfs: zoned: requeue to unused block group list if zone finish failed Naohiro Aota
@ 2025-07-11 8:12 ` Johannes Thumshirn
0 siblings, 0 replies; 5+ messages in thread
From: Johannes Thumshirn @ 2025-07-11 8:12 UTC (permalink / raw)
To: Naohiro Aota, linux-btrfs@vger.kernel.org
On 11.07.25 09:12, Naohiro Aota wrote:
> btrfs_zone_finish() can fail for several reason. If it is -EAGAIN, we need
resons.
> to try it again later. So, put the block group to the retry list properly.
>
> Failed to do so will keep the removable block group intact until remount
Failing
> and can causes unnecessary ENOSPC.
>
> Fixes: 74e91b12b115 ("btrfs: zoned: zone finish unused block group")
> CC: stable@vger.kernel.org # 6.1+
> Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-07-11 8:12 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-11 7:11 [PATCH v2 0/2] btrfs: zoned: fix removing of unwritten non-data block group Naohiro Aota
2025-07-11 7:11 ` [PATCH v2 1/2] btrfs: zoned: do not remove " Naohiro Aota
2025-07-11 8:10 ` Johannes Thumshirn
2025-07-11 7:11 ` [PATCH v2 2/2] btrfs: zoned: requeue to unused block group list if zone finish failed Naohiro Aota
2025-07-11 8:12 ` Johannes Thumshirn
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox