numam/storage/drivers/nvme.cc

136 lines
3.3 KiB
C++

#include <sys/endian.h>
#include "ntr.h"
#include "spdk/nvme.h"
#include "spdk/thread.h"
#include "storage/drivers/nvme.hh"
size_t
birb_nvme_driver::get_capacity()
{
return spdk_nvme_ns_get_size(this->ns);
}
birb_driver::birb_driver_status
birb_nvme_driver::get_status()
{
return this->status;
}
void
birb_nvme_driver::attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_ctrlr_opts *opts UNUSED)
{
struct spdk_nvme_ns * ns;
auto ctx = reinterpret_cast<struct attach_context *>(cb_ctx);
ntr(NTR_DEP_USER1, NTR_LEVEL_INFO, "birb_nvme_driver: attached to nvme at %s\n", trid->traddr);
for (int nsid = spdk_nvme_ctrlr_get_first_active_ns(ctrlr); nsid != 0;
nsid = spdk_nvme_ctrlr_get_next_active_ns(ctrlr, nsid)) {
ns = spdk_nvme_ctrlr_get_ns(ctrlr, nsid);
if (ns == nullptr || !spdk_nvme_ns_is_active(ns)) {
continue;
}
ntr(NTR_DEP_USER1, NTR_LEVEL_INFO, "birb_nvme_driver: namespace id: %d size: %zu LBA size: %u\n", spdk_nvme_ns_get_id(ns), spdk_nvme_ns_get_size(ns), spdk_nvme_ns_get_sector_size(ns));
/* XXX: use the first namespace */
break;
}
*ctx->ns = ns;
*ctx->ctrlr = ctrlr;
ctx->valid = 1;
}
bool
birb_nvme_driver::probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
struct spdk_nvme_ctrlr_opts *opts UNUSED)
{
printf("birb_nvme_driver: found nvme at %s\n", trid->traddr);
auto ctx = reinterpret_cast<struct attach_context *>(cb_ctx);
if (strcmp(trid->traddr, ctx->dev_name) == 0) {
return true;
}
return false;
}
birb_nvme_driver::birb_nvme_driver(const char * dev_name) : status(BIRB_FAIL),
ctrlr(nullptr),
ns(nullptr),
opts()
{
int rc;
struct spdk_nvme_transport_id trid;
struct attach_context ctx;
ctx.ctrlr = &this->ctrlr;
ctx.ns = &this->ns;
ctx.dev_name = dev_name;
ctx.valid = 0;
spdk_nvme_trid_populate_transport(&trid, SPDK_NVME_TRANSPORT_PCIE);
snprintf(trid.subnqn, sizeof(trid.subnqn), "%s", SPDK_NVMF_DISCOVERY_NQN);
rc = spdk_nvme_probe(&trid, reinterpret_cast<void *>(&ctx), probe_cb, attach_cb, nullptr);
if (rc != 0) {
ntr(NTR_DEP_USER1, NTR_LEVEL_ERROR, "birb_nvme_driver: failed to probe nvme device: %d\n", rc);
goto end;
}
if (ctx.valid != 1) {
rc = EINVAL;
ntr(NTR_DEP_USER1, NTR_LEVEL_ERROR, "birb_nvme_driver: could not find device: %s\n", dev_name);
goto end;
}
if (spdk_nvme_ns_get_csi(this->ns) == SPDK_NVME_CSI_ZNS) {
ntr(NTR_DEP_USER1, NTR_LEVEL_ERROR, "birb_nvme_driver: zoned nvme namespace is unsupported\n");
spdk_nvme_detach(this->ctrlr);
goto end;
} else {
spdk_nvme_ctrlr_get_default_io_qpair_opts(ctrlr, &this->opts, sizeof(this->opts));
ntr(NTR_DEP_USER1, NTR_LEVEL_INFO, "birb_nvme_driver: io queue depth: %d io queue requests: %d\n", opts.io_queue_size, opts.io_queue_requests);
this->status = BIRB_SUCCESS;
}
end:
return;
}
birb_nvme_driver::~birb_nvme_driver()
{
if (this->ctrlr != nullptr) {
spdk_nvme_detach(this->ctrlr);
}
}
birb_driver::birb_driver_type
birb_nvme_driver::get_type()
{
return BIRB_DRV_NVME;
}
size_t
birb_nvme_driver::get_align()
{
return 0x1000;
}
spdk_nvme_ctrlr *
birb_nvme_driver::get_ctrlr()
{
return this->ctrlr;
}
spdk_nvme_ns *
birb_nvme_driver::get_ns()
{
return this->ns;
}
spdk_nvme_io_qpair_opts *
birb_nvme_driver::get_io_qpair_opts()
{
return &this->opts;
}