aboutsummaryrefslogtreecommitdiff
path: root/hw/block
diff options
context:
space:
mode:
authorKlaus Jensen <k.jensen@samsung.com>2021-03-09 15:11:42 +0100
committerKlaus Jensen <k.jensen@samsung.com>2021-03-18 12:34:51 +0100
commit3754df04ec291b933c18285210793d02c9d9787a (patch)
tree45125cda78ec8cea50f6f26729fea213c134d7fb /hw/block
parent3921756dee6dd7beb7b60167f368e8b981c77365 (diff)
downloadqemu-3754df04ec291b933c18285210793d02c9d9787a.zip
qemu-3754df04ec291b933c18285210793d02c9d9787a.tar.gz
qemu-3754df04ec291b933c18285210793d02c9d9787a.tar.bz2
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: a479335bfaf3 ("hw/block/nvme: Support Zoned Namespace Command Set") Cc: Dmitry Fomichev <dmitry.fomichev@wdc.com> Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
Diffstat (limited to 'hw/block')
-rw-r--r--hw/block/nvme.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 0d9b980..9a14c5f 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -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;
}