From 6197903bd42478987516bc4cc3f0769488a37065 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 14 Jul 2022 20:27:59 +0200 Subject: Adding upstream version 2.0. Signed-off-by: Daniel Baumann --- plugins/zns/zns.c | 461 ++++++++++++++++++++++++++++++++++++++++++++---------- plugins/zns/zns.h | 29 ++-- 2 files changed, 391 insertions(+), 99 deletions(-) (limited to 'plugins/zns') diff --git a/plugins/zns/zns.c b/plugins/zns/zns.c index 2f765b6..56e53af 100644 --- a/plugins/zns/zns.c +++ b/plugins/zns/zns.c @@ -7,15 +7,110 @@ #include #include +#include "common.h" #include "nvme.h" -#include "nvme-ioctl.h" +#include "libnvme.h" #include "nvme-print.h" -#include "nvme-status.h" #define CREATE_CMD #include "zns.h" static const char *namespace_id = "Namespace identifier to use"; +static const char dash[100] = { [0 ... 99] = '-' }; + +static int detect_zns(nvme_ns_t ns, int *out_supported) +{ + int err = 0; + char *zoned; + + *out_supported = 0; + + zoned = nvme_get_attr(nvme_ns_get_sysfs_dir(ns), "queue/zoned"); + if (!zoned) { + *out_supported = 0; + return err; + } + + *out_supported = strcmp("host-managed", zoned) == 0; + free(zoned); + + return err; +} + +static int print_zns_list_ns(nvme_ns_t ns) +{ + int supported; + int err = 0; + + err = detect_zns(ns, &supported); + if (err) { + perror("Failed to enumerate namespace"); + return err; + } + + if (supported) { + nvme_show_list_item(ns); + } + + return err; +} + +static int print_zns_list(nvme_root_t nvme_root) +{ + int err = 0; + nvme_host_t h; + nvme_subsystem_t s; + nvme_ctrl_t c; + nvme_ns_t n; + nvme_for_each_host(nvme_root, h) + { + nvme_for_each_subsystem(h, s) + { + nvme_subsystem_for_each_ns(s, n) + { + err = print_zns_list_ns(n); + if (err) + return err; + } + + nvme_subsystem_for_each_ctrl(s, c) + { + nvme_ctrl_for_each_ns(c, n) + { + err = print_zns_list_ns(n); + if (err) + return err; + } + } + } + } + + return err; +} + +static int list(int argc, char **argv, struct command *cmd, + struct plugin *plugin) +{ + int err = 0; + nvme_root_t nvme_root; + + printf("%-21s %-20s %-40s %-9s %-26s %-16s %-8s\n", "Node", "SN", + "Model", "Namespace", "Usage", "Format", "FW Rev"); + printf("%-.21s %-.20s %-.40s %-.9s %-.26s %-.16s %-.8s\n", dash, dash, + dash, dash, dash, dash, dash); + + nvme_root = nvme_scan(NULL); + if (nvme_root) { + err = print_zns_list(nvme_root); + } else { + fprintf(stderr, "Failed to scan nvme subsystems\n"); + err = -errno; + } + + nvme_free_tree(nvme_root); + + return err; +} static int id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin) { @@ -57,7 +152,7 @@ static int id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *pl perror("zns identify controller"); close_fd: close(fd); - return nvme_status_to_errno(err, false); + return err; } static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plugin) @@ -76,8 +171,8 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug struct config { char *output_format; __u32 namespace_id; - int human_readable; - int vendor_specific; + bool human_readable; + bool vendor_specific; }; struct config cfg = { @@ -105,14 +200,14 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug flags |= VERBOSE; if (!cfg.namespace_id) { - err = cfg.namespace_id = nvme_get_nsid(fd); + err = nvme_get_nsid(fd, &cfg.namespace_id); if (err < 0) { perror("get-namespace-id"); goto close_fd; } } - err = nvme_identify_ns(fd, cfg.namespace_id, false, &id_ns); + err = nvme_identify_ns(fd, cfg.namespace_id, &id_ns); if (err) { nvme_show_status(err); goto close_fd; @@ -127,18 +222,6 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug perror("zns identify namespace"); close_fd: close(fd); - return nvme_status_to_errno(err, false); -} - -static int __zns_mgmt_send(int fd, __u32 namespace_id, __u64 zslba, - bool select_all, __u32 timeout, enum nvme_zns_send_action zsa, - __u32 data_len, void *buf) -{ - int err; - - err = nvme_zns_mgmt_send(fd, namespace_id, zslba, select_all, timeout, zsa, - data_len, buf); - close(fd); return err; } @@ -149,8 +232,9 @@ static int zns_mgmt_send(int argc, char **argv, struct command *cmd, struct plug const char *select_all = "send command to all zones"; const char *timeout = "timeout value, in milliseconds"; - int err, fd; + int err, fd, zcapc = 0; char *command; + __u32 result; struct config { __u64 zslba; @@ -171,26 +255,42 @@ static int zns_mgmt_send(int argc, char **argv, struct command *cmd, struct plug err = fd = parse_and_open(argc, argv, desc, opts); if (fd < 0) - return errno; + goto ret; err = asprintf(&command, "%s-%s", plugin->name, cmd->name); if (err < 0) goto close_fd; if (!cfg.namespace_id) { - err = cfg.namespace_id = nvme_get_nsid(fd); + err = nvme_get_nsid(fd, &cfg.namespace_id); if (err < 0) { perror("get-namespace-id"); goto free; } } - err = __zns_mgmt_send(fd, cfg.namespace_id, cfg.zslba, - cfg.select_all, cfg.timeout, zsa, 0, NULL); - if (!err) - printf("%s: Success, action:%d zone:%"PRIx64" all:%d nsid:%d\n", + struct nvme_zns_mgmt_send_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = cfg.namespace_id, + .slba = cfg.zslba, + .zsa = zsa, + .select_all = cfg.select_all, + .zsaso = 0, + .data_len = 0, + .data = NULL, + .timeout = cfg.timeout, + .result = &result, + }; + err = nvme_zns_mgmt_send(&args); + if (!err) { + if (zsa == NVME_ZNS_ZSA_RESET) + zcapc = result & 0x1; + + printf("%s: Success, action:%d zone:%"PRIx64" all:%d zcapc:%u nsid:%d\n", command, zsa, (uint64_t)cfg.zslba, (int)cfg.select_all, - cfg.namespace_id); + zcapc, cfg.namespace_id); + } else if (err > 0) nvme_show_status(err); else @@ -199,7 +299,8 @@ free: free(command); close_fd: close(fd); - return nvme_status_to_errno(err, false); +ret: + return err; } static int get_zdes_bytes(int fd, __u32 nsid) @@ -209,7 +310,7 @@ static int get_zdes_bytes(int fd, __u32 nsid) __u8 lbaf; int err; - err = nvme_identify_ns(fd, nsid, false, &id_ns); + err = nvme_identify_ns(fd, nsid, &id_ns); if (err > 0) { nvme_show_status(err); return -1; @@ -227,14 +328,16 @@ static int get_zdes_bytes(int fd, __u32 nsid) return -1; } - lbaf = id_ns.flbas & NVME_NS_FLBAS_LBA_MASK; + nvme_id_ns_flbas_to_lbaf_inuse(id_ns.flbas, &lbaf); return ns.lbafe[lbaf].zdes << 6; } static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plugin *plugin) { const char *desc = "Zone Management Send"; - const char *zslba = "starting LBA of the zone for this command"; + const char *zslba = "starting LBA of the zone for this command"\ + "(for flush action, last lba to flush)"; + const char *zsaso = "Zone Send Action Specific Option"; const char *select_all = "send command to all zones"; const char *zsa = "zone send action"; const char *data_len = "buffer length if data required"; @@ -247,6 +350,7 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu struct config { __u64 zslba; __u32 namespace_id; + bool zsaso; bool select_all; __u8 zsa; int data_len; @@ -259,6 +363,7 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu OPT_ARGS(opts) = { OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id), OPT_SUFFIX("start-lba", 's', &cfg.zslba, zslba), + OPT_FLAG("zsaso", 'o', &cfg.zsaso, zsaso), OPT_FLAG("select-all", 'a', &cfg.select_all, select_all), OPT_BYTE("zsa", 'z', &cfg.zsa, zsa), OPT_UINT("data-len", 'l', &cfg.data_len, data_len), @@ -272,7 +377,7 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu return errno; if (!cfg.namespace_id) { - err = cfg.namespace_id = nvme_get_nsid(fd); + err = nvme_get_nsid(fd, &cfg.namespace_id); if (err < 0) { perror("get-namespace-id"); goto close_fd; @@ -287,15 +392,17 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu if (cfg.zsa == NVME_ZNS_ZSA_SET_DESC_EXT) { if(!cfg.data_len) { - cfg.data_len = get_zdes_bytes(fd, cfg.namespace_id); - if (!cfg.data_len || cfg.data_len < 0) { + int data_len = get_zdes_bytes(fd, cfg.namespace_id); + + if (data_len == 0) { fprintf(stderr, "Zone Descriptor Extensions are not supported\n"); goto close_fd; - } else if (cfg.data_len < 0) { - err = cfg.data_len; + } else if (data_len < 0) { + err = data_len; goto close_fd; } + cfg.data_len = data_len; } if (posix_memalign(&buf, getpagesize(), cfg.data_len)) { fprintf(stderr, "can not allocate feature payload\n"); @@ -325,8 +432,20 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu } } - err = __zns_mgmt_send(fd, cfg.namespace_id, cfg.zslba, cfg.select_all, - cfg.timeout, cfg.zsa, cfg.data_len, buf); + struct nvme_zns_mgmt_send_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = cfg.namespace_id, + .slba = cfg.zslba, + .zsa = cfg.zsa, + .select_all = cfg.select_all, + .zsaso = cfg.zsaso, + .data_len = cfg.data_len, + .data = buf, + .timeout = cfg.timeout, + .result = NULL, + }; + err = nvme_zns_mgmt_send(&args); if (!err) printf("zone-mgmt-send: Success, action:%d zone:%"PRIx64" " "all:%d nsid:%d\n", @@ -344,7 +463,7 @@ free: free(buf); close_fd: close(fd); - return nvme_status_to_errno(err, false); + return err; } static int close_zone(int argc, char **argv, struct command *cmd, struct plugin *plugin) @@ -364,8 +483,67 @@ static int finish_zone(int argc, char **argv, struct command *cmd, struct plugin static int open_zone(int argc, char **argv, struct command *cmd, struct plugin *plugin) { const char *desc = "Open zones\n"; + const char *zslba = "starting LBA of the zone for this command"; + const char *zrwaa = "Allocate Zone Random Write Area to zone"; + const char *select_all = "send command to all zones"; + const char *timeout = "timeout value, in milliseconds"; + + int err, fd; + + struct config { + __u64 zslba; + __u32 namespace_id; + bool zrwaa; + bool select_all; + __u32 timeout; + }; + + struct config cfg = { + }; + + OPT_ARGS(opts) = { + OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id), + OPT_SUFFIX("start-lba", 's', &cfg.zslba, zslba), + OPT_FLAG("zrwaa", 'r', &cfg.zrwaa, zrwaa), + OPT_FLAG("select-all", 'a', &cfg.select_all, select_all), + OPT_UINT("timeout", 't', &cfg.timeout, timeout), + OPT_END() + }; + + fd = parse_and_open(argc, argv, desc, opts); + if (fd < 0) + return errno; + + if (!cfg.namespace_id) { + err = nvme_get_nsid(fd, &cfg.namespace_id); + if (err < 0) { + perror("get-namespace-id"); + goto close_fd; + } + } - return zns_mgmt_send(argc, argv, cmd, plugin, desc, NVME_ZNS_ZSA_OPEN); + struct nvme_zns_mgmt_send_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = cfg.namespace_id, + .slba = cfg.zslba, + .zsa = NVME_ZNS_ZSA_OPEN, + .select_all = cfg.select_all, + .zsaso = cfg.zrwaa, + .data_len = 0, + .data = NULL, + .timeout = cfg.timeout, + .result = NULL, + }; + err = nvme_zns_mgmt_send(&args); + if (!err) + printf("zns-open-zone: Success zone slba:%"PRIx64" nsid:%d\n", + (uint64_t)cfg.zslba, cfg.namespace_id); + else + nvme_show_status(err); +close_fd: + close(fd); + return err; } static int reset_zone(int argc, char **argv, struct command *cmd, struct plugin *plugin) @@ -386,15 +564,17 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug { const char *desc = "Set Zone Descriptor Extension\n"; const char *zslba = "starting LBA of the zone for this command"; + const char *zrwaa = "Allocate Zone Random Write Area to zone"; const char *data = "optional file for zone extention data (default stdin)"; const char *timeout = "timeout value, in milliseconds"; int fd, ffd = STDIN_FILENO, err; void *buf = NULL; - __u32 data_len; + int data_len; struct config { __u64 zslba; + bool zrwaa; __u32 namespace_id; char *file; __u32 timeout; @@ -405,6 +585,7 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug OPT_ARGS(opts) = { OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id), OPT_SUFFIX("start-lba", 's', &cfg.zslba, zslba), + OPT_FLAG("zrwaa", 'r', &cfg.zrwaa, zrwaa), OPT_FILE("data", 'd', &cfg.file, data), OPT_UINT("timeout", 't', &cfg.timeout, timeout), OPT_END() @@ -415,7 +596,7 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug return errno; if (!cfg.namespace_id) { - err = cfg.namespace_id = nvme_get_nsid(fd); + err = nvme_get_nsid(fd, &cfg.namespace_id); if (err < 0) { perror("get-namespace-id"); goto close_fd; @@ -454,8 +635,20 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug goto close_ffd; } - err = __zns_mgmt_send(fd, cfg.namespace_id, cfg.zslba, 0, cfg.timeout, - NVME_ZNS_ZSA_SET_DESC_EXT, data_len, buf); + struct nvme_zns_mgmt_send_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = cfg.namespace_id, + .slba = cfg.zslba, + .zsa = NVME_ZNS_ZSA_SET_DESC_EXT, + .select_all = 0, + .zsaso = cfg.zrwaa, + .data_len = data_len, + .data = buf, + .timeout = cfg.timeout, + .result = NULL, + }; + err = nvme_zns_mgmt_send(&args); if (!err) printf("set-zone-desc: Success, zone:%"PRIx64" nsid:%d\n", (uint64_t)cfg.zslba, cfg.namespace_id); @@ -470,7 +663,67 @@ free: free(buf); close_fd: close(fd); - return nvme_status_to_errno(err, false); + return err; +} + + +static int zrwa_flush_zone(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + const char *desc = "Flush Explicit ZRWA Range"; + const char *slba = "LBA to flush up to"; + const char *timeout = "timeout value, in milliseconds"; + + int err, fd; + + struct config { + __u64 lba; + __u32 namespace_id; + __u32 timeout; + }; + + struct config cfg = {}; + + OPT_ARGS(opts) = { + OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id), + OPT_SUFFIX("lba", 'l', &cfg.lba, slba), + OPT_UINT("timeout", 't', &cfg.timeout, timeout), + OPT_END() + }; + + fd = parse_and_open(argc, argv, desc, opts); + if (fd < 0) + return errno; + + if (!cfg.namespace_id) { + err = nvme_get_nsid(fd, &cfg.namespace_id); + if (err < 0) { + perror("get-namespace-id"); + goto close_fd; + } + } + + struct nvme_zns_mgmt_send_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = cfg.namespace_id, + .slba = cfg.lba, + .zsa = NVME_ZNS_ZSA_ZRWA_FLUSH, + .select_all = 0, + .zsaso = 0, + .data_len = 0, + .data = NULL, + .timeout = cfg.timeout, + .result = NULL, + }; + err = nvme_zns_mgmt_send(&args); + if (!err) + printf("zrwa-flush-zone: Success, lba:%"PRIx64" nsid:%d\n", + (uint64_t)cfg.lba, cfg.namespace_id); + else + nvme_show_status(err); +close_fd: + close(fd); + return err; } static int zone_mgmt_recv(int argc, char **argv, struct command *cmd, struct plugin *plugin) @@ -520,7 +773,7 @@ static int zone_mgmt_recv(int argc, char **argv, struct command *cmd, struct plu goto close_fd; if (!cfg.namespace_id) { - err = cfg.namespace_id = nvme_get_nsid(fd); + err = nvme_get_nsid(fd, &cfg.namespace_id); if (err < 0) { perror("get-namespace-id"); goto close_fd; @@ -541,8 +794,20 @@ static int zone_mgmt_recv(int argc, char **argv, struct command *cmd, struct plu } } - err = nvme_zns_mgmt_recv(fd, cfg.namespace_id, cfg.zslba, cfg.zra, - cfg.zrasf, cfg.partial, cfg.data_len, data); + struct nvme_zns_mgmt_recv_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = cfg.namespace_id, + .slba = cfg.zslba, + .zra = cfg.zra, + .zrasf = cfg.zrasf, + .zras_feat = cfg.partial, + .data_len = cfg.data_len, + .data = data, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + err = nvme_zns_mgmt_recv(&args); if (!err) printf("zone-mgmt-recv: Success, action:%d zone:%"PRIx64" nsid:%d\n", cfg.zra, (uint64_t)cfg.zslba, cfg.namespace_id); @@ -554,7 +819,7 @@ static int zone_mgmt_recv(int argc, char **argv, struct command *cmd, struct plu free(data); close_fd: close(fd); - return nvme_status_to_errno(err, false); + return err; } static int report_zones(int argc, char **argv, struct command *cmd, struct plugin *plugin) @@ -584,6 +849,7 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi struct nvme_id_ns id_ns; uint8_t lbaf; __le64 zsze; + struct json_object *zone_list = 0; struct config { char *output_format; @@ -591,7 +857,7 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi __u32 namespace_id; int num_descs; int state; - int verbose; + bool verbose; bool extended; bool partial; }; @@ -624,7 +890,7 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi flags |= VERBOSE; if (!cfg.namespace_id) { - err = cfg.namespace_id = nvme_get_nsid(fd); + err = nvme_get_nsid(fd, &cfg.namespace_id); if (err < 0) { perror("get-namespace-id"); goto close_fd; @@ -639,7 +905,7 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi } } - err = nvme_identify_ns(fd, cfg.namespace_id, false, &id_ns); + err = nvme_identify_ns(fd, cfg.namespace_id, &id_ns); if (err) { nvme_show_status(err); goto close_fd; @@ -648,7 +914,7 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi err = nvme_zns_identify_ns(fd, cfg.namespace_id, &id_zns); if (!err) { /* get zsze field from zns id ns data - needed for offset calculation */ - lbaf = id_ns.flbas & NVME_NS_FLBAS_LBA_MASK; + nvme_id_ns_flbas_to_lbaf_inuse(id_ns.flbas, &lbaf); zsze = le64_to_cpu(id_zns.lbafe[lbaf].zsze); } else { @@ -664,7 +930,9 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi } err = nvme_zns_report_zones(fd, cfg.namespace_id, 0, - 0, cfg.state, 0, log_len, buff); + cfg.state, false, false, + log_len, buff, + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); if (err > 0) { nvme_show_status(err); goto free_buff; @@ -695,7 +963,10 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi } offset = cfg.zslba; - printf("nr_zones: %"PRIu64"\n", (uint64_t)le64_to_cpu(total_nr_zones)); + if (flags & JSON) + zone_list = json_create_array(); + else + printf("nr_zones: %"PRIu64"\n", (uint64_t)le64_to_cpu(total_nr_zones)); while (nr_zones_retrieved < nr_zones) { if (nr_zones_retrieved >= nr_zones) @@ -707,27 +978,32 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi } err = nvme_zns_report_zones(fd, cfg.namespace_id, offset, - cfg.extended, cfg.state, cfg.partial, log_len, report); + cfg.state, cfg.extended, + cfg.partial, log_len, report, + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); if (err > 0) { nvme_show_status(err); break; } if (!err) - nvme_show_zns_report_zones(report, nr_zones_chunks, zdes, - log_len, flags); + nvme_show_zns_report_zones(report, nr_zones_chunks, + zdes, log_len, flags, zone_list); nr_zones_retrieved += nr_zones_chunks; offset = (nr_zones_retrieved * zsze); } + if (flags & JSON) + json_nvme_finish_zone_list(total_nr_zones, zone_list); + nvme_free(report, huge); free_buff: free(buff); close_fd: close(fd); - return nvme_status_to_errno(err, false); + return err; } static int zone_append(int argc, char **argv, struct command *cmd, struct plugin *plugin) @@ -754,6 +1030,7 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin void *buf = NULL, *mbuf = NULL; __u16 nblocks, control = 0; __u64 result; + __u8 lba_index; struct timeval start_time, end_time; struct nvme_id_ns ns; @@ -764,15 +1041,15 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin __u64 zslba; __u64 data_size; __u64 metadata_size; - int limited_retry; - int fua; + bool limited_retry; + bool fua; __u32 namespace_id; __u32 ref_tag; __u16 lbat; __u16 lbatm; __u8 prinfo; - int piremap; - int latency; + bool piremap; + bool latency; }; struct config cfg = {}; @@ -806,49 +1083,50 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin } if (!cfg.namespace_id) { - err = cfg.namespace_id = nvme_get_nsid(fd); + err = nvme_get_nsid(fd, &cfg.namespace_id); if (err < 0) { perror("get-namespace-id"); goto close_fd; } } - err = nvme_identify_ns(fd, cfg.namespace_id, false, &ns); + err = nvme_identify_ns(fd, cfg.namespace_id, &ns); if (err) { nvme_show_status(err); goto close_fd; } - lba_size = 1 << ns.lbaf[(ns.flbas & 0x0f)].ds; + nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &lba_index); + lba_size = 1 << ns.lbaf[lba_index].ds; if (cfg.data_size & (lba_size - 1)) { fprintf(stderr, "Data size:%#"PRIx64" not aligned to lba size:%#x\n", (uint64_t)cfg.data_size, lba_size); errno = EINVAL; - goto close_ns; + goto close_fd; } - meta_size = ns.lbaf[(ns.flbas & 0x0f)].ms; + meta_size = ns.lbaf[lba_index].ms; if (meta_size && !(meta_size == 8 && (cfg.prinfo & 0x8)) && (!cfg.metadata_size || cfg.metadata_size % meta_size)) { fprintf(stderr, "Metadata size:%#"PRIx64" not aligned to metadata size:%#x\n", (uint64_t)cfg.metadata_size, meta_size); errno = EINVAL; - goto close_ns; + goto close_fd; } if (cfg.prinfo > 0xf) { fprintf(stderr, "Invalid value for prinfo:%#x\n", cfg.prinfo); errno = EINVAL; - goto close_ns; + goto close_fd; } if (cfg.data) { dfd = open(cfg.data, O_RDONLY); if (dfd < 0) { perror(cfg.data); - goto close_ns; + goto close_fd; } } @@ -870,7 +1148,7 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin if (mfd < 0) { perror(cfg.metadata); err = -1; - goto close_dfd; + goto free_data; } } @@ -893,17 +1171,32 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin nblocks = (cfg.data_size / lba_size) - 1; control |= (cfg.prinfo << 10); if (cfg.limited_retry) - control |= NVME_RW_LR; + control |= NVME_IO_LR; if (cfg.fua) - control |= NVME_RW_FUA; + control |= NVME_IO_FUA; if (cfg.piremap) - control |= NVME_RW_PIREMAP; + control |= NVME_IO_ZNS_APPEND_PIREMAP; + + struct nvme_zns_append_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = cfg.namespace_id, + .zslba = cfg.zslba, + .nlb = nblocks, + .control = control, + .ilbrt = cfg.ref_tag, + .lbat = cfg.lbat, + .lbatm = cfg.lbatm, + .data_len = cfg.data_size, + .data = buf, + .metadata_len = cfg.metadata_size, + .metadata = mbuf, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = &result, + }; gettimeofday(&start_time, NULL); - err = nvme_zns_append(fd, cfg.namespace_id, cfg.zslba, nblocks, - control, cfg.ref_tag, cfg.lbat, cfg.lbatm, - cfg.data_size, buf, cfg.metadata_size, mbuf, - &result); + err = nvme_zns_append(&args); gettimeofday(&end_time, NULL); if (cfg.latency) printf(" latency: zone append: %llu us\n", @@ -926,10 +1219,9 @@ free_data: close_dfd: if (cfg.data) close(dfd); -close_ns: close_fd: close(fd); - return nvme_status_to_errno(err, false); + return err; } static int changed_zone_list(int argc, char **argv, struct command *cmd, struct plugin *plugin) @@ -967,15 +1259,14 @@ static int changed_zone_list(int argc, char **argv, struct command *cmd, struct goto close_fd; if (!cfg.namespace_id) { - err = cfg.namespace_id = nvme_get_nsid(fd); + err = nvme_get_nsid(fd, &cfg.namespace_id); if (err < 0) { perror("get-namespace-id"); goto close_fd; } } - err = nvme_get_log(fd, cfg.namespace_id, NVME_LOG_ZONE_CHANGED_LIST, - cfg.rae, NVME_NO_LOG_LSP, sizeof(log), &log); + err = nvme_get_log_zns_changed_zones(fd, cfg.namespace_id, cfg.rae, &log); if (!err) nvme_show_zns_changed(&log, flags); else if (err > 0) @@ -985,5 +1276,5 @@ static int changed_zone_list(int argc, char **argv, struct command *cmd, struct close_fd: close(fd); - return nvme_status_to_errno(err, false); + return err; } diff --git a/plugins/zns/zns.h b/plugins/zns/zns.h index 61063f7..1bdd4d9 100644 --- a/plugins/zns/zns.h +++ b/plugins/zns/zns.h @@ -8,23 +8,24 @@ PLUGIN(NAME("zns", "Zoned Namespace Command Set", NVME_VERSION), COMMAND_LIST( - ENTRY("id-ctrl", "Retrieve ZNS controller identification", id_ctrl) - ENTRY("id-ns", "Retrieve ZNS namespace identification", id_ns) - ENTRY("zone-mgmt-recv", "Sends the zone management receive command", zone_mgmt_recv) - ENTRY("zone-mgmt-send", "Sends the zone management send command", zone_mgmt_send) - ENTRY("report-zones", "Retrieve the Report Zones report", report_zones) - ENTRY("close-zone", "Closes one or more zones", close_zone) - ENTRY("finish-zone", "Finishes one or more zones", finish_zone) - ENTRY("open-zone", "Opens one or more zones", open_zone) - ENTRY("reset-zone", "Resets one or more zones", reset_zone) - ENTRY("offline-zone", "Offlines one or more zones", offline_zone) - ENTRY("set-zone-desc", "Attaches zone descriptor extension data", set_zone_desc) - ENTRY("zone-append", "Writes data and metadata (if applicable), appended to the end of the requested zone", zone_append) - ENTRY("changed-zone-list", "Retrieves the changed zone list log", changed_zone_list) + ENTRY("list", "List all NVMe devices with Zoned Namespace Command Set support", list) + ENTRY("id-ctrl", "Send NVMe Identify Zoned Namespace Controller, display structure", id_ctrl) + ENTRY("id-ns", "Send NVMe Identify Zoned Namespace Namespace, display structure", id_ns) + ENTRY("report-zones", "Report zones associated to a Zoned Namespace", report_zones) + ENTRY("reset-zone", "Reset one or more zones", reset_zone) + ENTRY("close-zone", "Close one or more zones", close_zone) + ENTRY("finish-zone", "Finishe one or more zones", finish_zone) + ENTRY("open-zone", "Open one or more zones", open_zone) + ENTRY("offline-zone", "Offline one or more zones", offline_zone) + ENTRY("set-zone-desc", "Attach zone descriptor extension data to a zone", set_zone_desc) + ENTRY("zrwa-flush-zone", "Flush LBAs associated with a ZRWA to a zone.", zrwa_flush_zone) + ENTRY("changed-zone-list", "Retrieve the changed zone list log", changed_zone_list) + ENTRY("zone-mgmt-recv", "Send the zone management receive command", zone_mgmt_recv) + ENTRY("zone-mgmt-send", "Send the zone management send command", zone_mgmt_send) + ENTRY("zone-append", "Append data and metadata (if applicable) to a zone", zone_append) ) ); #endif #include "define_cmd.h" - -- cgit v1.2.3