hw/block/nvme: fix zone management receive reporting too many zones

nvme_zone_mgmt_recv uses nvme_ns_nlbas() to get the number of LBAs in
the namespace and then calculates the number of zones to report by
incrementing slba with ZSZE until exceeding the number of LBAs as
returned by nvme_ns_nlbas().

This is bad because the namespace might be of such as size that some
LBAs are valid, but are not part of any zone, causing zone management
receive to report one additional (but non-existing) zone.

Fix this with a conventional loop on i < ns->num_zones instead.

Fixes: a479335bfa ("hw/block/nvme: Support Zoned Namespace Command Set")
Cc: Dmitry Fomichev <dmitry.fomichev@wdc.com>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
This commit is contained in:
Klaus Jensen 2021-03-09 15:11:42 +01:00
parent 3921756dee
commit 3754df04ec
1 changed files with 3 additions and 2 deletions

View File

@ -2620,12 +2620,13 @@ static uint16_t nvme_zone_mgmt_recv(NvmeCtrl *n, NvmeRequest *req)
uint32_t zone_idx, zra, zrasf, partial;
uint64_t max_zones, nr_zones = 0;
uint16_t status;
uint64_t slba, capacity = nvme_ns_nlbas(ns);
uint64_t slba;
NvmeZoneDescr *z;
NvmeZone *zone;
NvmeZoneReportHeader *header;
void *buf, *buf_p;
size_t zone_entry_sz;
int i;
req->status = NVME_SUCCESS;
@ -2667,7 +2668,7 @@ static uint16_t nvme_zone_mgmt_recv(NvmeCtrl *n, NvmeRequest *req)
buf = g_malloc0(data_size);
zone = &ns->zone_array[zone_idx];
for (; slba < capacity; slba += ns->zone_size) {
for (i = zone_idx; i < ns->num_zones; i++) {
if (partial && nr_zones >= max_zones) {
break;
}