nvme: add support for verify command

Signed-off-by: Ziv Hirsch <zivhirsch13@gmail.com>
Change-Id: Ic9859d5078d9568bb28eefcf8fb70a7fc222ee15
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13928
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
This commit is contained in:
Ziv Hirsch 2022-08-09 13:14:05 +03:00 committed by Tomasz Zawadzki
parent 5c3360ce1f
commit eda407a6f0
6 changed files with 90 additions and 0 deletions

View File

@ -51,6 +51,8 @@ an engine.
Added SPDK_NVME_TRANSPORT_CUSTOM_FABRICS to enum spdk_nvme_transport_type to support custom
fabric transport. SPDK_NVME_TRANSPORT_CUSTOM was intended to be non-fabric custom transport.
Added a new function `spdk_nvme_ns_cmd_verify` to submit a Verify Command to a Namespace.
## v22.05
### sock

View File

@ -3123,6 +3123,32 @@ int spdk_nvme_ns_cmd_write_zeroes(struct spdk_nvme_ns *ns, struct spdk_nvme_qpai
spdk_nvme_cmd_cb cb_fn, void *cb_arg,
uint32_t io_flags);
/**
* Submit a verify I/O to the specified NVMe namespace.
*
* The command is submitted to a qpair allocated by spdk_nvme_ctrlr_alloc_io_qpair().
* The user must ensure that only one thread submits I/O on a given qpair at any
* given time.
*
* \param ns NVMe namespace to submit the verify I/O.
* \param qpair I/O queue pair to submit the request.
* \param lba Starting LBA to verify the data.
* \param lba_count Length (in sectors) for the verify operation.
* \param cb_fn Callback function to invoke when the I/O is completed.
* \param cb_arg Argument to pass to the callback function.
* \param io_flags Set flags, defined by the SPDK_NVME_IO_FLAGS_* entries in
* spdk/nvme_spec.h, for this I/O.
*
* \return 0 if successfully submitted, negated errnos on the following error conditions:
* -EINVAL: The request is malformed.
* -ENOMEM: The request cannot be allocated.
* -ENXIO: The qpair is failed at the transport level.
*/
int spdk_nvme_ns_cmd_verify(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
uint64_t lba, uint32_t lba_count,
spdk_nvme_cmd_cb cb_fn, void *cb_arg,
uint32_t io_flags);
/**
* Submit a write uncorrectable I/O to the specified NVMe namespace.
*

View File

@ -1540,6 +1540,7 @@ enum spdk_nvme_nvm_opcode {
SPDK_NVME_OPC_WRITE_ZEROES = 0x08,
SPDK_NVME_OPC_DATASET_MANAGEMENT = 0x09,
SPDK_NVME_OPC_VERIFY = 0x0c,
SPDK_NVME_OPC_RESERVATION_REGISTER = 0x0d,
SPDK_NVME_OPC_RESERVATION_REPORT = 0x0e,

View File

@ -1087,6 +1087,40 @@ spdk_nvme_ns_cmd_write_zeroes(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *q
return nvme_qpair_submit_request(qpair, req);
}
int
spdk_nvme_ns_cmd_verify(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
uint64_t lba, uint32_t lba_count,
spdk_nvme_cmd_cb cb_fn, void *cb_arg,
uint32_t io_flags)
{
struct nvme_request *req;
struct spdk_nvme_cmd *cmd;
if (!_is_io_flags_valid(io_flags)) {
return -EINVAL;
}
if (lba_count == 0 || lba_count > UINT16_MAX + 1) {
return -EINVAL;
}
req = nvme_allocate_request_null(qpair, cb_fn, cb_arg);
if (req == NULL) {
return -ENOMEM;
}
cmd = &req->cmd;
cmd->opc = SPDK_NVME_OPC_VERIFY;
cmd->nsid = ns->id;
*(uint64_t *)&cmd->cdw10 = lba;
cmd->cdw12 = lba_count - 1;
cmd->fuse = (io_flags & SPDK_NVME_IO_FLAGS_FUSE_MASK);
cmd->cdw12 |= (io_flags & SPDK_NVME_IO_FLAGS_CDW12_MASK);
return nvme_qpair_submit_request(qpair, req);
}
int
spdk_nvme_ns_cmd_write_uncorrectable(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
uint64_t lba, uint32_t lba_count,

View File

@ -167,6 +167,7 @@
spdk_nvme_ns_cmd_compare_with_md;
spdk_nvme_ns_cmd_writev_ext;
spdk_nvme_ns_cmd_readv_ext;
spdk_nvme_ns_cmd_verify;
spdk_nvme_qpair_get_optimal_poll_group;
spdk_nvme_qpair_process_completions;

View File

@ -2204,6 +2204,31 @@ test_spdk_nvme_ns_cmd_readv_ext(void)
cleanup_after_test(&qpair);
}
static void
test_nvme_ns_cmd_verify(void)
{
struct spdk_nvme_ns ns;
struct spdk_nvme_ctrlr ctrlr;
struct spdk_nvme_qpair qpair;
uint64_t cmd_lba;
uint32_t cmd_lba_count;
int rc;
prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 0, false);
rc = spdk_nvme_ns_cmd_verify(&ns, &qpair, 0, 2, NULL, NULL, 0);
CU_ASSERT(rc == 0);
SPDK_CU_ASSERT_FATAL(g_request != NULL);
CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_VERIFY);
CU_ASSERT(g_request->cmd.nsid == ns.id);
nvme_cmd_interpret_rw(&g_request->cmd, &cmd_lba, &cmd_lba_count);
CU_ASSERT_EQUAL(cmd_lba, 0);
CU_ASSERT_EQUAL(cmd_lba_count, 2);
nvme_free_request(g_request);
cleanup_after_test(&qpair);
}
int
main(int argc, char **argv)
{
@ -2244,6 +2269,7 @@ main(int argc, char **argv)
CU_ADD_TEST(suite, test_spdk_nvme_ns_cmd_readv_with_md);
CU_ADD_TEST(suite, test_spdk_nvme_ns_cmd_writev_ext);
CU_ADD_TEST(suite, test_spdk_nvme_ns_cmd_readv_ext);
CU_ADD_TEST(suite, test_nvme_ns_cmd_verify);
g_spdk_nvme_driver = &_g_nvme_driver;