]> www.infradead.org Git - users/sagi/libnvme.git/commitdiff
types: Add ns-mgmt host software specified fields
authorSteven Seungcheol Lee <sc108.lee@samsung.com>
Mon, 13 Feb 2023 06:53:09 +0000 (15:53 +0900)
committerDaniel Wagner <wagi@monom.org>
Wed, 5 Apr 2023 11:58:04 +0000 (13:58 +0200)
nphndls, phndl from TP4146 Flexible Data Placement 2022.11.30 Ratified

Reviewed-by: Daniel Wagner <dwagner@suse.de>
Signed-off-by: Steven Seungcheol Lee <sc108.lee@samsung.com>
src/nvme/api-types.h
src/nvme/ioctl.c
src/nvme/ioctl.h
src/nvme/mi.c
src/nvme/mi.h
src/nvme/types.h
test/mi.c

index 9f3604ee86a11dbfab67aa5c4dd7316a317ecd1b..296a7b06b38cc5462d51e737238f28b63a3fd722 100644 (file)
@@ -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;
 };
 
 /**
index 2b5e09ddb3ca2cec7f8d32b605022196ca99a86c..884554de98191043712fd905cb9c03550e7dd287 100644 (file)
@@ -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);
 }
index 32e722e384ae0001e99d48159c3c8540dcfe7501..ee451f69607e0b2ad077bf41369316276a8631f3 100644 (file)
@@ -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);
index 391ba1a3f3d62c05492892dc729342ba924a543b..6b20edc40065aeb746056424f735166a89551f63 100644 (file)
@@ -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;
        }
 
index 12dbf6fb8f48db07e822d79f91052a9dea6e89d0..d22e1a5d726a9f91dc31f161009e480ade4111f4 100644 (file)
@@ -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);
index 3cc407f6eb7bc5e21915aae8c4b5e2a188ec122d..8d78cc4071580ab1d4745270db6d17c67db2a05c 100644 (file)
@@ -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 */
index 5bbb2f067f3f1af0583a83016e9722b4984380d3..7f8e005252e31e80e7801b0042286cd5a58c43ff 100644 (file)
--- 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);
 }