diff --git a/module/bdev/nvme/bdev_nvme.c b/module/bdev/nvme/bdev_nvme.c index 413bcb8a77a..f69ee80d666 100644 --- a/module/bdev/nvme/bdev_nvme.c +++ b/module/bdev/nvme/bdev_nvme.c @@ -2539,12 +2539,45 @@ bdev_nvme_no_pi_readv(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, return rc; } +static inline enum spdk_bdev_io_memory_key_ctx_type +bdev_nvme_map_io_mkey_ctx_type(enum spdk_nvme_ns_cmd_io_memory_key_ctx_type nvme_ctx_type) { + + switch (nvme_ctx_type) + { + case SPDK_NVME_NS_CMD_MEMORY_KEY_CTX_PD: + return SPDK_BDEV_MEMORY_KEY_CTX_PD; + default: + SPDK_ERRLOG("Unknown get_mkey ctx type %d\n", nvme_ctx_type); + assert(0); + } +} + +static int bdev_nvme_ns_cmd_io_get_mkey(void *cb_arg, void *address, size_t length, + struct spdk_nvme_ns_cmd_io_memory_key_ctx *nvme_ctx) +{ + struct nvme_bdev_io *bio = cb_arg; + struct spdk_bdev_io *bdev_io = spdk_bdev_io_from_ctx(bio); + struct spdk_bdev_io_memory_key_ctx bdev_ctx = { + .ctx_type = bdev_nvme_map_io_mkey_ctx_type(nvme_ctx->ctx_type), + .ctx = nvme_ctx->ctx + }; + int rc; + + assert(bdev_io->opts.get_mkey_cb); + + rc = bdev_io->opts.get_mkey_cb(bdev_io->opts.get_mkey_cb_arg, address, length, &bdev_ctx); + nvme_ctx->mkey = bdev_ctx.mkey; + + return rc; +} + static int bdev_nvme_readv(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, struct nvme_bdev_io *bio, struct iovec *iov, int iovcnt, void *md, uint64_t lba_count, uint64_t lba, uint32_t flags) { int rc; + struct spdk_bdev_io *bdev_io = spdk_bdev_io_from_ctx(bio); SPDK_DEBUGLOG(bdev_nvme, "read %" PRIu64 " blocks with offset %#" PRIx64 "\n", lba_count, lba); @@ -2554,7 +2587,17 @@ bdev_nvme_readv(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, bio->iovpos = 0; bio->iov_offset = 0; - if (iovcnt == 1) { + if (bdev_io->opts.opts_size) { + struct spdk_nvme_ns_cmd_ext_io_opts opts = { + .opts_size = sizeof(struct spdk_nvme_ns_cmd_ext_io_opts), + .get_mkey_cb = bdev_io->opts.get_mkey_cb ? bdev_nvme_ns_cmd_io_get_mkey : NULL + }; + + rc = spdk_nvme_ns_cmd_readv_with_md_ext(ns, qpair, lba, lba_count, + bdev_nvme_readv_done, bio, flags, + bdev_nvme_queued_reset_sgl, bdev_nvme_queued_next_sge, + md, 0, 0, &opts); + } else if (iovcnt == 1) { rc = spdk_nvme_ns_cmd_read_with_md(ns, qpair, iov[0].iov_base, md, lba, lba_count, bdev_nvme_readv_done, bio, @@ -2580,6 +2623,7 @@ bdev_nvme_writev(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, uint32_t flags) { int rc; + struct spdk_bdev_io *bdev_io = spdk_bdev_io_from_ctx(bio); SPDK_DEBUGLOG(bdev_nvme, "write %" PRIu64 " blocks with offset %#" PRIx64 "\n", lba_count, lba); @@ -2589,7 +2633,17 @@ bdev_nvme_writev(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, bio->iovpos = 0; bio->iov_offset = 0; - if (iovcnt == 1) { + if (bdev_io->opts.opts_size) { + struct spdk_nvme_ns_cmd_ext_io_opts opts = { + .opts_size = sizeof(struct spdk_nvme_ns_cmd_ext_io_opts), + .get_mkey_cb = bdev_io->opts.get_mkey_cb ? bdev_nvme_ns_cmd_io_get_mkey : NULL + }; + + rc = spdk_nvme_ns_cmd_writev_with_md_ext(ns, qpair, lba, lba_count, + bdev_nvme_readv_done, bio, flags, + bdev_nvme_queued_reset_sgl, bdev_nvme_queued_next_sge, + md, 0, 0, &opts); + } else if (iovcnt == 1) { rc = spdk_nvme_ns_cmd_write_with_md(ns, qpair, iov[0].iov_base, md, lba, lba_count, bdev_nvme_readv_done, bio,