#include #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(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(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(&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; }