From bc5f35b4b8a5d1d1d794c03f0916754bc7ee4d74 Mon Sep 17 00:00:00 2001 From: Jeff Lien Date: Wed, 5 Feb 2020 14:36:26 -0600 Subject: [PATCH] Add namespace-resize wdc plugin command for SN720 drives. --- plugins/wdc/wdc-nvme.c | 71 ++++++++++++++++++++++++++++++++++++++++++ plugins/wdc/wdc-nvme.h | 1 + 2 files changed, 72 insertions(+) diff --git a/plugins/wdc/wdc-nvme.c b/plugins/wdc/wdc-nvme.c index f342364..efe2233 100644 --- a/plugins/wdc/wdc-nvme.c +++ b/plugins/wdc/wdc-nvme.c @@ -484,6 +484,9 @@ static int wdc_clear_assert_dump(int argc, char **argv, struct command *command, static int wdc_drive_resize(int argc, char **argv, struct command *command, struct plugin *plugin); static int wdc_do_drive_resize(int fd, uint64_t new_size); +static int wdc_namespace_resize(int argc, char **argv, + struct command *command, struct plugin *plugin); +static int wdc_do_namespace_resize(int fd, __u32 nsid, __u32 op_option); static int wdc_reason_identifier(int argc, char **argv, struct command *command, struct plugin *plugin); static int wdc_do_get_reason_id(int fd, char *file, int log_id); @@ -4557,6 +4560,20 @@ static int wdc_do_drive_resize(int fd, uint64_t new_size) return ret; } +static int wdc_do_namespace_resize(int fd, __u32 nsid, __u32 op_option) +{ + int ret; + struct nvme_admin_cmd admin_cmd; + + memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd)); + admin_cmd.opcode = WDC_NVME_NAMESPACE_RESIZE_OPCODE; + admin_cmd.nsid = nsid; + admin_cmd.cdw10 = op_option; + + ret = nvme_submit_admin_passthru(fd, &admin_cmd); + return ret; +} + static int wdc_drive_resize(int argc, char **argv, struct command *command, struct plugin *plugin) { @@ -4598,6 +4615,60 @@ static int wdc_drive_resize(int argc, char **argv, return ret; } +static int wdc_namespace_resize(int argc, char **argv, + struct command *command, struct plugin *plugin) +{ + const char *desc = "Send a Namespace Resize command."; + const char *namespace_id = "The namespace id to resize."; + const char *op_option = "The over provisioning option to set for namespace."; + uint64_t capabilities = 0; + int fd, ret; + + struct config { + __u32 namespace_id; + __u32 op_option; + }; + + struct config cfg = { + .namespace_id = 0x1, + .op_option = 0xF, + }; + + OPT_ARGS(opts) = { + OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id), + OPT_UINT("op-option", 'o', &cfg.op_option, op_option), + OPT_END() + }; + + fd = parse_and_open(argc, argv, desc, opts); + if (fd < 0) + return fd; + + if ((cfg.op_option != 0x1) && + (cfg.op_option != 0x2) && + (cfg.op_option != 0x3) && + (cfg.op_option != 0xF)) + { + fprintf(stderr, "ERROR : WDC: unsupported OP option parameter\n"); + return -1; + } + + wdc_check_device(fd); + capabilities = wdc_get_drive_capabilities(fd); + if ((capabilities & WDC_DRIVE_CAP_NS_RESIZE) == WDC_DRIVE_CAP_NS_RESIZE) { + ret = wdc_do_namespace_resize(fd, cfg.namespace_id, cfg.op_option); + + if (ret != 0) + printf("ERROR : WDC: Namespace Resize of namespace id 0x%x, op option 0x%x failed\n", cfg.namespace_id, cfg.op_option); + } else { + fprintf(stderr, "ERROR : WDC: unsupported device for this command\n"); + ret = -1; + } + + fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret); + return ret; +} + static int wdc_reason_identifier(int argc, char **argv, struct command *command, struct plugin *plugin) { diff --git a/plugins/wdc/wdc-nvme.h b/plugins/wdc/wdc-nvme.h index fe8a75a..a9d33d8 100644 --- a/plugins/wdc/wdc-nvme.h +++ b/plugins/wdc/wdc-nvme.h @@ -28,6 +28,7 @@ PLUGIN(NAME("wdc", "Western Digital vendor specific extensions"), ENTRY("vs-telemetry-controller-option", "WDC Enable/Disable Controller Initiated Telemetry Log", wdc_vs_telemetry_controller_option) ENTRY("vs-error-reason-identifier", "WDC Telemetry Reason Identifier", wdc_reason_identifier) ENTRY("log-page-directory", "WDC Get Log Page Directory", wdc_log_page_directory) + ENTRY("namespace-resize", "WDC NamespaceDrive Resize", wdc_namespace_resize) ) ); -- 2.49.0