nvme: add support for write zeroes command
Change-Id: I07ae5805c434d3c06ac24c1a8e09c761b5506ff4 Signed-off-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
5578f74dd4
commit
20c767e796
@ -365,6 +365,7 @@ enum nvme_namespace_flags {
|
||||
NVME_NS_DEALLOCATE_SUPPORTED = 0x1, /**< The deallocate command is supported */
|
||||
NVME_NS_FLUSH_SUPPORTED = 0x2, /**< The flush command is supported */
|
||||
NVME_NS_RESERVATION_SUPPORTED = 0x4, /**< The reservation command is supported */
|
||||
NVME_NS_WRITE_ZEROES_SUPPORTED = 0x8, /**< The write zeroes command is supported */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -440,6 +441,27 @@ int nvme_ns_cmd_writev(struct nvme_namespace *ns, uint64_t lba, uint32_t lba_cou
|
||||
nvme_req_reset_sgl_fn_t reset_sgl_fn,
|
||||
nvme_req_next_sge_fn_t next_sge_fn);
|
||||
|
||||
/**
|
||||
* \brief Submits a write zeroes I/O to the specified NVMe namespace.
|
||||
*
|
||||
* \param ns NVMe namespace to submit the write zeroes I/O
|
||||
* \param lba starting LBA for this command
|
||||
* \param lba_count length (in sectors) for the write zero 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 NVME_IO_FLAGS_* entries
|
||||
* in spdk/nvme_spec.h, for this I/O.
|
||||
*
|
||||
* \return 0 if successfully submitted, ENOMEM if an nvme_request
|
||||
* structure cannot be allocated for the I/O request
|
||||
*
|
||||
* This function is thread safe and can be called at any point after
|
||||
* nvme_register_io_thread().
|
||||
*/
|
||||
int nvme_ns_cmd_write_zeroes(struct nvme_namespace *ns, uint64_t lba,
|
||||
uint32_t lba_count, nvme_cb_fn_t cb_fn, void *cb_arg,
|
||||
uint32_t io_flags);
|
||||
|
||||
/**
|
||||
* \brief Submits a read I/O to the specified NVMe namespace.
|
||||
*
|
||||
|
@ -126,6 +126,10 @@ nvme_ns_construct(struct nvme_namespace *ns, uint16_t id,
|
||||
ns->flags |= NVME_NS_FLUSH_SUPPORTED;
|
||||
}
|
||||
|
||||
if (ctrlr->cdata.oncs.write_zeroes) {
|
||||
ns->flags |= NVME_NS_WRITE_ZEROES_SUPPORTED;
|
||||
}
|
||||
|
||||
if (nsdata->nsrescap.raw) {
|
||||
ns->flags |= NVME_NS_RESERVATION_SUPPORTED;
|
||||
}
|
||||
|
@ -258,6 +258,38 @@ nvme_ns_cmd_writev(struct nvme_namespace *ns, uint64_t lba, uint32_t lba_count,
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
nvme_ns_cmd_write_zeroes(struct nvme_namespace *ns, uint64_t lba,
|
||||
uint32_t lba_count, nvme_cb_fn_t cb_fn, void *cb_arg,
|
||||
uint32_t io_flags)
|
||||
{
|
||||
struct nvme_request *req;
|
||||
struct nvme_command *cmd;
|
||||
uint64_t *tmp_lba;
|
||||
|
||||
if (lba_count == 0) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
req = nvme_allocate_request_null(cb_fn, cb_arg);
|
||||
if (req == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
cmd = &req->cmd;
|
||||
cmd->opc = NVME_OPC_WRITE_ZEROES;
|
||||
cmd->nsid = ns->id;
|
||||
|
||||
tmp_lba = (uint64_t *)&cmd->cdw10;
|
||||
*tmp_lba = lba;
|
||||
cmd->cdw12 = lba_count - 1;
|
||||
cmd->cdw12 |= io_flags;
|
||||
|
||||
nvme_ctrlr_submit_io_request(ns->ctrlr, req);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nvme_ns_cmd_deallocate(struct nvme_namespace *ns, void *payload,
|
||||
uint16_t num_ranges, nvme_cb_fn_t cb_fn, void *cb_arg)
|
||||
|
@ -331,6 +331,28 @@ test_nvme_ns_cmd_flush(void)
|
||||
nvme_free_request(g_request);
|
||||
}
|
||||
|
||||
static void
|
||||
test_nvme_ns_cmd_write_zeroes(void)
|
||||
{
|
||||
struct nvme_namespace ns = { 0 };
|
||||
struct nvme_controller ctrlr = { 0 };
|
||||
nvme_cb_fn_t cb_fn = NULL;
|
||||
void *cb_arg = NULL;
|
||||
uint64_t cmd_lba;
|
||||
uint32_t cmd_lba_count;
|
||||
|
||||
prepare_for_test(&ns, &ctrlr, 512, 128 * 1024, 0);
|
||||
|
||||
nvme_ns_cmd_write_zeroes(&ns, 0, 2, cb_fn, cb_arg, 0);
|
||||
CU_ASSERT(g_request->cmd.opc == NVME_OPC_WRITE_ZEROES);
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
test_nvme_ns_cmd_deallocate(void)
|
||||
{
|
||||
@ -426,6 +448,7 @@ int main(int argc, char **argv)
|
||||
|| CU_add_test(suite, "nvme_ns_cmd_flush testing", test_nvme_ns_cmd_flush) == NULL
|
||||
|| CU_add_test(suite, "nvme_ns_cmd_deallocate testing", test_nvme_ns_cmd_deallocate) == NULL
|
||||
|| CU_add_test(suite, "io_flags", test_io_flags) == NULL
|
||||
|| CU_add_test(suite, "nvme_ns_cmd_write_zeroes testing", test_nvme_ns_cmd_write_zeroes) == NULL
|
||||
) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
|
Loading…
Reference in New Issue
Block a user