summaryrefslogtreecommitdiffstats
path: root/plugins/zns
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/zns')
-rw-r--r--plugins/zns/zns.c461
-rw-r--r--plugins/zns/zns.h29
2 files changed, 391 insertions, 99 deletions
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 <linux/fs.h>
#include <sys/stat.h>
+#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"
-