* [PATCH] ublk: stop reporting zones on an empty response
@ 2026-11-09 14:51 shao.mingyin
2026-11-10 1:27 ` Ming Lei
0 siblings, 1 reply; 3+ messages in thread
From: shao.mingyin @ 2026-11-09 14:51 UTC (permalink / raw)
To: tom.leiming, linux-block; +Cc: axboe, linux-kernel
From: Shao Mingyin <shao.mingyin@zte.com.cn>
ublk_report_zones() treats a zero-length zone as the end of a server
response, but only breaks out of the inner loop. If the server returns
an empty report, done_zones and sector do not advance, so the driver
keeps issuing REPORT ZONES requests at the same sector indefinitely.
Finish the report when the zero-length marker is encountered and return
the number of zones already reported. Use the existing exit path to
release the report buffer, including when the first response is empty.
Fixes: 29802d7ca33b ("ublk: enable zoned storage support")
Cc: stable@vger.kernel.org
Signed-off-by: Shao Mingyin <shao.mingyin@zte.com.cn>
---
drivers/block/ublk_drv.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index 3d322fa1bc83..5c14daeaebbf 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -693,8 +693,10 @@ static int ublk_report_zones(struct gendisk *disk, sector_t sector,
struct blk_zone *zone = buffer + i;
/* A zero length zone means no more zones in this response */
- if (!zone->len)
- break;
+ if (!zone->len) {
+ ret = done_zones;
+ goto out;
+ }
ret = disk_report_zone(disk, zone, done_zones, args);
if (ret)
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] ublk: stop reporting zones on an empty response 2026-11-09 14:51 [PATCH] ublk: stop reporting zones on an empty response shao.mingyin @ 2026-11-10 1:27 ` Ming Lei 2026-11-10 3:00 ` shao.mingyin 0 siblings, 1 reply; 3+ messages in thread From: Ming Lei @ 2026-11-10 1:27 UTC (permalink / raw) To: shao.mingyin; +Cc: linux-block, axboe, linux-kernel On Mon, Nov 09, 2026 at 10:51:10PM +0800, shao.mingyin@zte.com.cn wrote: > From: Shao Mingyin <shao.mingyin@zte.com.cn> > > ublk_report_zones() treats a zero-length zone as the end of a server > response, but only breaks out of the inner loop. If the server returns > an empty report, done_zones and sector do not advance, so the driver > keeps issuing REPORT ZONES requests at the same sector indefinitely. > > Finish the report when the zero-length marker is encountered and return > the number of zones already reported. Use the existing exit path to > release the report buffer, including when the first response is empty. The issue is real, I can reproduce it with one ublk server which completes UBLK_IO_OP_REPORT_ZONES without filling any zone: both BLKREPORTZONE and START_DEV(blk_revalidate_disk_zones()) loop forever, and the task can't be killed. > > Fixes: 29802d7ca33b ("ublk: enable zoned storage support") > Cc: stable@vger.kernel.org > Signed-off-by: Shao Mingyin <shao.mingyin@zte.com.cn> > --- > drivers/block/ublk_drv.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c > index 3d322fa1bc83..5c14daeaebbf 100644 > --- a/drivers/block/ublk_drv.c > +++ b/drivers/block/ublk_drv.c > @@ -693,8 +693,10 @@ static int ublk_report_zones(struct gendisk *disk, sector_t sector, > struct blk_zone *zone = buffer + i; > > /* A zero length zone means no more zones in this response */ > - if (!zone->len) > - break; > + if (!zone->len) { > + ret = done_zones; > + goto out; > + } But this terminates the whole report on any zero-length zone, not only on an empty response. A zero-length zone means "no more zones in this response", and so far the driver continues from the advanced sector and asks for the remaining zones. With this patch, a server returning fewer zones than requested gets a truncated report. For example, when the server fills half of the requested zones each time: - BLKREPORTZONE for 256 zones returns 128 zones - START_DEV fails: ublkb0: last zone and capacity mismatch (1048576 != 2097152) ublkb0: failed to revalidate zones Both work fine before this patch. How about stopping only if the response doesn't carry any zone? That is what sd_zbc and virtio_blk do too. Something like: diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -661,6 +661,7 @@ static int ublk_report_zones(struct gendisk *disk, sector_t sector, struct request *req; struct ublk_zoned_report_desc desc; blk_status_t status; + unsigned int i; memset(buffer, 0, buffer_length); @@ -689,7 +690,7 @@ static int ublk_report_zones(struct gendisk *disk, sector_t sector, if (ret) goto out; - for (unsigned int i = 0; i < zones_in_request; i++) { + for (i = 0; i < zones_in_request; i++) { struct blk_zone *zone = buffer + i; /* A zero length zone means no more zones in this response */ @@ -704,6 +705,10 @@ static int ublk_report_zones(struct gendisk *disk, sector_t sector, sector += zone_size_sectors; } + + /* empty response: no progress, don't ask again */ + if (!i) + break; } ret = done_zones; With the above, empty response is handled as in your patch (BLKREPORTZONE returns 0 zones, START_DEV fails with "No zones reported"), and partial response still works. Thanks, Ming ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] ublk: stop reporting zones on an empty response 2026-11-10 1:27 ` Ming Lei @ 2026-11-10 3:00 ` shao.mingyin 0 siblings, 0 replies; 3+ messages in thread From: shao.mingyin @ 2026-11-10 3:00 UTC (permalink / raw) To: tom.leiming; +Cc: axboe, linux-block, linux-kernel On Mon, Nov 09, 2026 at 07:27:52PM -0600, Ming Lei wrote: > The issue is real, I can reproduce it with one ublk server which > completes UBLK_IO_OP_REPORT_ZONES without filling any zone: both > BLKREPORTZONE and START_DEV(blk_revalidate_disk_zones()) loop forever, > and the task can't be killed. Thanks for reproducing it against a real server. > But this terminates the whole report on any zero-length zone, not only > on an empty response. You're right, that is a regression I introduced. The zero-length entry marks the end of this response, and the driver is supposed to ask for the rest from the advanced sector. The UAPI says as much: "nr_zones" is an upper bound, and reporting fewer zones is done by zeroing the last entry. For BLKREPORTZONE the truncation is silent too: the ioctl still returns 0 and just reports 128 of the 256 requested zones, while START_DEV fails in the last-zone/capacity check. > How about stopping only if the response doesn't carry any zone? That is > what sd_zbc and virtio_blk do too. Taking that shape. v2 keeps the loop index outside the inner for and stops the outer loop only when the response carried no zone at all, so a short but non-empty response is still followed up as before. I'll keep the Fixes: and stable tags and add your Suggested-by. v2 will follow as a separate thread. Thanks, Shao Mingyin ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-11-10 3:01 UTC | newest] Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-11-09 14:51 [PATCH] ublk: stop reporting zones on an empty response shao.mingyin 2026-11-10 1:27 ` Ming Lei 2026-11-10 3:00 ` shao.mingyin
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®