From: Wang Yugui <wangyugui@e16-tech.com>
To: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Cc: linux-btrfs@vger.kernel.org, Naohiro Aota <naohiro.aota@wdc.com>
Subject: Re: [PATCH v2 1/4] btrfs: zoned: only change active zone counter on successful (de)activation
Date: Fri, 02 Oct 2026 23:38:57 +0800 [thread overview]
Message-ID: <20261002233856.C191.409509F4@e16-tech.com> (raw)
In-Reply-To: <20261002073715.2191177-2-johannes.thumshirn@wdc.com>
Hi,
> btrfs_zone_activate() unconditionally decrements the reserved_active_zones
> counter regardless if btrfs_dev_set_active_zone() fails to set the zone
> active, i.e. because it raced with another call that already set the bit
> in the bitmask, or not.
>
> This can lead to a double decrement of the counter in case the bit has
> already been set.
>
> Only decrement the counter *iff* btrfs_dev_set_active_zone() successfully
> marked the zone in the bitmap.
>
> Mirror this behaviour when clearing the bit again.
>
> Fixes: a7e1ac7bdc5a ("btrfs: zoned: reserve zones for an active metadata/system block group")
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
> ---
> fs/btrfs/zoned.c | 27 +++++++++++++++++++--------
> 1 file changed, 19 insertions(+), 8 deletions(-)
>
> diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
> index 9f562cc34e38..d68b91008e76 100644
> --- a/fs/btrfs/zoned.c
> +++ b/fs/btrfs/zoned.c
> @@ -1126,11 +1126,13 @@ u64 btrfs_find_allocatable_zones(struct btrfs_device *device, u64 hole_start,
> return pos;
> }
>
> -static bool btrfs_dev_set_active_zone(struct btrfs_device *device, u64 pos)
> +static bool btrfs_dev_set_active_zone(struct btrfs_device *device, u64 pos, bool *new)
> {
> struct btrfs_zoned_device_info *zone_info = device->zone_info;
> unsigned int zno = (pos >> zone_info->zone_size_shift);
>
> + *new = false;
> +
> /* We can use any number of zones */
> if (zone_info->max_active_zones == 0)
> return true;
> @@ -1142,23 +1144,30 @@ static bool btrfs_dev_set_active_zone(struct btrfs_device *device, u64 pos)
> if (test_and_set_bit(zno, zone_info->active_zones)) {
> /* Someone already set the bit */
> atomic_inc(&zone_info->active_zones_left);
> + } else {
> + *new = true;
> }
> }
>
> return true;
> }
>
> -static void btrfs_dev_clear_active_zone(struct btrfs_device *device, u64 pos)
> +static bool btrfs_dev_clear_active_zone(struct btrfs_device *device, u64 pos)
> {
> struct btrfs_zoned_device_info *zone_info = device->zone_info;
> unsigned int zno = (pos >> zone_info->zone_size_shift);
>
> +
> /* We can use any number of zones */
> if (zone_info->max_active_zones == 0)
> - return;
> + return false;
>
> - if (test_and_clear_bit(zno, zone_info->active_zones))
> + if (test_and_clear_bit(zno, zone_info->active_zones)) {
> atomic_inc(&zone_info->active_zones_left);
> + return true;
> + }
> +
> + return false;
> }
>
> int btrfs_reset_device_zone(struct btrfs_device *device, u64 physical,
> @@ -2411,6 +2420,7 @@ bool btrfs_zone_activate(struct btrfs_block_group *block_group)
> u64 physical;
> const bool is_data = (block_group->flags & BTRFS_BLOCK_GROUP_DATA);
> bool ret;
> + bool new;
'new' is not a good var name because it is a keyword in C++/Java.
'is_new' just like above 'is_data' maybe a better var name.
Best Regards
Wang Yugui
next prev parent reply other threads:[~2026-10-02 15:54 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-02 7:37 [PATCH v2 0/4] btrfs: zoned: LLM inspired fixes Johannes Thumshirn
2026-10-02 7:37 ` [PATCH v2 1/4] btrfs: zoned: only change active zone counter on successful (de)activation Johannes Thumshirn
2026-10-02 15:38 ` Wang Yugui [this message]
2026-10-02 16:28 ` Johannes Thumshirn
2026-10-02 7:37 ` [PATCH v2 2/4] btrfs: zoned: fix possible UAF in wait_eb_writebacks Johannes Thumshirn
2026-10-02 7:37 ` [PATCH v2 3/4] btrfs: zoned: requeue block group if zone reset bails out Johannes Thumshirn
2026-10-02 7:37 ` [PATCH v2 4/4] btrfs: zoned: avoid underflow of bytes_zone_unusable Johannes Thumshirn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261002233856.C191.409509F4@e16-tech.com \
--to=wangyugui@e16-tech.com \
--cc=johannes.thumshirn@wdc.com \
--cc=linux-btrfs@vger.kernel.org \
--cc=naohiro.aota@wdc.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.