2022-03-21 15:01:24 +00:00
|
|
|
#include <sys/endian.h>
|
|
|
|
|
2022-03-28 16:47:46 +00:00
|
|
|
#include "storage/drivers/nvme.hh"
|
2022-03-21 15:01:24 +00:00
|
|
|
#include "ntr.h"
|
|
|
|
#include "spdk/bdev.h"
|
|
|
|
#include "spdk/nvme.h"
|
|
|
|
#include "spdk/nvme_spec.h"
|
|
|
|
#include "spdk/thread.h"
|
|
|
|
|
|
|
|
birb_nvme_thread_context::birb_nvme_thread_context(birb_nvme_driver * driver) : status(birb_driver::BIRB_FAIL),
|
|
|
|
driver(driver),
|
|
|
|
qpair(nullptr)
|
|
|
|
{
|
|
|
|
struct spdk_nvme_ctrlr * ctrlr = driver->get_ctrlr();
|
|
|
|
struct spdk_nvme_qpair * qpair = spdk_nvme_ctrlr_alloc_io_qpair(ctrlr, driver->get_io_qpair_opts(), sizeof(struct spdk_nvme_io_qpair_opts));
|
|
|
|
if (qpair == nullptr) {
|
|
|
|
ntr(NTR_DEP_USER1, NTR_LEVEL_ERROR, "birb_nvme_thread_context: could not allocate qpairs.\n");
|
|
|
|
} else {
|
|
|
|
this->qpair = qpair;
|
|
|
|
status = birb_driver::BIRB_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
birb_driver::birb_driver_status
|
|
|
|
birb_nvme_thread_context::get_status()
|
|
|
|
{
|
|
|
|
return this->status;
|
|
|
|
}
|
|
|
|
|
|
|
|
birb_nvme_thread_context::~birb_nvme_thread_context()
|
|
|
|
{
|
|
|
|
if (this->qpair != nullptr) {
|
|
|
|
spdk_nvme_ctrlr_free_io_qpair(this->qpair);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Callback function for io completion.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
birb_nvme_thread_context::io_callback(void *arg, const struct spdk_nvme_cpl *completion)
|
|
|
|
{
|
|
|
|
bool success = !spdk_nvme_cpl_is_error(completion);
|
|
|
|
auto ctx = reinterpret_cast<struct cb_context *>(arg);
|
|
|
|
ctx->cb(success, ctx->ctx);
|
|
|
|
delete ctx;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t
|
|
|
|
birb_nvme_thread_context::size_to_lba(size_t size, int lba_size)
|
|
|
|
{
|
|
|
|
return (size - 1) / lba_size + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
birb_nvme_thread_context::addr_to_lba(size_t addr, int lba_size)
|
|
|
|
{
|
|
|
|
return addr / lba_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
birb_nvme_thread_context::read(size_t offset, size_t size, char * buffer, callback callback, void * context)
|
|
|
|
{
|
|
|
|
auto ctx = new struct cb_context;
|
|
|
|
ctx->cb = callback;
|
|
|
|
ctx->ctx = context;
|
|
|
|
|
|
|
|
struct spdk_nvme_ns * ns = this->driver->get_ns();
|
|
|
|
int lba_size = spdk_nvme_ns_get_sector_size(ns);
|
|
|
|
return spdk_nvme_ns_cmd_read(ns, this->qpair, buffer, addr_to_lba(offset, lba_size), size_to_lba(size, lba_size), io_callback, reinterpret_cast<void*>(ctx), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
birb_nvme_thread_context::write(size_t offset, size_t size, char * buffer, callback callback, void * context)
|
|
|
|
{
|
|
|
|
auto ctx = new struct cb_context;
|
|
|
|
ctx->cb = callback;
|
|
|
|
ctx->ctx = context;
|
|
|
|
|
|
|
|
struct spdk_nvme_ns * ns = this->driver->get_ns();
|
|
|
|
int lba_size = spdk_nvme_ns_get_sector_size(ns);
|
|
|
|
|
|
|
|
return spdk_nvme_ns_cmd_write(ns, this->qpair, buffer, addr_to_lba(offset, lba_size), size_to_lba(size, lba_size), io_callback, reinterpret_cast<void*>(ctx), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
birb_nvme_thread_context::poll()
|
|
|
|
{
|
|
|
|
spdk_nvme_qpair_process_completions(this->qpair, 0);
|
|
|
|
}
|