Skip to contentSkip to conversation

nvme-cli: Extended Data Structure in resv-report

PATCH New Schremmer, Steven 2 participants 2 messages Jun 28, 2017

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 nvme-cli: Extended Data Structure in resv-report

Allow user to specify cdw11 value to request Extended Data Structure. Update resv_report show and json functions to decode the returned data.

Signed-off-by Steve Schremmer <steve.schremmer at netapp.com>
---
 Documentation/nvme-resv-report.txt |  5 ++
 linux/nvme.h                       | 20 +++++++-
 nvme-ioctl.c                       |  3 +-
 nvme-ioctl.h                       |  2 +-
 nvme-print.c                       | 96 +++++++++++++++++++++++++++++---------
 nvme-print.h                       |  4 +-
 nvme.c                             | 13 ++++--
 7 files changed, 114 insertions(+), 29 deletions(-)
Documentation/nvme-resv-report.txt +5 -0
index a7def3a..e207102 100644
@@ -37,6 +37,11 @@ OPTIONS
 	Specify the number of Dwords of the Reservation Status structure
 	to transfer. Defaults to 4k.
 
+-c <cdw11>::
+--cdw11=<cdw11>::
+	The value for command dword 11. Setting bit 0 specifies that the 
+	controller returns the Extended Data Structure.
+
 -b::
 --raw-binary::
 	Print the raw buffer to stdout. Structure is not parsed by
linux/nvme.h +19 -1
index fd58a36..c5a6ca6 100644
@@ -373,7 +373,7 @@ struct nvme_reservation_status {
 	__u8	regctl[2];
 	__u8	resv5[2];
 	__u8	ptpls;
-	__u8	resv10[13];
+	__u8	resv10[14];
 	struct {
 		__le16	cntlid;
 		__u8	rcsts;
@@ -383,6 +383,24 @@ struct nvme_reservation_status {
 	} regctl_ds[];
 };
 
+struct nvme_reservation_status_ext {
+	__le32	gen;
+	__u8	rtype;
+	__u8	regctl[2];
+	__u8	resv5[2];
+	__u8	ptpls;
+	__u8	resv10[14];
+	__u8	resv24[40];
+	struct {
+		__le16	cntlid;
+		__u8	rcsts;
+		__u8	resv3[5];
+		__le64	rkey;
+		__u8	hostid[16];
+		__u8	resv32[32];
+	} regctl_eds[];
+};
+
 enum nvme_async_event_type {
 	NVME_AER_TYPE_ERROR	= 0,
 	NVME_AER_TYPE_SMART	= 1,
nvme-ioctl.c +2 -1
index e3e9af4..f5cbc28 100644
@@ -300,12 +300,13 @@ int nvme_resv_release(int fd, __u32 nsid, __u8 rtype, __u8 rrela,
 	return nvme_submit_io_passthru(fd, &cmd);
 }
 
-int nvme_resv_report(int fd, __u32 nsid, __u32 numd, void *data)
+int nvme_resv_report(int fd, __u32 nsid, __u32 numd, __u32 cdw11, void *data)
 {
 	struct nvme_passthru_cmd cmd = {
 		.opcode		= nvme_cmd_resv_report,
 		.nsid		= nsid,
 		.cdw10		= numd,
+		.cdw11		= cdw11,
 		.addr		= (__u64)(uintptr_t) data,
 		.data_len	= numd << 2,
 	};
nvme-ioctl.h +1 -1
index 8faf345..7818721 100644
@@ -62,7 +62,7 @@ int nvme_resv_register(int fd, __u32 nsid, __u8 rrega, __u8 cptpl,
 		       bool iekey, __u64 crkey, __u64 nrkey);
 int nvme_resv_release(int fd, __u32 nsid, __u8 rtype, __u8 rrela,
 		      bool iekey, __u64 crkey);
-int nvme_resv_report(int fd, __u32 nsid, __u32 numd, void *data);
+int nvme_resv_report(int fd, __u32 nsid, __u32 numd, __u32 cdw11, void *data);
 
 /* NVME_ADMIN_CMD */
 int nvme_passthru_admin(int fd, __u8 opcode, __u8 flags, __u16 rsvd,
nvme-print.c +75 -21

137 lines not on this page · raw message

nvme-print.h +2 -2
index d39bc63..fd89c96 100644
@@ -20,7 +20,7 @@ uint64_t int48_to_long(__u8 *data);
 void __show_nvme_id_ctrl(struct nvme_id_ctrl *ctrl, unsigned int mode, void (*vendor_show)(__u8 *vs, struct json_object *root));
 void show_nvme_id_ctrl(struct nvme_id_ctrl *ctrl, unsigned int mode);
 void show_nvme_id_ns(struct nvme_id_ns *ns, unsigned int flags);
-void show_nvme_resv_report(struct nvme_reservation_status *status);
+void show_nvme_resv_report(struct nvme_reservation_status *status, int bytes, __u32 cdw11);
 void show_lba_range(struct nvme_lba_range_type *lbrt, int nr_ranges);
 void show_error_log(struct nvme_error_log_page *err_log, int entries, const char *devname);
 void show_smart_log(struct nvme_smart_log *smart, unsigned int nsid, const char *devname);
@@ -35,7 +35,7 @@ char *nvme_feature_to_string(int feature);
 
 void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl, unsigned int mode, void (*vendor_show)(__u8 *vs, struct json_object *root));
 void json_nvme_id_ns(struct nvme_id_ns *ns, unsigned int flags);
-void json_nvme_resv_report(struct nvme_reservation_status *status);
+void json_nvme_resv_report(struct nvme_reservation_status *status, int bytes, __u32 cdw11);
 void json_error_log(struct nvme_error_log_page *err_log, int entries, const char *devname);
 void json_smart_log(struct nvme_smart_log *smart, unsigned int nsid, const char *devname);
 void json_fw_log(struct nvme_firmware_log_page *fw_log, const char *devname);
nvme.c +10 -3
index 62ddd17..b31483f 100644
@@ -2214,6 +2214,7 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
 		"namespace.";
 	const char *namespace_id = "identifier of desired namespace";
 	const char *numd = "number of dwords to transfer";
+	const char *cdw11 = "command dword 11 value";
 	const char *raw_binary = "dump output in binary format";
 
 	int err, fmt, fd;
@@ -2222,6 +2223,7 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
 	struct config {
 		__u32 namespace_id;
 		__u32 numd;
+		__u32 cdw11;
 		int   raw_binary;
 		char *output_format;
 	};
@@ -2229,12 +2231,14 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
 	struct config cfg = {
 		.namespace_id = 0,
 		.numd         = 0,
+		.cdw11	      = 0,
 		.output_format = "normal",
 	};
 
 	const struct argconfig_commandline_options command_line_options[] = {
 		{"namespace-id",  'n', "NUM", CFG_POSITIVE, &cfg.namespace_id,  required_argument, namespace_id},
 		{"numd",          'd', "NUM", CFG_POSITIVE, &cfg.numd,          required_argument, numd},
+		{"cdw11",         'c', "NUM", CFG_POSITIVE, &cfg.cdw11,         required_argument, cdw11},
 		{"raw-binary",    'b', "",    CFG_NONE,     &cfg.raw_binary,    no_argument,       raw_binary},
 		{"output-format", 'o', "FMT", CFG_STRING,   &cfg.output_format, required_argument, output_format },
 		{NULL}
@@ -2254,13 +2258,16 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
 		cfg.namespace_id = get_nsid(fd);
 	if (!cfg.numd || cfg.numd > (0x1000 >> 2))
 		cfg.numd = 0x1000 >> 2;
+	if (cfg.numd < 3)
+		cfg.numd = 3; /* get the header fields at least */
 
 	if (posix_memalign((void **)&status, getpagesize(), cfg.numd << 2)) {
 		fprintf(stderr, "No memory for resv report:%d\n", cfg.numd << 2);
 		return ENOMEM;
 	}
+	memset(status, 0, cfg.numd << 2);
 
-	err = nvme_resv_report(fd, cfg.namespace_id, cfg.numd, status);
+	err = nvme_resv_report(fd, cfg.namespace_id, cfg.numd, cfg.cdw11, status);
 	if (err < 0)
 		perror("reservation report");
 	else if (err != 0)
@@ -2269,10 +2276,10 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
 		if (fmt == BINARY)
 			d_raw((unsigned char *)status, cfg.numd << 2);
 		else if (fmt == JSON)
-			json_nvme_resv_report(status);
+			json_nvme_resv_report(status, cfg.numd << 2, cfg.cdw11);
 		else {
 			printf("NVME Reservation Report success\n");
-			show_nvme_resv_report(status);
+			show_nvme_resv_report(status, cfg.numd << 2, cfg.cdw11);
 		}
 	}
 	free(status);
Signature · 1 line
2.12.2
#1 lore raw

PATCH 1/1 nvme-cli: Extended Data Structure in resv-report

Quoted 5 lines · Steven

Allow user to specify cdw11 value to request Extended Data Structure. Update resv_report show and json functions to decode the returned data.

Signed-off-by Steve Schremmer <steve.schremmer at netapp.com>

Looks great, applied.

Also, thanks for the fix to the nvme_reservation structure.