* [PATCH 0/2] null_blk: zone resource management fixes @ 2026-10-21 20:21 Niklas Cassel 2026-10-21 20:21 ` [PATCH 1/2] null_blk: fix opening closed zones at the active zone limit Niklas Cassel 2026-10-21 20:21 ` [PATCH 2/2] null_blk: don't finish zones to set them read-only or offline Niklas Cassel 0 siblings, 2 replies; 7+ messages in thread From: Niklas Cassel @ 2026-10-21 20:21 UTC (permalink / raw) To: Jens Axboe Cc: Shin'ichiro Kawasaki, Johannes Thumshirn, Damien Le Moal, linux-block, Niklas Cassel Patch 1 fixes writing, opening and finishing a closed zone when both the open and the active zone limits are reached: null_blk fails the request instead of closing an implicitly open zone, as ZBC-3 and NVMe ZNS require. Patch 2 fixes zone_readonly and zone_offline, which can close an unrelated zone, or leak the closed zone count. Both issues were reproduced, and the fixes tested, in QEMU, with null_blk devices created through configfs (memory_backed=0 and 1, CONFIG_PROVE_LOCKING=y). Developed with the help of an AI coding assistant. Niklas Cassel (2): null_blk: fix opening closed zones at the active zone limit null_blk: don't finish zones to set them read-only or offline drivers/block/null_blk/zoned.c | 48 ++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 11 deletions(-) base-commit: f47d223627f80cb7a1eb14c585fe6cb35de5e984 -- 2.56.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] null_blk: fix opening closed zones at the active zone limit 2026-10-21 20:21 [PATCH 0/2] null_blk: zone resource management fixes Niklas Cassel @ 2026-10-21 20:21 ` Niklas Cassel 2026-10-22 7:09 ` Damien Le Moal 2026-10-21 20:21 ` [PATCH 2/2] null_blk: don't finish zones to set them read-only or offline Niklas Cassel 1 sibling, 1 reply; 7+ messages in thread From: Niklas Cassel @ 2026-10-21 20:21 UTC (permalink / raw) To: Jens Axboe Cc: Shin'ichiro Kawasaki, Johannes Thumshirn, Damien Le Moal, linux-block, Niklas Cassel When the open zone limit is reached, null_check_open() closes an implicitly open zone only if the active zone limit is not reached. Closing an implicitly open zone does not change the number of active zones, so this check is wrong. For an empty zone, the active zone limit was already checked by null_check_zone_resources(). For a closed zone, the check makes writing to, opening or finishing the zone fail with BLK_STS_ZONE_OPEN_RESOURCE at the active zone limit, whereas ZBC-3 (4.5.3.2.7.2) and NVMe ZNS (2.1.1.4.1) require closing an implicitly open zone instead. Remove the check, and update the comment above null_check_zone_resources() accordingly. Fixes: dc4d137ee3b7 ("null_blk: add support for max open/active zone limit for zoned devices") Signed-off-by: Niklas Cassel <cassel@kernel.org> --- drivers/block/null_blk/zoned.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/block/null_blk/zoned.c b/drivers/block/null_blk/zoned.c index 7e9b5ffb9e84..ecdc8d68ca2a 100644 --- a/drivers/block/null_blk/zoned.c +++ b/drivers/block/null_blk/zoned.c @@ -311,10 +311,8 @@ static blk_status_t null_check_open(struct nullb_device *dev) return BLK_STS_OK; if (dev->nr_zones_imp_open) { - if (null_check_active(dev) == BLK_STS_OK) { - null_close_imp_open_zone(dev); - return BLK_STS_OK; - } + null_close_imp_open_zone(dev); + return BLK_STS_OK; } return BLK_STS_ZONE_OPEN_RESOURCE; @@ -330,8 +328,11 @@ static blk_status_t null_check_open(struct nullb_device *dev) * * ZBC states that an implicit open zone shall be closed only if there is not * room within the open limit. However, with the addition of an active limit, - * it is not certain that closing an implicit open zone will allow a new zone - * to be opened, since we might already be at the active limit capacity. + * it is not certain that closing an implicit open zone will allow an empty + * zone to be opened, since we might already be at the active limit capacity. + * Therefore, the active limit is checked first for an empty zone. A closed + * zone already holds an active zone resource, so only the open limit has to + * be checked for a closed zone. */ static blk_status_t null_check_zone_resources(struct nullb_device *dev, struct nullb_zone *zone) -- 2.56.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] null_blk: fix opening closed zones at the active zone limit 2026-10-21 20:21 ` [PATCH 1/2] null_blk: fix opening closed zones at the active zone limit Niklas Cassel @ 2026-10-22 7:09 ` Damien Le Moal 0 siblings, 0 replies; 7+ messages in thread From: Damien Le Moal @ 2026-10-22 7:09 UTC (permalink / raw) To: Niklas Cassel, Jens Axboe Cc: Shin'ichiro Kawasaki, Johannes Thumshirn, linux-block On 2026/10/21 22:21, Niklas Cassel wrote: > When the open zone limit is reached, null_check_open() closes an > implicitly open zone only if the active zone limit is not reached. > > Closing an implicitly open zone does not change the number of active > zones, so this check is wrong. For an empty zone, the active zone limit > was already checked by null_check_zone_resources(). For a closed zone, > the check makes writing to, opening or finishing the zone fail with > BLK_STS_ZONE_OPEN_RESOURCE at the active zone limit, whereas ZBC-3 > (4.5.3.2.7.2) and NVMe ZNS (2.1.1.4.1) require closing an implicitly > open zone instead. > > Remove the check, and update the comment above > null_check_zone_resources() accordingly. > > Fixes: dc4d137ee3b7 ("null_blk: add support for max open/active zone limit for zoned devices") > Signed-off-by: Niklas Cassel <cassel@kernel.org> Looks good. Reviewed-by: Damien Le Moal <dlemoal@kernel.org> -- Damien Le Moal Western Digital Research ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/2] null_blk: don't finish zones to set them read-only or offline 2026-10-21 20:21 [PATCH 0/2] null_blk: zone resource management fixes Niklas Cassel 2026-10-21 20:21 ` [PATCH 1/2] null_blk: fix opening closed zones at the active zone limit Niklas Cassel @ 2026-10-21 20:21 ` Niklas Cassel 2026-10-22 7:15 ` Damien Le Moal 1 sibling, 1 reply; 7+ messages in thread From: Niklas Cassel @ 2026-10-21 20:21 UTC (permalink / raw) To: Jens Axboe Cc: Shin'ichiro Kawasaki, Johannes Thumshirn, Damien Le Moal, linux-block, Niklas Cassel null_set_zone_cond() calls null_finish_zone() to release the zone resources held by a zone before setting it read-only or offline. For an empty or closed zone, null_finish_zone() first runs the zone resource checks, which can close an unrelated implicitly open zone, or fail. As the error is ignored, a failure for a closed zone leaks nr_zones_closed, permanently lowering the effective active zone limit. Setting a zone read-only or offline requires no zone resources, so release the zone resources held by the zone directly instead, using a new helper, null_release_zone_resources(). Fixes: d3a5738849e0 ("null_blk: support read-only and offline zone conditions") Signed-off-by: Niklas Cassel <cassel@kernel.org> --- drivers/block/null_blk/zoned.c | 35 +++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/drivers/block/null_blk/zoned.c b/drivers/block/null_blk/zoned.c index ecdc8d68ca2a..015f5d304c7c 100644 --- a/drivers/block/null_blk/zoned.c +++ b/drivers/block/null_blk/zoned.c @@ -743,6 +743,33 @@ blk_status_t null_process_zoned_cmd(struct nullb_cmd *cmd, enum req_op op, } } +/* + * Release the zone resources held by a zone, before changing the condition of + * the zone to a condition that does not hold any zone resources. + */ +static void null_release_zone_resources(struct nullb_device *dev, + struct nullb_zone *zone) +{ + if (!dev->need_zone_res_mgmt) + return; + + spin_lock(&dev->zone_res_lock); + switch (zone->cond) { + case BLK_ZONE_COND_IMP_OPEN: + dev->nr_zones_imp_open--; + break; + case BLK_ZONE_COND_EXP_OPEN: + dev->nr_zones_exp_open--; + break; + case BLK_ZONE_COND_CLOSED: + dev->nr_zones_closed--; + break; + default: + break; + } + spin_unlock(&dev->zone_res_lock); +} + /* * Set a zone in the read-only or offline condition. */ @@ -759,8 +786,8 @@ static void null_set_zone_cond(struct nullb_device *dev, * If the read-only condition is requested again to zones already in * read-only condition, restore back normal empty condition. Do the same * if the offline condition is requested for offline zones. Otherwise, - * set the specified zone condition to the zones. Finish the zones - * beforehand to free up zone resources. + * set the specified zone condition to the zones. Release the zone + * resources held by the zones beforehand. */ if (zone->cond == cond) { zone->cond = BLK_ZONE_COND_EMPTY; @@ -768,9 +795,7 @@ static void null_set_zone_cond(struct nullb_device *dev, if (dev->memory_backed) null_handle_discard(dev, zone->start, zone->len); } else { - if (zone->cond != BLK_ZONE_COND_READONLY && - zone->cond != BLK_ZONE_COND_OFFLINE) - null_finish_zone(dev, zone); + null_release_zone_resources(dev, zone); zone->cond = cond; zone->wp = NULL_ZONE_INVALID_WP; } -- 2.56.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] null_blk: don't finish zones to set them read-only or offline 2026-10-21 20:21 ` [PATCH 2/2] null_blk: don't finish zones to set them read-only or offline Niklas Cassel @ 2026-10-22 7:15 ` Damien Le Moal 2026-10-22 7:36 ` Niklas Cassel 0 siblings, 1 reply; 7+ messages in thread From: Damien Le Moal @ 2026-10-22 7:15 UTC (permalink / raw) To: Niklas Cassel, Jens Axboe Cc: Shin'ichiro Kawasaki, Johannes Thumshirn, linux-block On 2026/10/21 22:21, Niklas Cassel wrote: > null_set_zone_cond() calls null_finish_zone() to release the zone > resources held by a zone before setting it read-only or offline. > > For an empty or closed zone, null_finish_zone() first runs the zone > resource checks, which can close an unrelated implicitly open zone, or > fail. As the error is ignored, a failure for a closed zone leaks > nr_zones_closed, permanently lowering the effective active zone limit. > > Setting a zone read-only or offline requires no zone resources, so > release the zone resources held by the zone directly instead, using a > new helper, null_release_zone_resources(). > > Fixes: d3a5738849e0 ("null_blk: support read-only and offline zone conditions") > Signed-off-by: Niklas Cassel <cassel@kernel.org> Looks good, modulo one nit below. Reviewed-by: Damien Le Moal <dlemoal@kernel.org> > --- > drivers/block/null_blk/zoned.c | 35 +++++++++++++++++++++++++++++----- > 1 file changed, 30 insertions(+), 5 deletions(-) > > diff --git a/drivers/block/null_blk/zoned.c b/drivers/block/null_blk/zoned.c > index ecdc8d68ca2a..015f5d304c7c 100644 > --- a/drivers/block/null_blk/zoned.c > +++ b/drivers/block/null_blk/zoned.c > @@ -743,6 +743,33 @@ blk_status_t null_process_zoned_cmd(struct nullb_cmd *cmd, enum req_op op, > } > } > > +/* > + * Release the zone resources held by a zone, before changing the condition of > + * the zone to a condition that does not hold any zone resources. > + */ > +static void null_release_zone_resources(struct nullb_device *dev, > + struct nullb_zone *zone) > +{ > + if (!dev->need_zone_res_mgmt) > + return; > + > + spin_lock(&dev->zone_res_lock); > + switch (zone->cond) { > + case BLK_ZONE_COND_IMP_OPEN: > + dev->nr_zones_imp_open--; > + break; > + case BLK_ZONE_COND_EXP_OPEN: > + dev->nr_zones_exp_open--; > + break; > + case BLK_ZONE_COND_CLOSED: > + dev->nr_zones_closed--; > + break; > + default: > + break; > + } > + spin_unlock(&dev->zone_res_lock); > +} > + > /* > * Set a zone in the read-only or offline condition. > */ > @@ -759,8 +786,8 @@ static void null_set_zone_cond(struct nullb_device *dev, > * If the read-only condition is requested again to zones already in > * read-only condition, restore back normal empty condition. Do the same > * if the offline condition is requested for offline zones. Otherwise, > - * set the specified zone condition to the zones. Finish the zones > - * beforehand to free up zone resources. > + * set the specified zone condition to the zones. Release the zone > + * resources held by the zones beforehand. > */ > if (zone->cond == cond) { > zone->cond = BLK_ZONE_COND_EMPTY; > @@ -768,9 +795,7 @@ static void null_set_zone_cond(struct nullb_device *dev, This function is called only from zone_cond_store() with cond either BLK_ZONE_COND_READONLY or BLK_ZONE_COND_OFFLINE. Since your change is valid only for these 2 conditions, we really should check that cond is either of the already used values and add a comment, to avoid invalid use of null_set_zone_cond() in the future (without tweaking it). > if (dev->memory_backed) > null_handle_discard(dev, zone->start, zone->len); > } else { > - if (zone->cond != BLK_ZONE_COND_READONLY && > - zone->cond != BLK_ZONE_COND_OFFLINE) > - null_finish_zone(dev, zone); > + null_release_zone_resources(dev, zone); > zone->cond = cond; > zone->wp = NULL_ZONE_INVALID_WP; > } -- Damien Le Moal Western Digital Research ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] null_blk: don't finish zones to set them read-only or offline 2026-10-22 7:15 ` Damien Le Moal @ 2026-10-22 7:36 ` Niklas Cassel 2026-10-22 7:42 ` Damien Le Moal 0 siblings, 1 reply; 7+ messages in thread From: Niklas Cassel @ 2026-10-22 7:36 UTC (permalink / raw) To: Damien Le Moal Cc: Jens Axboe, Shin'ichiro Kawasaki, Johannes Thumshirn, linux-block On Thu, Oct 22, 2026 at 09:15:32AM +0200, Damien Le Moal wrote: > On 2026/10/21 22:21, Niklas Cassel wrote: > > null_set_zone_cond() calls null_finish_zone() to release the zone > > resources held by a zone before setting it read-only or offline. > > > > For an empty or closed zone, null_finish_zone() first runs the zone > > resource checks, which can close an unrelated implicitly open zone, or > > fail. As the error is ignored, a failure for a closed zone leaks > > nr_zones_closed, permanently lowering the effective active zone limit. > > > > Setting a zone read-only or offline requires no zone resources, so > > release the zone resources held by the zone directly instead, using a > > new helper, null_release_zone_resources(). > > > > Fixes: d3a5738849e0 ("null_blk: support read-only and offline zone conditions") > > Signed-off-by: Niklas Cassel <cassel@kernel.org> > > Looks good, modulo one nit below. > > Reviewed-by: Damien Le Moal <dlemoal@kernel.org> (snip) > > @@ -768,9 +795,7 @@ static void null_set_zone_cond(struct nullb_device *dev, > > This function is called only from zone_cond_store() with cond either > BLK_ZONE_COND_READONLY or BLK_ZONE_COND_OFFLINE. Since your change is valid only > for these 2 conditions, we really should check that cond is either of the > already used values and add a comment, to avoid invalid use of > null_set_zone_cond() in the future (without tweaking it). Could you clarify with code what you mean? For a comment, there is one already: https://github.com/torvalds/linux/blob/v7.3/drivers/block/null_blk/zoned.c#L746 For a check that cond is either read-only or offline, there such a check already: https://github.com/torvalds/linux/blob/v7.3/drivers/block/null_blk/zoned.c#L751-L752 Kind regards, Niklas ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] null_blk: don't finish zones to set them read-only or offline 2026-10-22 7:36 ` Niklas Cassel @ 2026-10-22 7:42 ` Damien Le Moal 0 siblings, 0 replies; 7+ messages in thread From: Damien Le Moal @ 2026-10-22 7:42 UTC (permalink / raw) To: Niklas Cassel Cc: Jens Axboe, Shin'ichiro Kawasaki, Johannes Thumshirn, linux-block On 2026/10/22 9:36, Niklas Cassel wrote: > On Thu, Oct 22, 2026 at 09:15:32AM +0200, Damien Le Moal wrote: >> On 2026/10/21 22:21, Niklas Cassel wrote: >>> null_set_zone_cond() calls null_finish_zone() to release the zone >>> resources held by a zone before setting it read-only or offline. >>> >>> For an empty or closed zone, null_finish_zone() first runs the zone >>> resource checks, which can close an unrelated implicitly open zone, or >>> fail. As the error is ignored, a failure for a closed zone leaks >>> nr_zones_closed, permanently lowering the effective active zone limit. >>> >>> Setting a zone read-only or offline requires no zone resources, so >>> release the zone resources held by the zone directly instead, using a >>> new helper, null_release_zone_resources(). >>> >>> Fixes: d3a5738849e0 ("null_blk: support read-only and offline zone conditions") >>> Signed-off-by: Niklas Cassel <cassel@kernel.org> >> >> Looks good, modulo one nit below. >> >> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> > > (snip) > >>> @@ -768,9 +795,7 @@ static void null_set_zone_cond(struct nullb_device *dev, >> >> This function is called only from zone_cond_store() with cond either >> BLK_ZONE_COND_READONLY or BLK_ZONE_COND_OFFLINE. Since your change is valid only >> for these 2 conditions, we really should check that cond is either of the >> already used values and add a comment, to avoid invalid use of >> null_set_zone_cond() in the future (without tweaking it). > > Could you clarify with code what you mean? > > > For a comment, there is one already: > https://github.com/torvalds/linux/blob/v7.3/drivers/block/null_blk/zoned.c#L746 > > For a check that cond is either read-only or offline, there such a check > already: > https://github.com/torvalds/linux/blob/v7.3/drivers/block/null_blk/zoned.c#L751-L752 Ah! I missed that! So please ignore my nit comment. That said, adding a cleanup patch that changes null_set_zone_cond() to something like: static void null_set_zone_readonly_or_offline(struct nullb_device *dev, struct nullb_zone *zone, bool set_offline) would make things a lot clearer :) -- Damien Le Moal Western Digital Research ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-10-22 7:43 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-10-21 20:21 [PATCH 0/2] null_blk: zone resource management fixes Niklas Cassel 2026-10-21 20:21 ` [PATCH 1/2] null_blk: fix opening closed zones at the active zone limit Niklas Cassel 2026-10-22 7:09 ` Damien Le Moal 2026-10-21 20:21 ` [PATCH 2/2] null_blk: don't finish zones to set them read-only or offline Niklas Cassel 2026-10-22 7:15 ` Damien Le Moal 2026-10-22 7:36 ` Niklas Cassel 2026-10-22 7:42 ` Damien Le Moal
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox