Skip to content

Commit acd7603

Browse files
committed
nvme: add support for sanitize-ns command
Supported by NVMe 2.3. Signed-off-by: Tokunori Ikegami <[email protected]>
1 parent 8411baf commit acd7603

File tree

3 files changed

+116
-0
lines changed

3 files changed

+116
-0
lines changed

libnvme/src/nvme/ioctl.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4088,6 +4088,34 @@ nvme_init_sanitize_nvm(struct nvme_passthru_cmd *cmd,
40884088
cmd->cdw11 = ovrpat;
40894089
}
40904090

4091+
/**
4092+
* nvme_init_sanitize_ns() - Initialize passthru command to start a
4093+
* sanitize namespace operation
4094+
* @cmd: Passthru command to use
4095+
* @sanact: Sanitize action, see &enum nvme_sanitize_sanact
4096+
* @ause: Set to allow unrestricted sanitize exit
4097+
* @emvs: Set to enter media verification state
4098+
*
4099+
* Initializes the passthru command buffer for the Sanitize namespace command.
4100+
*/
4101+
static inline void
4102+
nvme_init_sanitize_ns(struct nvme_passthru_cmd *cmd,
4103+
enum nvme_sanitize_sanact sanact, bool ause, bool emvs)
4104+
{
4105+
memset(cmd, 0, sizeof(*cmd));
4106+
4107+
cmd->opcode = nvme_admin_sanitize_ns;
4108+
cmd->cdw10 = NVME_FIELD_ENCODE(sanact,
4109+
NVME_SANITIZE_CDW10_SANACT_SHIFT,
4110+
NVME_SANITIZE_CDW10_SANACT_MASK) |
4111+
NVME_FIELD_ENCODE(ause,
4112+
NVME_SANITIZE_CDW10_AUSE_SHIFT,
4113+
NVME_SANITIZE_CDW10_AUSE_MASK) |
4114+
NVME_FIELD_ENCODE(emvs,
4115+
NVME_SANITIZE_CDW10_EMVS_SHIFT,
4116+
NVME_SANITIZE_CDW10_EMVS_MASK);
4117+
}
4118+
40914119
/**
40924120
* nvme_init_dev_self_test() - Initialize passthru command to start or
40934121
* abort a self test

nvme-builtin.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ COMMAND_LIST(
9494
ENTRY("verify", "Submit a verify command, return results", verify_cmd)
9595
ENTRY("sanitize", "Submit a sanitize command", sanitize_cmd)
9696
ENTRY("sanitize-log", "Retrieve sanitize log, show it", sanitize_log)
97+
ENTRY("sanitize-ns", "Submit a sanitize namespace command",
98+
sanitize_ns_cmd)
9799
ENTRY("reset", "Resets the controller", reset)
98100
ENTRY("subsystem-reset", "Resets the subsystem", subsystem_reset)
99101
ENTRY("ns-rescan", "Rescans the NVME namespaces", ns_rescan)

nvme.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5565,6 +5565,92 @@ static int sanitize_cmd(int argc, char **argv, struct command *acmd, struct plug
55655565
return err;
55665566
}
55675567

5568+
static int sanitize_ns_cmd(int argc, char **argv, struct command *acmd,
5569+
struct plugin *plugin)
5570+
{
5571+
const char *desc = "Send a sanitize namespace command.";
5572+
const char *emvs_desc = "Enter media verification state.";
5573+
const char *ause_desc = "Allow unrestricted sanitize exit.";
5574+
const char *sanact_desc = "Sanitize action: 1 = Exit failure mode,\n"
5575+
"4 = Start a crypto erase namespace sanitize operation,\n"
5576+
"5 = Exit media verification state";
5577+
5578+
_cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl =
5579+
NULL;
5580+
5581+
_cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL;
5582+
struct nvme_passthru_cmd cmd;
5583+
nvme_print_flags_t flags;
5584+
int err;
5585+
5586+
struct config {
5587+
bool ause;
5588+
__u8 sanact;
5589+
bool emvs;
5590+
};
5591+
5592+
struct config cfg = {
5593+
.ause = false,
5594+
.sanact = 0,
5595+
.emvs = false,
5596+
};
5597+
5598+
OPT_VALS(sanact) = {
5599+
VAL_BYTE("exit-failure", NVME_SANITIZE_SANACT_EXIT_FAILURE),
5600+
VAL_BYTE("start-crypto-erase",
5601+
NVME_SANITIZE_SANACT_START_CRYPTO_ERASE),
5602+
VAL_BYTE("exit-media-verification",
5603+
NVME_SANITIZE_SANACT_EXIT_MEDIA_VERIF),
5604+
VAL_END()
5605+
};
5606+
5607+
NVME_ARGS(opts,
5608+
OPT_FLAG("ause", 'u', &cfg.ause, ause_desc),
5609+
OPT_BYTE("sanact", 'a', &cfg.sanact, sanact_desc, sanact),
5610+
OPT_FLAG("emvs", 'e', &cfg.emvs, emvs_desc));
5611+
5612+
err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
5613+
if (err)
5614+
return err;
5615+
5616+
err = validate_output_format(nvme_cfg.output_format, &flags);
5617+
if (err < 0) {
5618+
nvme_show_error("Invalid output format");
5619+
return err;
5620+
}
5621+
5622+
switch (cfg.sanact) {
5623+
case NVME_SANITIZE_SANACT_EXIT_FAILURE:
5624+
case NVME_SANITIZE_SANACT_START_CRYPTO_ERASE:
5625+
case NVME_SANITIZE_SANACT_EXIT_MEDIA_VERIF:
5626+
break;
5627+
default:
5628+
nvme_show_error("Invalid Sanitize Action");
5629+
return -EINVAL;
5630+
}
5631+
5632+
if (cfg.ause) {
5633+
if (cfg.sanact == NVME_SANITIZE_SANACT_EXIT_FAILURE) {
5634+
nvme_show_error("SANACT is Exit Failure Mode");
5635+
return -EINVAL;
5636+
} else if (cfg.sanact ==
5637+
NVME_SANITIZE_SANACT_EXIT_MEDIA_VERIF) {
5638+
nvme_show_error(
5639+
"SANACT is Exit Media Verification State");
5640+
return -EINVAL;
5641+
}
5642+
}
5643+
5644+
nvme_init_sanitize_ns(&cmd, cfg.sanact, cfg.ause, cfg.emvs);
5645+
err = nvme_submit_admin_passthru(hdl, &cmd);
5646+
if (err < 0)
5647+
nvme_show_error("sanitize ns: %s", nvme_strerror(err));
5648+
else if (err > 0)
5649+
nvme_show_status(err);
5650+
5651+
return err;
5652+
}
5653+
55685654
static int nvme_get_single_property(struct nvme_transport_handle *hdl, struct get_reg_config *cfg, __u64 *value)
55695655
{
55705656
struct nvme_passthru_cmd cmd;

0 commit comments

Comments
 (0)