From 4e9a9c4a22f2bc840e37f0f1a74749bbb7f6392d Mon Sep 17 00:00:00 2001 From: Niklas Cassel Date: Mon, 26 Oct 2020 10:09:39 +0000 Subject: [PATCH] examples/nvme_fio_plugin: fix zone reporting All zone management receive helper functions (including spdk_nvme_zns_report_zones()) are implemented to match the parameters of the zone management receive function in the ZNS specification. The documentation for spdk_nvme_zns_report_zones() states: "param partial_report If true, nr_zones field in the zone report indicates the number of zone descriptors that were successfully written to the zone report. If false, nr_zones field in the zone report indicates the number of zone descriptors that match the report_opts criteria." This matches the description of the "Partial Report" bit in the ZNS spec. Since the FIO function parse_zone_info() calls the io_ops->report_zones() function multiple times, until all zones have been reported, it expects the return from this function to represent the number of zones that were successfully reported. By setting the partial_report bit to false, the controller will return the total number of zones, and since spdk_fio_report_zones() loops until idx < report->nr_zones, and writes to zbdz[idx], the current code will overwrite heap memory, since idx will take on index values that are out of bounds for the memory allocated by the FIO function parse_zone_info(). Therefore, spdk_fio_report_zones() has to set the partial_report bit to true when calling the NVMe level function spdk_nvme_zns_report_zones(). Signed-off-by: Niklas Cassel Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4871 (master) (cherry picked from commit 1e83b640aa36f6eac8ec2cde59b6bf5534c0632d) Change-Id: I8846711bfed4faadac0315b450158293cefa36f4 Signed-off-by: Tomasz Zawadzki Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4943 Reviewed-by: Jim Harris Reviewed-by: Shuhei Matsumoto Tested-by: SPDK CI Jenkins --- examples/nvme/fio_plugin/fio_plugin.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/nvme/fio_plugin/fio_plugin.c b/examples/nvme/fio_plugin/fio_plugin.c index 9cda30779..c2041b872 100644 --- a/examples/nvme/fio_plugin/fio_plugin.c +++ b/examples/nvme/fio_plugin/fio_plugin.c @@ -1139,13 +1139,14 @@ spdk_fio_report_zones(struct thread_data *td, struct fio_file *f, uint64_t offse } err = spdk_nvme_zns_report_zones(fio_qpair->ns, fio_qpair->qpair, report, report_nbytes, - offset / lba_nbytes, SPDK_NVME_ZRA_LIST_ALL, false, pcu_cb, + offset / lba_nbytes, SPDK_NVME_ZRA_LIST_ALL, true, pcu_cb, &completed); if (err || pcu(fio_qpair->qpair, &completed) || completed < 0) { log_err("spdk/nvme: report_zones(): err: %d, cpl: %d\n", err, completed); err = err ? err : -EIO; goto exit; } + assert(report->nr_zones <= report_nzones_max); report_nzones = report->nr_zones; for (uint64_t idx = 0; idx < report->nr_zones; ++idx) {