Re: [PATCH] btrfs: zoned: fix deadlock between metadata writeback and transaction commit

"Naohiro Aota" <[email protected]>
Newsgroups org.kernel.vger.linux-btrfs,org.kernel.vger.stable
Message-ID <[email protected]>
On Fri Jul 3, 2026 at 2:54 PM JST, Johannes Thumshirn wrote:
> When writing out metadata extent buffers in a zoned filesystem,
> btree_writepages() holds fs_info->zoned_meta_io_lock across the whole
> writeback loop, including the call to btrfs_check_meta_write_pointer() ->
> check_bg_is_active().
>
> For the tree-log block group, check_bg_is_active() may fail to activate
> the zone and fall back to btrfs_zone_finish_one_bg() to free an active
> zone. That path waits for the running transaction to commit while still
> holding zoned_meta_io_lock, but the committer needs that same lock to
> write out the tree extents, so the two tasks deadlock:
>
>   Task A (kworker, metadata writeback)      Task B (fsstress, transaction commit)
>   ------------------------------------      -------------------------------------
>   wb_workfn()                               btrfs_commit_transaction(T)
>    btree_writepages()                        btrfs_write_and_wait_transaction()
>     btrfs_zoned_meta_io_lock()                btrfs_write_marked_extents()
>     btrfs_check_meta_write_pointer()           btree_writepages()
>      check_bg_is_active() [treelog_bg]          btrfs_zoned_meta_io_lock()
>       btrfs_zone_finish_one_bg()               <blocks on zoned_meta_io_lock,
>        btrfs_zone_finish()                      held by Task A>
>         do_zone_finish()
>          btrfs_inc_block_group_ro()
>           btrfs_wait_for_commit()
>            <blocks waiting for commit
>             of transaction T, done by
>             Task B>
>
> The sibling branch in check_bg_is_active() already drops zoned_meta_io_lock
> around do_zone_finish() for this exact reason. Do the same in the tree-log
> branch: release the lock around btrfs_zone_finish_one_bg() and re-acquire
> it afterwards. The lock only protects fs_info->active_{meta,system}_bg,
> which this branch does not touch, and ctx->zoned_bg keeps a reference to
> the block group across the unlock, so nothing is lost while the lock
> is dropped.
>
> This hang occasionally reproduces with fstests generic/475 on a zoned
> btrfs filesystem.

looks good,

Reviewed-by: Naohiro Aota <[email protected]>

Note: I'm thinking to make treelog_bg reserved, and pivot like as
metadata block group. It will be more reliable and naturally aligned
with the metadata block group.

>
> Fixes: 13bb483d32ab ("btrfs: zoned: activate metadata block group on write time")
> Cc: [email protected]
> Signed-off-by: Johannes Thumshirn <[email protected]>
> ---
>  fs/btrfs/zoned.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
> index 97f06dd01693..44a13ed6b8b2 100644
> --- a/fs/btrfs/zoned.c
> +++ b/fs/btrfs/zoned.c
> @@ -2190,7 +2190,11 @@ static bool check_bg_is_active(struct btrfs_eb_write_context *ctx,
>  
>  	if (fs_info->treelog_bg == block_group->start) {
>  		if (!btrfs_zone_activate(block_group)) {
> -			int ret_fin = btrfs_zone_finish_one_bg(fs_info);
> +			int ret_fin;
> +
> +			btrfs_zoned_meta_io_unlock(fs_info);
> +			ret_fin = btrfs_zone_finish_one_bg(fs_info);
> +			btrfs_zoned_meta_io_lock(fs_info);
>  
>  			if (ret_fin != 1 || !btrfs_zone_activate(block_group))
>  				return false;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.