From: Steven Seungcheol Lee Date: Fri, 7 Jan 2022 09:37:06 +0000 (+0900) Subject: nvme: Add nvm-id-ns-lba-format(CNS 0Ah) command from TP4095 X-Git-Tag: v2.0-rc3~18^2~1 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=a2861f19f56486d51d7b4a71dca77edf58953d56;p=users%2Fsagi%2Fnvme-cli.git nvme: Add nvm-id-ns-lba-format(CNS 0Ah) command from TP4095 I/O Command Set specific Identify Namespace data structure for the specified LBA Format index for the NVM Command Set specified in the CSI field. None capabilities from nvme_id_ns structure are returned as 0 with this command Set maximum nlbaf when identify ns for all ns is failed to print elbafs Signed-off-by: Steven Seungcheol Lee --- diff --git a/Documentation/nvme-nvm-id-ns-lba-format.1 b/Documentation/nvme-nvm-id-ns-lba-format.1 new file mode 100644 index 00000000..86723f0a --- /dev/null +++ b/Documentation/nvme-nvm-id-ns-lba-format.1 @@ -0,0 +1,117 @@ +'\" t +.\" Title: nvme-nvm-id-ns-lba-format +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.78.1 +.\" Date: 01/07/2022 +.\" Manual: NVMe Manual +.\" Source: NVMe +.\" Language: English +.\" +.TH "NVME\-NVM\-ID\-NS\-L" "1" "01/07/2022" "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-nvm-id-ns-lba-format \- Send NVMe Identify NVM Command Set specific Namespace data structure for specified LBA format, display structure +.SH "SYNOPSIS" +.sp +.nf +\fInvme nvm\-id\-ns\-lba\-format\fR [\-\-uuid\-index= | \-U ] + [\-\-lba\-format\-index= | \-i ] + [\-v | \-\-verbose] + [\-\-output\-format= | \-o ] +.fi +.SH "DESCRIPTION" +.sp +Identify NVM Command Set specific Namespace data structure for the specified LBA format index for the NVM Command Set specified in the CSI field\&. +.sp +The parameter is mandatory and may be either the NVMe character device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1)\&. +.sp +On success, the structure may be returned in one of several ways depending on the option flags; the structure may be parsed by the program or the raw buffer may be printed to stdout\&. +.SH "OPTIONS" +.PP +\-U , \-\-uuid\-index= +.RS 4 +UUID Index of the feature +.RE +.PP +\-i , \-\-lba\-format\-index= +.RS 4 +This field specifies the index into the LBA Format list identifying the LBA Format capabilities that are to be returned +.RE +.PP +\-v, \-\-verbose +.RS 4 +Increase the information detail in the output\&. +.RE +.PP +\-o , \-\-output\-format= +.RS 4 +Set the reporting format to +\fInormal\fR, +\fIjson\fR, or +\fIbinary\fR\&. Only one output format can be used at a time\&. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +Has the program interpret the returned buffer and display the known fields in a human readable format: +.sp +.if n \{\ +.RS 4 +.\} +.nf +# nvme nvm\-id\-ns\-lba\-format /dev/nvme0n1 \-i 0 +.fi +.if n \{\ +.RE +.\} +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +Have the program return the raw structure in binary: +.sp +.if n \{\ +.RS 4 +.\} +.nf +# nvme nvm\-id\-ns\-lba\-format /dev/nvme0 \-i 0 \-o binary > nvm_id_ns\&.raw +# nvme nvm\-id\-ns\-lba\-format /dev/nvme0n1 \-i 0 \-\-output\-format=binary > nvm_id_ns\&.raw +.fi +.if n \{\ +.RE +.\} +.RE +.SH "NVME" +.sp +Part of the nvme\-user suite diff --git a/Documentation/nvme-nvm-id-ns-lba-format.html b/Documentation/nvme-nvm-id-ns-lba-format.html new file mode 100644 index 00000000..09ac1c4c --- /dev/null +++ b/Documentation/nvme-nvm-id-ns-lba-format.html @@ -0,0 +1,863 @@ + + + + + +nvme-nvm-id-ns-lba-format(1) + + + + + +
+
+

SYNOPSIS

+
+
+
nvme nvm-id-ns-lba-format <device> [--uuid-index=<uuid-index> | -U <uuid_index>]
+                        [--lba-format-index=<lba_format_index> | -i <lba_format_index>]
+                        [-v | --verbose]
+                        [--output-format=<fmt> | -o <fmt>]
+
+
+
+
+
+

DESCRIPTION

+
+

Identify NVM Command Set specific Namespace data structure for the specified +LBA format index for the NVM Command Set specified in the CSI field.

+

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

+

On success, the structure may be returned in one of several ways depending +on the option flags; the structure may be parsed by the program or the +raw buffer may be printed to stdout.

+
+
+
+

OPTIONS

+
+
+
+-U <uuid-index> +
+
+--uuid-index=<uuid-index> +
+
+

+ UUID Index of the feature +

+
+
+-i <lba_format_index> +
+
+--lba-format-index=<lba_format_index> +
+
+

+ This field specifies the index into the LBA Format list identifying + the LBA Format capabilities that are to be returned +

+
+
+-v +
+
+--verbose +
+
+

+ Increase the information detail in the output. +

+
+
+-o <format> +
+
+--output-format=<format> +
+
+

+ Set the reporting format to normal, json, or + binary. Only one output format can be used at a time. +

+
+
+
+
+
+

EXAMPLES

+
+
    +
  • +

    +Has the program interpret the returned buffer and display the known +fields in a human readable format: +

    +
    +
    +
    # nvme nvm-id-ns-lba-format /dev/nvme0n1 -i 0
    +
    +
  • +
  • +

    +Have the program return the raw structure in binary: +

    +
    +
    +
    # nvme nvm-id-ns-lba-format /dev/nvme0 -i 0 -o binary > nvm_id_ns.raw
    +# nvme nvm-id-ns-lba-format /dev/nvme0n1 -i 0 --output-format=binary > nvm_id_ns.raw
    +
    +
  • +
+
+
+
+

NVME

+
+

Part of the nvme-user suite

+
+
+
+

+ + + diff --git a/Documentation/nvme-nvm-id-ns-lba-format.txt b/Documentation/nvme-nvm-id-ns-lba-format.txt new file mode 100644 index 00000000..638e2fba --- /dev/null +++ b/Documentation/nvme-nvm-id-ns-lba-format.txt @@ -0,0 +1,67 @@ +nvme-nvm-id-ns-lba-format(1) +============================ + +NAME +---- +nvme-nvm-id-ns-lba-format - Send NVMe Identify NVM Command Set specific +Namespace data structure for specified LBA format, display structure + +SYNOPSIS +-------- +[verse] +'nvme nvm-id-ns-lba-format' [--uuid-index= | -U ] + [--lba-format-index= | -i ] + [-v | --verbose] + [--output-format= | -o ] + +DESCRIPTION +----------- +Identify NVM Command Set specific Namespace data structure for the specified +LBA format index for the NVM Command Set specified in the CSI field. + +The parameter is mandatory and may be either the NVMe character +device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1). + +On success, the structure may be returned in one of several ways depending +on the option flags; the structure may be parsed by the program or the +raw buffer may be printed to stdout. + +OPTIONS +------- +-U :: +--uuid-index=:: + UUID Index of the feature + +-i :: +--lba-format-index=:: + This field specifies the index into the LBA Format list identifying + the LBA Format capabilities that are to be returned + +-v:: +--verbose:: + Increase the information detail in the output. + +-o :: +--output-format=:: + Set the reporting format to 'normal', 'json', or + 'binary'. Only one output format can be used at a time. + +EXAMPLES +-------- +* Has the program interpret the returned buffer and display the known +fields in a human readable format: ++ +------------ +# nvme nvm-id-ns-lba-format /dev/nvme0n1 -i 0 +------------ ++ +* Have the program return the raw structure in binary: ++ +------------ +# nvme nvm-id-ns-lba-format /dev/nvme0 -i 0 -o binary > nvm_id_ns.raw +# nvme nvm-id-ns-lba-format /dev/nvme0n1 -i 0 --output-format=binary > nvm_id_ns.raw +------------ + +NVME +---- +Part of the nvme-user suite diff --git a/completions/_nvme b/completions/_nvme index 980dbc9e..14a005cb 100644 --- a/completions/_nvme +++ b/completions/_nvme @@ -21,6 +21,7 @@ _nvme () { 'list-ctrl:identify all controller(s) attached' 'nvm-id-ctrl:display information about the nvm command set' 'nvm-id-ns:display information about the namespace of nvm command set' + 'id-ns-lba-format:display information about the namespace of nvm command set capability fields for specific LBA format' 'list-endgrp:display information about nvme endurance group list' 'get-ns-id:get namespace id of opened block device' 'get-log:retrieve any log in raw format' @@ -188,6 +189,22 @@ _nvme () { _arguments '*:: :->subcmds' _describe -t commands "nvme nvm-id-ns options" _nvmidns ;; + (id-ns-lba-format) + local _nvm_idns_lba_format + _nvm_idns_lba_format=( + /dev/nvme':supply a device to use (required)' + --lba-format-index=':show infos for lba format index ' + -i':alias of --lba-format-index' + --uuid-index=':uuid index' + -U':alias for --uuid-index' + --output-format=':Output format: normal|json|binary' + -o':alias for --output-format' + --verbose':show infos verbosely' + -v':alias of --verbose' + ) + _arguments '*:: :->subcmds' + _describe -t commands "nvme nvm-id-ns-lba-format options" _nvm_idns_lba_format + ;; (list-endgrp) local _listendgrp _listendgrp=( @@ -949,6 +966,7 @@ _nvme () { pred-lat-event-agg-log nvm-id-ctrl endurance-event-agg-log lba-status-log resv-notif-log capacity-mgmt id-domain boot-part-log fid-support-effects-log supported-log-pages lockdown media-unit-stat-log id-ns-lba-format nvm-id-ns + nvm-id-ns-lba-format ) _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 da9ed9bf..10cbdd1e 100644 --- a/completions/bash-nvme-completion.sh +++ b/completions/bash-nvme-completion.sh @@ -78,7 +78,7 @@ readonly _plugin_funcs=( # Top level commands _cmds="list list-subsys id-ctrl id-ns \ id-ns-granularity list-ns list-ctrl \ - id-ns-lba-format nvm-id-ns \ + id-ns-lba-format nvm-id-ns nvm-id-ns-lba-format \ nvm-id-ctrl primary-ctrl-caps list-secondary \ ns-descs id-nvmset id-uuid id-iocs create-ns \ delete-ns get-ns-id get-log telemetry-log \ @@ -168,6 +168,10 @@ nvme_list_opts () { opts+=" --namespace-id= -n --uuid-index= -U\ --verbose -v --output-format= -o" ;; + "nvm-id-ns-lba-format") + opts+=" --lba-format-index= -i --uuid-index= -U \ + --verbose -v --output-format= -o" + ;; "primary-ctrl-caps") opts+=" --output-format= -o --human-readable -H" ;; diff --git a/nvme-builtin.h b/nvme-builtin.h index bac94cba..4b123a86 100644 --- a/nvme-builtin.h +++ b/nvme-builtin.h @@ -17,6 +17,7 @@ COMMAND_LIST( ENTRY("list-ctrl", "Send NVMe Identify Controller List, display structure", list_ctrl) ENTRY("nvm-id-ctrl", "Send NVMe Identify Controller NVM Command Set, display structure", nvm_id_ctrl) ENTRY("nvm-id-ns", "Send NVMe Identify Namespace NVM Command Set, display structure", nvm_id_ns) + ENTRY("nvm-id-ns-lba-format", "Send NVMe Identify Namespace NVM Command Set for the specified LBA Format index, display structure", nvm_id_ns_lba_format) ENTRY("primary-ctrl-caps", "Send NVMe Identify Primary Controller Capabilities", primary_ctrl_caps) ENTRY("list-secondary", "List Secondary Controllers associated with a Primary Controller", list_secondary_ctrl) ENTRY("cmdset-ind-id-ns", "I/O Command Set Independent Identify Namespace", cmd_set_independent_id_ns) diff --git a/nvme-print.c b/nvme-print.c index 2fb6197e..d382969d 100644 --- a/nvme-print.c +++ b/nvme-print.c @@ -3871,12 +3871,13 @@ void nvme_show_id_ns(struct nvme_id_ns *ns, unsigned int nsid, for (i = 0; i < 16; i++) printf("%02x", ns->nguid[i]); printf("\n"); + + printf("eui64 : "); + for (i = 0; i < 8; i++) + printf("%02x", ns->eui64[i]); + printf("\n"); } - printf("eui64 : "); - for (i = 0; i < 8; i++) - printf("%02x", ns->eui64[i]); - printf("\n"); nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &flbas); for (i = 0; i <= ns->nlbaf + ns->nulbaf; i++) { if (human) @@ -4425,7 +4426,7 @@ void nvme_show_id_ctrl_nvm(struct nvme_id_ctrl_nvm *ctrl_nvm, } static void json_nvme_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns, - struct nvme_id_ns *ns) + struct nvme_id_ns *ns, bool cap_only) { struct json_object *root; struct json_object *elbafs; @@ -4433,7 +4434,9 @@ static void json_nvme_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns, root = json_create_object(); - json_object_add_value_uint64(root, "lbstm", le64_to_cpu(nvm_ns->lbstm)); + if (!cap_only) { + json_object_add_value_uint64(root, "lbstm", le64_to_cpu(nvm_ns->lbstm)); + } json_object_add_value_int(root, "pic", nvm_ns->pic); elbafs = json_create_array(); @@ -4470,24 +4473,31 @@ static void nvme_show_nvm_id_ns_pic(__u8 pic) } void nvme_show_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns, unsigned int nsid, - struct nvme_id_ns *ns, enum nvme_print_flags flags) + struct nvme_id_ns *ns, unsigned int lba_index, + bool cap_only, enum nvme_print_flags flags) { int i, verbose = flags & VERBOSE; __u32 elbaf; int pif, sts; + char *in_use = "(in use)"; if (flags & BINARY) return d_raw((unsigned char *)nvm_ns, sizeof(*nvm_ns)); else if (flags & JSON) - return json_nvme_nvm_id_ns(nvm_ns, ns); + return json_nvme_nvm_id_ns(nvm_ns, ns, cap_only); - printf("NVMe NVM Identify Namespace %d:\n", nsid); - printf("lbstm : %#"PRIx64"\n", le64_to_cpu(nvm_ns->lbstm)); + if (!cap_only) { + printf("NVMe NVM Identify Namespace %d:\n", nsid); + printf("lbstm : %#"PRIx64"\n", le64_to_cpu(nvm_ns->lbstm)); + } else { + printf("NVMe NVM Identify Namespace for LBA format[%d]:\n", lba_index); + in_use = ""; + } printf("pic : %#x\n", nvm_ns->pic); if (verbose) nvme_show_nvm_id_ns_pic(nvm_ns->pic); - for (i = 0; i <= ns->nlbaf; i++) { + for (i = 0; i <= ns->nlbaf + ns->nulbaf; i++) { elbaf = le32_to_cpu(nvm_ns->elbaf[i]); pif = (elbaf >> 7) & 0x3; sts = elbaf & 0x7f; @@ -4497,10 +4507,10 @@ void nvme_show_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns, unsigned int nsid, i, pif == 3 ? "Reserved" : pif == 2 ? "64b Guard" : pif == 1 ? "32b Guard" : "16b Guard", - pif, sts, i == (ns->flbas & 0xf) ? "(in use)" : ""); + pif, sts, i == (ns->flbas & 0xf) ? in_use : ""); else printf("elbaf %2d : pif:%d lbads:%-2d %s\n", i, - pif, sts, i == (ns->flbas & 0xf) ? "(in use)" : ""); + pif, sts, i == (ns->flbas & 0xf) ? in_use : ""); } } diff --git a/nvme-print.h b/nvme-print.h index f9ba54d4..5f4f872e 100644 --- a/nvme-print.h +++ b/nvme-print.h @@ -113,7 +113,8 @@ void nvme_show_zns_id_ctrl(struct nvme_zns_id_ctrl *ctrl, unsigned int mode); void nvme_show_id_ctrl_nvm(struct nvme_id_ctrl_nvm *ctrl_nvm, enum nvme_print_flags flags); void nvme_show_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns, unsigned int nsid, - struct nvme_id_ns *ns, enum nvme_print_flags flags); + struct nvme_id_ns *ns, unsigned int lba_index, + bool cap_only, enum nvme_print_flags flags); void nvme_show_zns_id_ns(struct nvme_zns_id_ns *ns, struct nvme_id_ns *id_ns, unsigned long flags); void nvme_show_zns_changed( struct nvme_zns_changed_zone_log *log, diff --git a/nvme.c b/nvme.c index 1c7069cf..60e79c7d 100644 --- a/nvme.c +++ b/nvme.c @@ -2719,7 +2719,7 @@ static int nvm_id_ns(int argc, char **argv, struct command *cmd, err = nvme_identify_ns_csi(fd, cfg.namespace_id, cfg.uuid_index, NVME_CSI_NVM, &id_ns); if (!err) - nvme_show_nvm_id_ns(&id_ns, cfg.namespace_id, &ns, flags); + nvme_show_nvm_id_ns(&id_ns, cfg.namespace_id, &ns, 0, false, flags); else if (err > 0) nvme_show_status(err); else @@ -2730,6 +2730,74 @@ ret: return nvme_status_to_errno(err, false); } +static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + const char *desc = "Send an NVM Command Set specific Identify Namespace " + "command to the given device, returns capability field properties of " + "the specified LBA Format index in the specified namespace in various " + "formats."; + const char *lba_format_index = "The index into the LBA Format list "\ + "identifying the LBA Format capabilities that are to be returned"; + const char *uuid_index = "UUID index"; + const char *verbose = "Increase output verbosity"; + enum nvme_print_flags flags; + struct nvme_id_ns ns; + struct nvme_nvm_id_ns nvm_ns; + int err = -1, fd; + + struct config { + __u16 lba_format_index; + __u8 uuid_index; + int verbose; + char *output_format; + }; + + struct config cfg = { + .lba_format_index = 0, + .uuid_index = NVME_UUID_NONE, + .verbose = 0, + .output_format = "normal", + }; + + OPT_ARGS(opts) = { + OPT_UINT("lba-format-index", 'i', &cfg.lba_format_index, lba_format_index), + OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index), + OPT_FLAG("verbose", 'v', &cfg.verbose, verbose), + OPT_FMT("output-format", 'o', &cfg.output_format, output_format), + OPT_END() + }; + + err = fd = parse_and_open(argc, argv, desc, opts); + if (fd < 0) + goto ret; + + err = flags = validate_output_format(cfg.output_format); + if (flags < 0) + goto close_fd; + + if (cfg.verbose) + flags |= VERBOSE; + + err = nvme_identify_ns(fd, NVME_NSID_ALL, &ns); + if (err) { + ns.nlbaf = NVME_FEAT_LBA_RANGE_MAX - 1; + ns.nulbaf = 0; + } + err = nvme_identify_iocs_ns_csi_user_data_format(fd, cfg.lba_format_index, + cfg.uuid_index, NVME_CSI_NVM, &nvm_ns); + if (!err) + nvme_show_nvm_id_ns(&nvm_ns, 0, &ns, cfg.lba_format_index, true, + flags); + else if (err > 0) + nvme_show_status(err); + else + perror("NVM identify namespace for specific LBA format"); +close_fd: + close(fd); +ret: + return nvme_status_to_errno(err, false); +} + static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *plugin) { const char *desc = "Send Namespace Identification Descriptors command to the "\