From: Steven Seungcheol Lee Date: Mon, 13 Feb 2023 06:53:09 +0000 (+0900) Subject: types: Add ns-mgmt host software specified fields X-Git-Tag: v1.5~59 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=5ac91b716ca9e6872660d037f6b366abfccbb234;p=users%2Fsagi%2Flibnvme.git types: Add ns-mgmt host software specified fields nphndls, phndl from TP4146 Flexible Data Placement 2022.11.30 Ratified Reviewed-by: Daniel Wagner Signed-off-by: Steven Seungcheol Lee --- diff --git a/src/nvme/api-types.h b/src/nvme/api-types.h index 9f3604ee..296a7b06 100644 --- a/src/nvme/api-types.h +++ b/src/nvme/api-types.h @@ -196,6 +196,9 @@ struct nvme_format_nvm_args { * @nsid: Namespace identifier * @sel: Type of management operation to perform * @csi: Command Set Identifier + * @rsvd1: Reserved + * @rsvd2: Reserved + * @data: Host Software Specified Fields */ struct nvme_ns_mgmt_args { __u32 *result; @@ -206,6 +209,9 @@ struct nvme_ns_mgmt_args { __u32 nsid; enum nvme_ns_mgmt_sel sel; __u8 csi; + __u8 rsvd1[3]; + void *rsvd2; + struct nvme_ns_mgmt_host_sw_specified *data; }; /** diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 2b5e09dd..884554de 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1235,9 +1235,15 @@ int nvme_format_nvm(struct nvme_format_nvm_args *args) int nvme_ns_mgmt(struct nvme_ns_mgmt_args *args) { + const size_t size_v1 = sizeof_args(struct nvme_ns_mgmt_args, csi, __u64); + const size_t size_v2 = sizeof_args(struct nvme_ns_mgmt_args, data, __u64); __u32 cdw10 = NVME_SET(args->sel, NAMESPACE_MGMT_CDW10_SEL); __u32 cdw11 = NVME_SET(args->csi, NAMESPACE_MGMT_CDW11_CSI); - __u32 data_len = args->ns ? sizeof(*args->ns) : 0; + + if (args->args_size < size_v1 || args->args_size > size_v2) { + errno = EINVAL; + return -1; + } struct nvme_passthru_cmd cmd = { .nsid = args->nsid, @@ -1245,13 +1251,19 @@ int nvme_ns_mgmt(struct nvme_ns_mgmt_args *args) .cdw10 = cdw10, .cdw11 = cdw11, .timeout_ms = args->timeout, - .data_len = data_len, - .addr = (__u64)(uintptr_t)args->ns, }; - if (args->args_size < sizeof(*args)) { - errno = EINVAL; - return -1; + if (args->args_size == size_v2) { + if (args->data) { + cmd.data_len = sizeof(*args->data); + cmd.addr = (__u64)(uintptr_t)args->data; + } + } + else { + if (args->ns) { + cmd.data_len = sizeof(*args->ns); + cmd.addr = (__u64)(uintptr_t)args->ns; + } } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 32e722e3..ee451f69 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3036,6 +3036,7 @@ int nvme_ns_mgmt(struct nvme_ns_mgmt_args *args); * @timeout: Override the default timeout to this value in milliseconds; * set to 0 to use the system default. * @csi: Command Set Identifier + * @data: Host Software Specified Fields that defines ns creation parameters * * On successful creation, the namespace exists in the subsystem, but is not * attached to any controller. Use the nvme_ns_attach_ctrls() to assign the @@ -3045,7 +3046,8 @@ int nvme_ns_mgmt(struct nvme_ns_mgmt_args *args); * &enum nvme_status_field) or -1 with errno set otherwise. */ static inline int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, - __u32 *nsid, __u32 timeout, __u8 csi) + __u32 *nsid, __u32 timeout, __u8 csi, + struct nvme_ns_mgmt_host_sw_specified *data) { struct nvme_ns_mgmt_args args = { .result = nsid, @@ -3056,6 +3058,7 @@ static inline int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, .nsid = NVME_NSID_NONE, .sel = NVME_NS_MGMT_SEL_CREATE, .csi = csi, + .data = data, }; return nvme_ns_mgmt(&args); diff --git a/src/nvme/mi.c b/src/nvme/mi.c index 391ba1a3..6b20edc4 100644 --- a/src/nvme/mi.c +++ b/src/nvme/mi.c @@ -1077,14 +1077,19 @@ int nvme_mi_admin_set_features(nvme_mi_ctrl_t ctrl, int nvme_mi_admin_ns_mgmt(nvme_mi_ctrl_t ctrl, struct nvme_ns_mgmt_args *args) { + const size_t size_v1 = sizeof_args(struct nvme_ns_mgmt_args, csi, __u64); + const size_t size_v2 = sizeof_args(struct nvme_ns_mgmt_args, data, __u64); struct nvme_mi_admin_resp_hdr resp_hdr; struct nvme_mi_admin_req_hdr req_hdr; struct nvme_mi_resp resp; struct nvme_mi_req req; int rc; + size_t data_len; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < size_v1 || args->args_size > size_v2) { + errno = EINVAL; + return -1; + } nvme_mi_admin_init_req(&req, &req_hdr, ctrl->id, nvme_admin_ns_mgmt); @@ -1092,10 +1097,23 @@ int nvme_mi_admin_ns_mgmt(nvme_mi_ctrl_t ctrl, req_hdr.cdw1 = cpu_to_le32(args->nsid); req_hdr.cdw10 = cpu_to_le32(args->sel & 0xf); req_hdr.cdw11 = cpu_to_le32(args->csi << 24); - if (args->ns) { - req.data = args->ns; - req.data_len = sizeof(*args->ns); - req_hdr.dlen = cpu_to_le32(sizeof(*args->ns)); + + if (args->args_size == size_v2) { + if (args->data) { + req.data = args->data; + data_len = sizeof(*args->data); + } + } + else { + if (args->ns) { + req.data = args->ns; + data_len = sizeof(*args->ns); + } + } + + if (req.data) { + req.data_len = data_len; + req_hdr.dlen = cpu_to_le32(data_len); req_hdr.flags = 0x1; } diff --git a/src/nvme/mi.h b/src/nvme/mi.h index 12dbf6fb..d22e1a5d 100644 --- a/src/nvme/mi.h +++ b/src/nvme/mi.h @@ -2451,6 +2451,7 @@ int nvme_mi_admin_ns_mgmt(nvme_mi_ctrl_t ctrl, * @ns: New namespace parameters * @csi: Command Set Identifier for new NS * @nsid: Set to new namespace ID on create + * @data: Host Software Specified Fields that defines ns creation parameters * * Issues a Namespace Management (Create) command to @ctrl, to create a * new namespace specified by @ns, using command set @csi. On success, @@ -2460,8 +2461,8 @@ int nvme_mi_admin_ns_mgmt(nvme_mi_ctrl_t ctrl, * &enum nvme_status_field) or -1 with errno set otherwise. */ static inline int nvme_mi_admin_ns_mgmt_create(nvme_mi_ctrl_t ctrl, - struct nvme_id_ns *ns, - __u8 csi, __u32 *nsid) + struct nvme_id_ns *ns, __u8 csi, __u32 *nsid, + struct nvme_ns_mgmt_host_sw_specified *data) { struct nvme_ns_mgmt_args args = { .result = nsid, @@ -2470,6 +2471,7 @@ static inline int nvme_mi_admin_ns_mgmt_create(nvme_mi_ctrl_t ctrl, .nsid = NVME_NSID_NONE, .sel = NVME_NS_MGMT_SEL_CREATE, .csi = csi, + .data = data, }; return nvme_mi_admin_ns_mgmt(ctrl, &args); diff --git a/src/nvme/types.h b/src/nvme/types.h index 3cc407f6..8d78cc40 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -7651,4 +7651,64 @@ enum nvme_io_mgmt_send_mo { NVME_IO_MGMT_SEND_RUH_UPDATE = 0x1, }; +/** + * struct nvme_ns_mgmt_host_sw_specified - Namespace management Host Software + * Specified Fields. + * @nsze: Namespace Size indicates the total size of the namespace in + * logical blocks. The number of logical blocks is based on the + * formatted LBA size. + * @ncap: Namespace Capacity indicates the maximum number of logical blocks + * that may be allocated in the namespace at any point in time. The + * number of logical blocks is based on the formatted LBA size. + * @rsvd16: Reserved + * @flbas: Formatted LBA Size, see &enum nvme_id_ns_flbas. + * @rsvd27: Reserved + * @dps: End-to-end Data Protection Type Settings, see + * &enum nvme_id_ns_dps. + * @nmic: Namespace Multi-path I/O and Namespace Sharing Capabilities, see + * &enum nvme_id_ns_nmic. + * @rsvd31: Reserved + * @anagrpid: ANA Group Identifier indicates the ANA Group Identifier of the + * ANA group of which the namespace is a member. + * @rsvd96: Reserved + * @nvmsetid: NVM Set Identifier indicates the NVM Set with which this + * namespace is associated. + * @endgid: Endurance Group Identifier indicates the Endurance Group with + * which this namespace is associated. + * @rsvd104: Reserved + * @lbstm: Logical Block Storage Tag Mask Identifies the mask for the + * Storage Tag field for the protection information + * @nphndls: Number of Placement Handles specifies the number of Placement + * Handles included in the Placement Handle List + * @rsvd394: Reserved + * @rsvd499: Reserved for I/O Command Sets that extend this specification. + * @phndl: Placement Handle Associated RUH : This field specifies the Reclaim + * Unit Handle Identifier to be associated with the Placement Handle + * value. If the Flexible Data Placement capability is not supported or + * not enabled in specified Endurance Group, then the controller shall + * ignore this field. + * @rsvd768: Reserved + */ +struct nvme_ns_mgmt_host_sw_specified { + __le64 nsze; + __le64 ncap; + __u8 rsvd16[10]; + __u8 flbas; + __u8 rsvd27[2]; + __u8 dps; + __u8 nmic; + __u8 rsvd31[61]; + __le32 anagrpid; + __u8 rsvd96[4]; + __le16 nvmsetid; + __le16 endgid; + __u8 rsvd104[280]; + __le64 lbstm; + __le16 nphndls; + __u8 rsvd394[105]; + __u8 rsvd499[13]; + __le16 phndl[128]; + __u8 rsvd768[3328]; +}; + #endif /* _LIBNVME_TYPES_H */ diff --git a/test/mi.c b/test/mi.c index 5bbb2f06..7f8e0052 100644 --- a/test/mi.c +++ b/test/mi.c @@ -1291,7 +1291,7 @@ static int test_admin_ns_mgmt_cb(struct nvme_mi_ep *ep, void *data) { __u8 *rq_hdr, *rs_hdr, sel, csi; - struct nvme_id_ns *id; + struct nvme_ns_mgmt_host_sw_specified *create_data; __u32 nsid; rq_hdr = (__u8 *)req->hdr; @@ -1305,15 +1305,15 @@ static int test_admin_ns_mgmt_cb(struct nvme_mi_ep *ep, switch (sel) { case NVME_NS_MGMT_SEL_CREATE: - assert(req->data_len == sizeof(struct nvme_id_ns)); - id = req->data; + assert(req->data_len == sizeof(struct nvme_ns_mgmt_host_sw_specified)); + create_data = req->data; /* No NSID on created namespaces */ assert(nsid == 0); assert(csi == 0); /* allow operations on nsze == 42, reject others */ - if (le64_to_cpu(id->nsze) != 42) { + if (le64_to_cpu(create_data->nsze) != 42) { rs_hdr[4] = 0; /* response cdw0 is created NSID */ rs_hdr[8] = 0x04; @@ -1342,7 +1342,7 @@ static int test_admin_ns_mgmt_cb(struct nvme_mi_ep *ep, static void test_admin_ns_mgmt_create(struct nvme_mi_ep *ep) { - struct nvme_id_ns nsid = { 0 }; + struct nvme_ns_mgmt_host_sw_specified data = { 0 }; nvme_mi_ctrl_t ctrl; __u32 ns; int rc; @@ -1352,12 +1352,12 @@ static void test_admin_ns_mgmt_create(struct nvme_mi_ep *ep) ctrl = nvme_mi_init_ctrl(ep, 5); assert(ctrl); - rc = nvme_mi_admin_ns_mgmt_create(ctrl, &nsid, 0, &ns); + rc = nvme_mi_admin_ns_mgmt_create(ctrl, NULL, 0, &ns, &data); assert(!rc); assert(ns == 0x01020304); - nsid.nsze = cpu_to_le64(42); - rc = nvme_mi_admin_ns_mgmt_create(ctrl, &nsid, 0, &ns); + data.nsze = cpu_to_le64(42); + rc = nvme_mi_admin_ns_mgmt_create(ctrl, NULL, 0, &ns, &data); assert(rc); }