From c52c24b6e1515da4a19c15ccb0a9cbd1b9354223 Mon Sep 17 00:00:00 2001 From: Gollu Appalanaidu Date: Fri, 2 Jul 2021 00:22:11 +0530 Subject: [PATCH] nvme: add capacity management command support Host software issues this Capacity Management command to configure/Create/Delete Endurance Groups and NVM Sets in an NVM subsystem. Signed-off-by: Gollu Appalanaidu Signed-off-by: Karthik Balan [dwagner: removed nvme-ioctl changes; part of libnvme] Signed-off-by: Daniel Wagner --- Documentation/nvme-capacity-mgmt.1 | 71 +++ Documentation/nvme-capacity-mgmt.html | 845 ++++++++++++++++++++++++++ Documentation/nvme-capacity-mgmt.txt | 54 ++ completions/_nvme | 19 +- completions/bash-nvme-completion.sh | 4 + nvme-builtin.h | 1 + nvme.c | 69 +++ 7 files changed, 1062 insertions(+), 1 deletion(-) create mode 100644 Documentation/nvme-capacity-mgmt.1 create mode 100644 Documentation/nvme-capacity-mgmt.html create mode 100644 Documentation/nvme-capacity-mgmt.txt diff --git a/Documentation/nvme-capacity-mgmt.1 b/Documentation/nvme-capacity-mgmt.1 new file mode 100644 index 00000000..b27dd2ca --- /dev/null +++ b/Documentation/nvme-capacity-mgmt.1 @@ -0,0 +1,71 @@ +'\" t +.\" Title: nvme-capacity-mgmt +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.79.1 +.\" Date: 07/02/2021 +.\" Manual: NVMe Manual +.\" Source: NVMe +.\" Language: English +.\" +.TH "NVME\-CAPACITY\-MGMT" "1" "07/02/2021" "NVMe" "NVMe Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nvme-capacity-mgmt \- Send capacity management command to configure/create/delete Endurance Groups or NVM Sets, returns results\&. +.SH "SYNOPSIS" +.sp +.nf +\fInvme capacity\-mgmt\fR [\-\-operation= | \-o ] + [\-\-element\-id= | \-i ] + [\-\-cap\-lower= | \-l ] + [\-\-cap\-upper= | \-u ] +.fi +.SH "DESCRIPTION" +.sp +For the NVMe device given, sends a capacity management command to configure/create/delete the Endurance Groups or NVM Sets with the requested operation and element_id\&. On success, if the Operation is Create Endurance group or NVM Set, CQE CDW0 contains Created element identifier else CQE CDW0 is reserved\&. +.sp +The parameter is mandatory and may be either the NVMe character device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1)\&. +.SH "OPTIONS" +.PP +\-o , \-\-operation= +.RS 4 +Operation to be performed by the controller +.RE +.PP +\-i , \-\-element\-id= +.RS 4 +Value specific to the value of the Operation field\&. +.RE +.PP +\-l , \-\-cap\-lower= +.RS 4 +Least significant 32 bits of the capacity in bytes of the Endurance Group or NVM Set to be created +.RE +.PP +\-u , \-\-cap\-upper= +.RS 4 +Most significant 32 bits of the capacity in bytes of the Endurance Group or NVM Set to be created +.RE +.SH "EXAMPLES" +.sp +No examples provided yet\&. +.SH "NVME" +.sp +Part of the nvme\-user suite diff --git a/Documentation/nvme-capacity-mgmt.html b/Documentation/nvme-capacity-mgmt.html new file mode 100644 index 00000000..aeb0fbc0 --- /dev/null +++ b/Documentation/nvme-capacity-mgmt.html @@ -0,0 +1,845 @@ + + + + + + +nvme-capacity-mgmt(1) + + + + + +
+
+

SYNOPSIS

+
+
+
nvme capacity-mgmt <device> [--operation=<operation> | -o <operation>]
+                        [--element-id=<element-id> | -i <element-id>]
+                        [--cap-lower=<cap-lower> | -l <cap-lower>]
+                        [--cap-upper=<cap-upper> | -u <cap-upper>]
+
+
+
+
+
+

DESCRIPTION

+
+

For the NVMe device given, sends a capacity management command to configure/create/delete +the Endurance Groups or NVM Sets with the requested operation and element_id. On success, +if the Operation is Create Endurance group or NVM Set, CQE CDW0 contains Created element +identifier else CQE CDW0 is reserved.

+

The <device> parameter is mandatory and may be either the NVMe character +device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).

+
+
+
+

OPTIONS

+
+
+
+-o <operation> +
+
+--operation=<operation> +
+
+

+ Operation to be performed by the controller +

+
+
+-i <element-id> +
+
+--element-id=<element-id> +
+
+

+ Value specific to the value of the Operation field. +

+
+
+-l <cap-lower> +
+
+--cap-lower=<cap-lower> +
+
+

+ Least significant 32 bits of the capacity in bytes of the Endurance Group or + NVM Set to be created +

+
+
+-u <cap-upper> +
+
+--cap-upper=<cap-upper> +
+
+

+ Most significant 32 bits of the capacity in bytes of the Endurance Group or + NVM Set to be created +

+
+
+
+
+
+

EXAMPLES

+
+

No examples provided yet.

+
+
+
+

NVME

+
+

Part of the nvme-user suite

+
+
+
+

+ + + diff --git a/Documentation/nvme-capacity-mgmt.txt b/Documentation/nvme-capacity-mgmt.txt new file mode 100644 index 00000000..96274cf0 --- /dev/null +++ b/Documentation/nvme-capacity-mgmt.txt @@ -0,0 +1,54 @@ +nvme-capacity-mgmt(1) +===================== + +NAME +---- +nvme-capacity-mgmt - Send capacity management command to configure/create/delete + Endurance Groups or NVM Sets, returns results. + +SYNOPSIS +-------- +[verse] +'nvme capacity-mgmt' [--operation= | -o ] + [--element-id= | -i ] + [--cap-lower= | -l ] + [--cap-upper= | -u ] + +DESCRIPTION +----------- +For the NVMe device given, sends a capacity management command to +configure/create/delete the Endurance Groups or NVM Sets with the requested +operation and element_id. On success, if the Operation is Create Endurance +group or NVM Set, CQE CDW0 contains Created element identifier else CQE CDW0 is +reserved. + +The parameter is mandatory and may be either the NVMe character +device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1). + +OPTIONS +------- +-o :: +--operation=:: + Operation to be performed by the controller + +-i :: +--element-id=:: + Value specific to the value of the Operation field. + +-l :: +--cap-lower=:: + Least significant 32 bits of the capacity in bytes of the Endurance Group or + NVM Set to be created + +-u :: +--cap-upper=:: + Most significant 32 bits of the capacity in bytes of the Endurance Group or + NVM Set to be created + +EXAMPLES +-------- +No examples provided yet. + +NVME +---- +Part of the nvme-user suite \ No newline at end of file diff --git a/completions/_nvme b/completions/_nvme index db96baa3..b2181a8c 100644 --- a/completions/_nvme +++ b/completions/_nvme @@ -47,6 +47,7 @@ _nvme () { 'compare:compare data on device to data elsewhere' 'read:submit a read command' 'write:submit a write command' + 'capacity-mgmt: submit capacity management command' 'show-regs:shows the controller registers; requires admin character device' 'help:print brief descriptions of all nvme commands' ) @@ -418,6 +419,22 @@ _nvme () { _arguments '*:: :->subcmds' _describe -t commands "nvme fw-download options" _fwd ;; + (capacity-mgmt) + local _fwd + _fwd=( + /dev/nvme':supply a device to use (required)' + --operation=':Operation to be performed by the controller' + -o':alias of --operation' + --element-id=':specific to the value of the Operation field' + -i':alias of --element-id' + --cap-lower=':Least significant 32 bits of the capacity in bytes' + -l':alias of --cap-lower' + --cap-upper=':Most significant 32 bits of the capacity in bytes' + -u':alias of --cap-upper' + ) + _arguments '*:: :->subcmds' + _describe -t commands "nvme capacity-mgmt options" _fwd + ;; (admin-passthru) local _admin _admin=( @@ -794,7 +811,7 @@ _nvme () { security-send security-recv resv-acquire resv-register resv-release resv-report flush compare read write copy show-regs persistent-event-log pred-lat-event-agg-log nvm-id-ctrl endurance-event-agg-log lba-status-log - resv-notif-log + resv-notif-log capacity-mgmt ) _arguments '*:: :->subcmds' _describe -t commands "help: infos on a specific nvme command, or provide no option to see a synopsis of all nvme commands" _h diff --git a/completions/bash-nvme-completion.sh b/completions/bash-nvme-completion.sh index 6f34e5db..2b31233e 100644 --- a/completions/bash-nvme-completion.sh +++ b/completions/bash-nvme-completion.sh @@ -282,6 +282,10 @@ nvme_list_opts () { "fw-download") opts+=" --fw= -f --xfer= -x --offset= -o" ;; + "capacity-mgmt") + opts+=" --operation= -f --element-id= -i --cap-lower= -l \ + --cap-upper= -u" + ;; "admin-passthru") opts+=" --opcode= -o --flags= -f --prefil= -p --rsvd= -R \ --namespace-id= -n --data-len= -l --metadata-len= -m \ diff --git a/nvme-builtin.h b/nvme-builtin.h index a413d008..42ae5a27 100644 --- a/nvme-builtin.h +++ b/nvme-builtin.h @@ -55,6 +55,7 @@ COMMAND_LIST( ENTRY("security-send", "Submit a Security Send command, return results", sec_send) ENTRY("security-recv", "Submit a Security Receive command, return results", sec_recv) ENTRY("get-lba-status", "Submit a Get LBA Status command, return results", get_lba_status) + ENTRY("capacity-mgmt", "Submit Capacity Management Command, return results", capacity_mgmt) ENTRY("resv-acquire", "Submit a Reservation Acquire, return results", resv_acquire) ENTRY("resv-register", "Submit a Reservation Register, return results", resv_register) ENTRY("resv-release", "Submit a Reservation Release, return results", resv_release) diff --git a/nvme.c b/nvme.c index f85d92ce..522a9131 100644 --- a/nvme.c +++ b/nvme.c @@ -5583,6 +5583,75 @@ err: return nvme_status_to_errno(err, false); } +static int capacity_mgmt(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + const char *desc = "Host software uses the Capacity Management command to "\ + "configure Endurance Groups and NVM Sets in an NVM subsystem by either " \ + "selecting one of a set of supported configurations or by specifying the "\ + "capacity of the Endurance Group or NVM Set to be created"; + const char *operation = "Operation to be performed by the controller"; + const char *element_id = "Value specific to the value of the Operation field."; + const char *cap_lower = "Least significant 32 bits of the capacity in bytes of the "\ + "Endurance Group or NVM Set to be created"; + const char *cap_upper = "Most significant 32 bits of the capacity in bytes of the "\ + "Endurance Group or NVM Set to be created"; + + int err = -1, fd; + __u32 result; + + struct config { + __u8 operation; + __u16 element_id; + __u32 dw11; + __u32 dw12; + }; + + struct config cfg = { + .operation = 0xff, + .element_id = 0xffff, + .dw11 = 0, + .dw12 = 0, + }; + + OPT_ARGS(opts) = { + OPT_BYTE("operation", 'o', &cfg.operation, operation), + OPT_SHRT("element-id", 'i', &cfg.element_id, element_id), + OPT_UINT("cap-lower", 'l', &cfg.dw11, cap_lower), + OPT_UINT("cap-upper", 'u', &cfg.dw12, cap_upper), + OPT_END() + }; + + err = fd = parse_and_open(argc, argv, desc, opts); + if (fd < 0) + goto ret; + + if (cfg.operation > 0xf) { + fprintf(stderr, "invalid operation field: %u\n", cfg.operation); + errno = EINVAL; + err = -1; + goto close_fd; + } + + err = nvme_capacity_mgmt(fd, cfg.operation, cfg.element_id, cfg.dw11, + cfg.dw12, &result); + if (!err) { + printf("Capacity Management Command is Success\n"); + if (cfg.operation == 1) { + printf("Created Element Identifier for Endurance Group is: %u\n", result); + } else if (cfg.operation == 3) { + printf("Created Element Identifier for NVM Set is: %u\n", result); + } + } else if (err > 0) + nvme_show_status(err); + else if (err < 0) + perror("capacity management"); + +close_fd: + close(fd); +ret: + return nvme_status_to_errno(err, false); +} + static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin *plugin) { const char *desc = "Read directive parameters of the "\ -- 2.50.1