nvmf: Transports are no longer global
Create one transport per nvmf target. Today, there is just one global nvmf target, but this paves the way for multiple. Change-Id: Iaa1f8c5e7b3c1e87621ef2a636c68c2dd8fd929e Signed-off-by: Ben Walker <benjamin.walker@intel.com> Reviewed-on: https://review.gerrithub.io/371748 Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com> Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
parent
269910c05c
commit
31d033f944
@ -263,7 +263,7 @@ nvmf_tgt_shutdown_subsystem_by_nqn(const char *nqn)
|
||||
static void
|
||||
acceptor_poll(void *arg)
|
||||
{
|
||||
spdk_nvmf_acceptor_poll();
|
||||
spdk_nvmf_tgt_poll();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -167,7 +167,7 @@ int spdk_nvmf_subsystem_set_sn(struct spdk_nvmf_subsystem *subsystem, const char
|
||||
const char *spdk_nvmf_subsystem_get_nqn(struct spdk_nvmf_subsystem *subsystem);
|
||||
enum spdk_nvmf_subtype spdk_nvmf_subsystem_get_type(struct spdk_nvmf_subsystem *subsystem);
|
||||
|
||||
void spdk_nvmf_acceptor_poll(void);
|
||||
void spdk_nvmf_tgt_poll(void);
|
||||
|
||||
void spdk_nvmf_handle_connect(struct spdk_nvmf_request *req);
|
||||
|
||||
|
@ -163,7 +163,7 @@ nvmf_init_nvme_ctrlr_properties(struct spdk_nvmf_ctrlr *ctrlr)
|
||||
static void ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr)
|
||||
{
|
||||
TAILQ_REMOVE(&ctrlr->subsys->ctrlrs, ctrlr, link);
|
||||
ctrlr->transport->ctrlr_fini(ctrlr);
|
||||
ctrlr->transport->ops->ctrlr_fini(ctrlr);
|
||||
}
|
||||
|
||||
void
|
||||
@ -174,7 +174,7 @@ spdk_nvmf_ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr)
|
||||
|
||||
TAILQ_REMOVE(&ctrlr->qpairs, qpair, link);
|
||||
ctrlr->num_qpairs--;
|
||||
qpair->transport->qpair_fini(qpair);
|
||||
qpair->transport->ops->qpair_fini(qpair);
|
||||
}
|
||||
|
||||
ctrlr_destruct(ctrlr);
|
||||
@ -288,7 +288,7 @@ spdk_nvmf_ctrlr_connect(struct spdk_nvmf_qpair *qpair,
|
||||
}
|
||||
|
||||
/* Establish a new ctrlr */
|
||||
ctrlr = qpair->transport->ctrlr_init();
|
||||
ctrlr = qpair->transport->ops->ctrlr_init(qpair->transport);
|
||||
if (ctrlr == NULL) {
|
||||
SPDK_ERRLOG("Memory allocation failure\n");
|
||||
rsp->status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR;
|
||||
@ -313,9 +313,9 @@ spdk_nvmf_ctrlr_connect(struct spdk_nvmf_qpair *qpair,
|
||||
|
||||
memcpy(ctrlr->hostid, data->hostid, sizeof(ctrlr->hostid));
|
||||
|
||||
if (qpair->transport->ctrlr_add_qpair(ctrlr, qpair)) {
|
||||
if (qpair->transport->ops->ctrlr_add_qpair(ctrlr, qpair)) {
|
||||
rsp->status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR;
|
||||
qpair->transport->ctrlr_fini(ctrlr);
|
||||
qpair->transport->ops->ctrlr_fini(ctrlr);
|
||||
free(ctrlr);
|
||||
return;
|
||||
}
|
||||
@ -374,7 +374,7 @@ spdk_nvmf_ctrlr_connect(struct spdk_nvmf_qpair *qpair,
|
||||
return;
|
||||
}
|
||||
|
||||
if (qpair->transport->ctrlr_add_qpair(ctrlr, qpair)) {
|
||||
if (qpair->transport->ops->ctrlr_add_qpair(ctrlr, qpair)) {
|
||||
INVALID_CONNECT_CMD(qid);
|
||||
return;
|
||||
}
|
||||
@ -399,8 +399,8 @@ spdk_nvmf_ctrlr_disconnect(struct spdk_nvmf_qpair *qpair)
|
||||
ctrlr->num_qpairs--;
|
||||
TAILQ_REMOVE(&ctrlr->qpairs, qpair, link);
|
||||
|
||||
qpair->transport->ctrlr_remove_qpair(ctrlr, qpair);
|
||||
qpair->transport->qpair_fini(qpair);
|
||||
qpair->transport->ops->ctrlr_remove_qpair(ctrlr, qpair);
|
||||
qpair->transport->ops->qpair_fini(qpair);
|
||||
|
||||
if (ctrlr->num_qpairs == 0) {
|
||||
ctrlr_destruct(ctrlr);
|
||||
@ -654,7 +654,7 @@ spdk_nvmf_ctrlr_poll(struct spdk_nvmf_ctrlr *ctrlr)
|
||||
}
|
||||
|
||||
TAILQ_FOREACH_SAFE(qpair, &ctrlr->qpairs, link, tmp) {
|
||||
if (qpair->transport->qpair_poll(qpair) < 0) {
|
||||
if (qpair->transport->ops->qpair_poll(qpair) < 0) {
|
||||
SPDK_ERRLOG("Transport poll failed for qpair %p; closing connection\n", qpair);
|
||||
spdk_nvmf_ctrlr_disconnect(qpair);
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ enum spdk_nvmf_qpair_type {
|
||||
};
|
||||
|
||||
struct spdk_nvmf_qpair {
|
||||
const struct spdk_nvmf_transport *transport;
|
||||
struct spdk_nvmf_transport *transport;
|
||||
struct spdk_nvmf_ctrlr *ctrlr;
|
||||
enum spdk_nvmf_qpair_type type;
|
||||
|
||||
@ -92,7 +92,7 @@ struct spdk_nvmf_ctrlr {
|
||||
} async_event_config;
|
||||
struct spdk_nvmf_request *aer_req;
|
||||
uint8_t hostid[16];
|
||||
const struct spdk_nvmf_transport *transport;
|
||||
struct spdk_nvmf_transport *transport;
|
||||
|
||||
TAILQ_ENTRY(spdk_nvmf_ctrlr) link;
|
||||
};
|
||||
|
@ -58,7 +58,7 @@ nvmf_update_discovery_log(void)
|
||||
struct spdk_nvmf_subsystem_allowed_listener *allowed_listener;
|
||||
struct spdk_nvmf_listen_addr *listen_addr;
|
||||
struct spdk_nvmf_discovery_log_page_entry *entry;
|
||||
const struct spdk_nvmf_transport *transport;
|
||||
struct spdk_nvmf_transport *transport;
|
||||
struct spdk_nvmf_discovery_log_page *disc_log;
|
||||
size_t cur_size;
|
||||
|
||||
@ -99,10 +99,10 @@ nvmf_update_discovery_log(void)
|
||||
entry->subtype = subsystem->subtype;
|
||||
snprintf(entry->subnqn, sizeof(entry->subnqn), "%s", subsystem->subnqn);
|
||||
|
||||
transport = spdk_nvmf_transport_get(listen_addr->trid.trtype);
|
||||
transport = spdk_nvmf_tgt_get_transport(&g_nvmf_tgt, listen_addr->trid.trtype);
|
||||
assert(transport != NULL);
|
||||
|
||||
transport->listen_addr_discover(listen_addr, entry);
|
||||
transport->ops->listen_addr_discover(transport, listen_addr, entry);
|
||||
|
||||
numrec++;
|
||||
}
|
||||
|
@ -52,8 +52,6 @@ int
|
||||
spdk_nvmf_tgt_init(uint16_t max_queue_depth, uint16_t max_qpairs_per_ctrlr,
|
||||
uint32_t in_capsule_data_size, uint32_t max_io_size)
|
||||
{
|
||||
int rc;
|
||||
|
||||
g_nvmf_tgt.max_qpairs_per_ctrlr = max_qpairs_per_ctrlr;
|
||||
g_nvmf_tgt.max_queue_depth = max_queue_depth;
|
||||
g_nvmf_tgt.in_capsule_data_size = in_capsule_data_size;
|
||||
@ -64,18 +62,13 @@ spdk_nvmf_tgt_init(uint16_t max_queue_depth, uint16_t max_qpairs_per_ctrlr,
|
||||
g_nvmf_tgt.current_subsystem_id = 0;
|
||||
TAILQ_INIT(&g_nvmf_tgt.subsystems);
|
||||
TAILQ_INIT(&g_nvmf_tgt.listen_addrs);
|
||||
TAILQ_INIT(&g_nvmf_tgt.transports);
|
||||
|
||||
SPDK_TRACELOG(SPDK_TRACE_NVMF, "Max Queue Pairs Per Controller: %d\n", max_qpairs_per_ctrlr);
|
||||
SPDK_TRACELOG(SPDK_TRACE_NVMF, "Max Queue Depth: %d\n", max_queue_depth);
|
||||
SPDK_TRACELOG(SPDK_TRACE_NVMF, "Max In Capsule Data: %d bytes\n", in_capsule_data_size);
|
||||
SPDK_TRACELOG(SPDK_TRACE_NVMF, "Max I/O Size: %d bytes\n", max_io_size);
|
||||
|
||||
rc = spdk_nvmf_transport_init();
|
||||
if (rc < 0) {
|
||||
SPDK_ERRLOG("Transport initialization failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -83,6 +76,7 @@ int
|
||||
spdk_nvmf_tgt_fini(void)
|
||||
{
|
||||
struct spdk_nvmf_listen_addr *listen_addr, *listen_addr_tmp;
|
||||
struct spdk_nvmf_transport *transport, *transport_tmp;
|
||||
|
||||
TAILQ_FOREACH_SAFE(listen_addr, &g_nvmf_tgt.listen_addrs, link, listen_addr_tmp) {
|
||||
TAILQ_REMOVE(&g_nvmf_tgt.listen_addrs, listen_addr, link);
|
||||
@ -91,21 +85,32 @@ spdk_nvmf_tgt_fini(void)
|
||||
spdk_nvmf_listen_addr_destroy(listen_addr);
|
||||
}
|
||||
|
||||
spdk_nvmf_transport_fini();
|
||||
TAILQ_FOREACH_SAFE(transport, &g_nvmf_tgt.transports, link, transport_tmp) {
|
||||
TAILQ_REMOVE(&g_nvmf_tgt.transports, transport, link);
|
||||
spdk_nvmf_transport_destroy(transport);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct spdk_nvmf_transport *
|
||||
spdk_nvmf_tgt_get_transport(struct spdk_nvmf_tgt *tgt, enum spdk_nvme_transport_type type)
|
||||
{
|
||||
struct spdk_nvmf_transport *transport;
|
||||
|
||||
TAILQ_FOREACH(transport, &tgt->transports, link) {
|
||||
if (transport->ops->type == type) {
|
||||
return transport;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct spdk_nvmf_listen_addr *
|
||||
spdk_nvmf_listen_addr_create(struct spdk_nvme_transport_id *trid)
|
||||
{
|
||||
struct spdk_nvmf_listen_addr *listen_addr;
|
||||
const struct spdk_nvmf_transport *transport;
|
||||
|
||||
transport = spdk_nvmf_transport_get(trid->trtype);
|
||||
if (!transport) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
listen_addr = calloc(1, sizeof(*listen_addr));
|
||||
if (!listen_addr) {
|
||||
@ -120,15 +125,28 @@ spdk_nvmf_listen_addr_create(struct spdk_nvme_transport_id *trid)
|
||||
void
|
||||
spdk_nvmf_listen_addr_destroy(struct spdk_nvmf_listen_addr *addr)
|
||||
{
|
||||
const struct spdk_nvmf_transport *transport;
|
||||
struct spdk_nvmf_transport *transport;
|
||||
|
||||
transport = spdk_nvmf_transport_get(addr->trid.trtype);
|
||||
assert(transport != NULL);
|
||||
transport->listen_addr_remove(addr);
|
||||
transport = spdk_nvmf_tgt_get_transport(&g_nvmf_tgt, addr->trid.trtype);
|
||||
if (!transport) {
|
||||
SPDK_ERRLOG("Attempted to destroy listener without a valid transport\n");
|
||||
return;
|
||||
}
|
||||
|
||||
transport->ops->listen_addr_remove(transport, addr);
|
||||
free(addr);
|
||||
}
|
||||
|
||||
void
|
||||
spdk_nvmf_tgt_poll(void)
|
||||
{
|
||||
struct spdk_nvmf_transport *transport, *tmp;
|
||||
|
||||
TAILQ_FOREACH_SAFE(transport, &g_nvmf_tgt.transports, link, tmp) {
|
||||
transport->ops->acceptor_poll(transport);
|
||||
}
|
||||
}
|
||||
|
||||
SPDK_TRACE_REGISTER_FN(nvmf_trace)
|
||||
{
|
||||
spdk_trace_register_object(OBJECT_NVMF_IO, 'r');
|
||||
|
@ -87,6 +87,7 @@ struct spdk_nvmf_tgt {
|
||||
size_t discovery_log_page_size;
|
||||
TAILQ_HEAD(, spdk_nvmf_listen_addr) listen_addrs;
|
||||
uint32_t current_subsystem_id;
|
||||
TAILQ_HEAD(, spdk_nvmf_transport) transports;
|
||||
};
|
||||
|
||||
extern struct spdk_nvmf_tgt g_nvmf_tgt;
|
||||
@ -94,6 +95,9 @@ extern struct spdk_nvmf_tgt g_nvmf_tgt;
|
||||
struct spdk_nvmf_listen_addr *spdk_nvmf_listen_addr_create(struct spdk_nvme_transport_id *trid);
|
||||
void spdk_nvmf_listen_addr_destroy(struct spdk_nvmf_listen_addr *addr);
|
||||
|
||||
struct spdk_nvmf_transport *spdk_nvmf_tgt_get_transport(struct spdk_nvmf_tgt *tgt,
|
||||
enum spdk_nvme_transport_type);
|
||||
|
||||
#define OBJECT_NVMF_IO 0x30
|
||||
|
||||
#define TRACE_GROUP_NVMF 0x3
|
||||
|
@ -258,7 +258,8 @@ spdk_nvmf_rdma_qpair_destroy(struct spdk_nvmf_rdma_qpair *rdma_qpair)
|
||||
}
|
||||
|
||||
static struct spdk_nvmf_rdma_qpair *
|
||||
spdk_nvmf_rdma_qpair_create(struct rdma_cm_id *id, struct ibv_comp_channel *channel,
|
||||
spdk_nvmf_rdma_qpair_create(struct spdk_nvmf_transport *transport,
|
||||
struct rdma_cm_id *id, struct ibv_comp_channel *channel,
|
||||
uint16_t max_queue_depth, uint16_t max_rw_depth, uint32_t subsystem_id)
|
||||
{
|
||||
struct spdk_nvmf_rdma_qpair *rdma_qpair;
|
||||
@ -310,7 +311,7 @@ spdk_nvmf_rdma_qpair_create(struct rdma_cm_id *id, struct ibv_comp_channel *chan
|
||||
}
|
||||
|
||||
qpair = &rdma_qpair->qpair;
|
||||
qpair->transport = &spdk_nvmf_transport_rdma;
|
||||
qpair->transport = transport;
|
||||
id->context = qpair;
|
||||
rdma_qpair->cm_id = id;
|
||||
|
||||
@ -534,7 +535,7 @@ spdk_nvmf_rdma_request_transfer_data(struct spdk_nvmf_request *req)
|
||||
}
|
||||
|
||||
static int
|
||||
nvmf_rdma_connect(struct rdma_cm_event *event)
|
||||
nvmf_rdma_connect(struct spdk_nvmf_transport *transport, struct rdma_cm_event *event)
|
||||
{
|
||||
struct spdk_nvmf_rdma_qpair *rdma_qpair = NULL;
|
||||
struct spdk_nvmf_rdma_listen_addr *addr;
|
||||
@ -613,7 +614,7 @@ nvmf_rdma_connect(struct rdma_cm_event *event)
|
||||
max_queue_depth, max_rw_depth);
|
||||
|
||||
/* Init the NVMf rdma transport connection */
|
||||
rdma_qpair = spdk_nvmf_rdma_qpair_create(event->id, addr->comp_channel, max_queue_depth,
|
||||
rdma_qpair = spdk_nvmf_rdma_qpair_create(transport, event->id, addr->comp_channel, max_queue_depth,
|
||||
max_rw_depth, subsystem_id);
|
||||
if (rdma_qpair == NULL) {
|
||||
SPDK_ERRLOG("Error on nvmf connection creation\n");
|
||||
@ -912,35 +913,45 @@ spdk_nvmf_rdma_handle_pending_rdma_rw(struct spdk_nvmf_qpair *qpair)
|
||||
|
||||
/* Public API callbacks begin here */
|
||||
|
||||
static int
|
||||
spdk_nvmf_rdma_init(uint16_t max_queue_depth, uint32_t max_io_size,
|
||||
uint32_t in_capsule_data_size)
|
||||
static struct spdk_nvmf_transport *
|
||||
spdk_nvmf_rdma_create(struct spdk_nvmf_tgt *tgt)
|
||||
{
|
||||
int rc;
|
||||
struct spdk_nvmf_transport *transport;
|
||||
|
||||
transport = calloc(1, sizeof(*transport));
|
||||
if (!transport) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
transport->tgt = tgt;
|
||||
transport->ops = &spdk_nvmf_transport_rdma;
|
||||
|
||||
SPDK_NOTICELOG("*** RDMA Transport Init ***\n");
|
||||
|
||||
pthread_mutex_lock(&g_rdma.lock);
|
||||
g_rdma.max_queue_depth = max_queue_depth;
|
||||
g_rdma.max_io_size = max_io_size;
|
||||
g_rdma.in_capsule_data_size = in_capsule_data_size;
|
||||
g_rdma.max_queue_depth = tgt->max_queue_depth;
|
||||
g_rdma.max_io_size = tgt->max_io_size;
|
||||
g_rdma.in_capsule_data_size = tgt->in_capsule_data_size;
|
||||
|
||||
g_rdma.event_channel = rdma_create_event_channel();
|
||||
if (g_rdma.event_channel == NULL) {
|
||||
SPDK_ERRLOG("rdma_create_event_channel() failed, %s\n", strerror(errno));
|
||||
free(transport);
|
||||
pthread_mutex_unlock(&g_rdma.lock);
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = fcntl(g_rdma.event_channel->fd, F_SETFL, O_NONBLOCK);
|
||||
if (rc < 0) {
|
||||
SPDK_ERRLOG("fcntl to set fd to non-blocking failed\n");
|
||||
free(transport);
|
||||
pthread_mutex_unlock(&g_rdma.lock);
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&g_rdma.lock);
|
||||
return 0;
|
||||
return transport;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -953,7 +964,7 @@ spdk_nvmf_rdma_listen_addr_free(struct spdk_nvmf_rdma_listen_addr *addr)
|
||||
free(addr);
|
||||
}
|
||||
static int
|
||||
spdk_nvmf_rdma_fini(void)
|
||||
spdk_nvmf_rdma_destroy(struct spdk_nvmf_transport *transport)
|
||||
{
|
||||
pthread_mutex_lock(&g_rdma.lock);
|
||||
|
||||
@ -963,11 +974,14 @@ spdk_nvmf_rdma_fini(void)
|
||||
}
|
||||
pthread_mutex_unlock(&g_rdma.lock);
|
||||
|
||||
free(transport);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
spdk_nvmf_rdma_listen_remove(struct spdk_nvmf_listen_addr *listen_addr)
|
||||
spdk_nvmf_rdma_listen_remove(struct spdk_nvmf_transport *transport,
|
||||
struct spdk_nvmf_listen_addr *listen_addr)
|
||||
{
|
||||
struct spdk_nvmf_rdma_listen_addr *addr, *tmp;
|
||||
|
||||
@ -1017,7 +1031,7 @@ spdk_nvmf_rdma_addr_listen_init(struct spdk_nvmf_rdma_listen_addr *addr)
|
||||
}
|
||||
|
||||
static void
|
||||
spdk_nvmf_rdma_acceptor_poll(void)
|
||||
spdk_nvmf_rdma_acceptor_poll(struct spdk_nvmf_transport *transport)
|
||||
{
|
||||
struct rdma_cm_event *event;
|
||||
int rc;
|
||||
@ -1057,7 +1071,7 @@ spdk_nvmf_rdma_acceptor_poll(void)
|
||||
|
||||
switch (event->event) {
|
||||
case RDMA_CM_EVENT_CONNECT_REQUEST:
|
||||
rc = nvmf_rdma_connect(event);
|
||||
rc = nvmf_rdma_connect(transport, event);
|
||||
if (rc < 0) {
|
||||
SPDK_ERRLOG("Unable to process connect event. rc: %d\n", rc);
|
||||
break;
|
||||
@ -1091,7 +1105,8 @@ spdk_nvmf_rdma_acceptor_poll(void)
|
||||
}
|
||||
|
||||
static int
|
||||
spdk_nvmf_rdma_listen(struct spdk_nvmf_listen_addr *listen_addr)
|
||||
spdk_nvmf_rdma_listen(struct spdk_nvmf_transport *transport,
|
||||
struct spdk_nvmf_listen_addr *listen_addr)
|
||||
{
|
||||
struct spdk_nvmf_rdma_listen_addr *addr;
|
||||
struct sockaddr_in saddr;
|
||||
@ -1177,7 +1192,8 @@ spdk_nvmf_rdma_listen(struct spdk_nvmf_listen_addr *listen_addr)
|
||||
}
|
||||
|
||||
static void
|
||||
spdk_nvmf_rdma_discover(struct spdk_nvmf_listen_addr *listen_addr,
|
||||
spdk_nvmf_rdma_discover(struct spdk_nvmf_transport *transport,
|
||||
struct spdk_nvmf_listen_addr *listen_addr,
|
||||
struct spdk_nvmf_discovery_log_page_entry *entry)
|
||||
{
|
||||
entry->trtype = SPDK_NVMF_TRTYPE_RDMA;
|
||||
@ -1193,7 +1209,7 @@ spdk_nvmf_rdma_discover(struct spdk_nvmf_listen_addr *listen_addr,
|
||||
}
|
||||
|
||||
static struct spdk_nvmf_ctrlr *
|
||||
spdk_nvmf_rdma_ctrlr_init(void)
|
||||
spdk_nvmf_rdma_ctrlr_init(struct spdk_nvmf_transport *transport)
|
||||
{
|
||||
struct spdk_nvmf_rdma_ctrlr *rdma_ctrlr;
|
||||
int i;
|
||||
@ -1222,7 +1238,7 @@ spdk_nvmf_rdma_ctrlr_init(void)
|
||||
SLIST_INSERT_HEAD(&rdma_ctrlr->data_buf_pool, buf, link);
|
||||
}
|
||||
|
||||
rdma_ctrlr->ctrlr.transport = &spdk_nvmf_transport_rdma;
|
||||
rdma_ctrlr->ctrlr.transport = transport;
|
||||
|
||||
return &rdma_ctrlr->ctrlr;
|
||||
}
|
||||
@ -1575,10 +1591,10 @@ spdk_nvmf_rdma_qpair_is_idle(struct spdk_nvmf_qpair *qpair)
|
||||
return false;
|
||||
}
|
||||
|
||||
const struct spdk_nvmf_transport spdk_nvmf_transport_rdma = {
|
||||
const struct spdk_nvmf_transport_ops spdk_nvmf_transport_rdma = {
|
||||
.type = SPDK_NVME_TRANSPORT_RDMA,
|
||||
.transport_init = spdk_nvmf_rdma_init,
|
||||
.transport_fini = spdk_nvmf_rdma_fini,
|
||||
.create = spdk_nvmf_rdma_create,
|
||||
.destroy = spdk_nvmf_rdma_destroy,
|
||||
|
||||
.acceptor_poll = spdk_nvmf_rdma_acceptor_poll,
|
||||
|
||||
|
@ -59,7 +59,7 @@ spdk_nvmf_request_complete(struct spdk_nvmf_request *req)
|
||||
response->cid, response->cdw0, response->rsvd1,
|
||||
*(uint16_t *)&response->status);
|
||||
|
||||
if (req->qpair->transport->req_complete(req)) {
|
||||
if (req->qpair->transport->ops->req_complete(req)) {
|
||||
SPDK_ERRLOG("Transport request completion error!\n");
|
||||
return -1;
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ nvmf_subsystem_removable(struct spdk_nvmf_subsystem *subsystem)
|
||||
if (subsystem->is_removed) {
|
||||
TAILQ_FOREACH(ctrlr, &subsystem->ctrlrs, link) {
|
||||
TAILQ_FOREACH(qpair, &ctrlr->qpairs, link) {
|
||||
if (!qpair->transport->qpair_is_idle(qpair)) {
|
||||
if (!qpair->transport->ops->qpair_is_idle(qpair)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -262,7 +262,7 @@ struct spdk_nvmf_listen_addr *
|
||||
spdk_nvmf_tgt_listen(struct spdk_nvme_transport_id *trid)
|
||||
{
|
||||
struct spdk_nvmf_listen_addr *listen_addr;
|
||||
const struct spdk_nvmf_transport *transport;
|
||||
struct spdk_nvmf_transport *transport;
|
||||
int rc;
|
||||
|
||||
TAILQ_FOREACH(listen_addr, &g_nvmf_tgt.listen_addrs, link) {
|
||||
@ -271,18 +271,23 @@ spdk_nvmf_tgt_listen(struct spdk_nvme_transport_id *trid)
|
||||
}
|
||||
}
|
||||
|
||||
transport = spdk_nvmf_transport_get(trid->trtype);
|
||||
transport = spdk_nvmf_tgt_get_transport(&g_nvmf_tgt, trid->trtype);
|
||||
if (!transport) {
|
||||
SPDK_ERRLOG("Unknown transport '%u'\n", trid->trtype);
|
||||
return NULL;
|
||||
transport = spdk_nvmf_transport_create(&g_nvmf_tgt, trid->trtype);
|
||||
if (!transport) {
|
||||
SPDK_ERRLOG("Transport initialization failed\n");
|
||||
return NULL;
|
||||
}
|
||||
TAILQ_INSERT_TAIL(&g_nvmf_tgt.transports, transport, link);
|
||||
}
|
||||
|
||||
|
||||
listen_addr = spdk_nvmf_listen_addr_create(trid);
|
||||
if (!listen_addr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = transport->listen_addr_add(listen_addr);
|
||||
rc = transport->ops->listen_addr_add(transport, listen_addr);
|
||||
if (rc < 0) {
|
||||
free(listen_addr);
|
||||
SPDK_ERRLOG("Unable to listen on address '%s'\n", trid->traddr);
|
||||
|
@ -42,71 +42,56 @@
|
||||
|
||||
#include "nvmf_internal.h"
|
||||
|
||||
static const struct spdk_nvmf_transport *const g_transports[] = {
|
||||
static const struct spdk_nvmf_transport_ops *const g_transport_ops[] = {
|
||||
#ifdef SPDK_CONFIG_RDMA
|
||||
&spdk_nvmf_transport_rdma,
|
||||
#endif
|
||||
};
|
||||
|
||||
#define NUM_TRANSPORTS (SPDK_COUNTOF(g_transports))
|
||||
#define NUM_TRANSPORTS (SPDK_COUNTOF(g_transport_ops))
|
||||
|
||||
int
|
||||
spdk_nvmf_transport_init(void)
|
||||
struct spdk_nvmf_transport *
|
||||
spdk_nvmf_transport_create(struct spdk_nvmf_tgt *tgt,
|
||||
enum spdk_nvme_transport_type type)
|
||||
{
|
||||
size_t i;
|
||||
int count = 0;
|
||||
const struct spdk_nvmf_transport_ops *ops = NULL;
|
||||
struct spdk_nvmf_transport *transport;
|
||||
|
||||
for (i = 0; i != NUM_TRANSPORTS; i++) {
|
||||
if (g_transports[i]->transport_init(g_nvmf_tgt.max_queue_depth, g_nvmf_tgt.max_io_size,
|
||||
g_nvmf_tgt.in_capsule_data_size) < 0) {
|
||||
SPDK_NOTICELOG("Transport type %s init failed\n",
|
||||
spdk_nvme_transport_id_trtype_str(g_transports[i]->type));
|
||||
} else {
|
||||
count++;
|
||||
if (g_transport_ops[i]->type == type) {
|
||||
ops = g_transport_ops[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
if (!ops) {
|
||||
SPDK_ERRLOG("Transport type %s unavailable.\n",
|
||||
spdk_nvme_transport_id_trtype_str(type));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
transport = ops->create(tgt);
|
||||
if (!transport) {
|
||||
SPDK_ERRLOG("Unable to create new transport of type %s\n",
|
||||
spdk_nvme_transport_id_trtype_str(type));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
transport->ops = ops;
|
||||
transport->tgt = tgt;
|
||||
|
||||
return transport;
|
||||
}
|
||||
|
||||
int
|
||||
spdk_nvmf_transport_fini(void)
|
||||
spdk_nvmf_transport_destroy(struct spdk_nvmf_transport *transport)
|
||||
{
|
||||
size_t i;
|
||||
int count = 0;
|
||||
|
||||
for (i = 0; i != NUM_TRANSPORTS; i++) {
|
||||
if (g_transports[i]->transport_fini() < 0) {
|
||||
SPDK_NOTICELOG("Transport type %s fini failed\n",
|
||||
spdk_nvme_transport_id_trtype_str(g_transports[i]->type));
|
||||
} else {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
return transport->ops->destroy(transport);
|
||||
}
|
||||
|
||||
void
|
||||
spdk_nvmf_acceptor_poll(void)
|
||||
spdk_nvmf_transport_poll(struct spdk_nvmf_transport *transport)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i != NUM_TRANSPORTS; i++) {
|
||||
g_transports[i]->acceptor_poll();
|
||||
}
|
||||
}
|
||||
|
||||
const struct spdk_nvmf_transport *
|
||||
spdk_nvmf_transport_get(enum spdk_nvme_transport_type type)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i != NUM_TRANSPORTS; i++) {
|
||||
if (type == g_transports[i]->type) {
|
||||
return g_transports[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
transport->ops->acceptor_poll(transport);
|
||||
}
|
||||
|
@ -42,49 +42,58 @@
|
||||
struct spdk_nvmf_listen_addr;
|
||||
|
||||
struct spdk_nvmf_transport {
|
||||
struct spdk_nvmf_tgt *tgt;
|
||||
const struct spdk_nvmf_transport_ops *ops;
|
||||
|
||||
TAILQ_ENTRY(spdk_nvmf_transport) link;
|
||||
};
|
||||
|
||||
struct spdk_nvmf_transport_ops {
|
||||
/**
|
||||
* Transport type
|
||||
*/
|
||||
enum spdk_nvme_transport_type type;
|
||||
|
||||
/**
|
||||
* Initialize the transport.
|
||||
* Create a transport for the given target
|
||||
*/
|
||||
int (*transport_init)(uint16_t max_queue_depth, uint32_t max_io_size,
|
||||
uint32_t in_capsule_data_size);
|
||||
struct spdk_nvmf_transport *(*create)(struct spdk_nvmf_tgt *tgt);
|
||||
|
||||
/**
|
||||
* Shut down the transport.
|
||||
* Destroy the transport
|
||||
*/
|
||||
int (*transport_fini)(void);
|
||||
int (*destroy)(struct spdk_nvmf_transport *transport);
|
||||
|
||||
/**
|
||||
* Check for new connections on the transport.
|
||||
*/
|
||||
void (*acceptor_poll)(void);
|
||||
void (*acceptor_poll)(struct spdk_nvmf_transport *transport);
|
||||
|
||||
/**
|
||||
* Instruct the acceptor to listen on the address provided. This
|
||||
* may be called multiple times.
|
||||
*/
|
||||
int (*listen_addr_add)(struct spdk_nvmf_listen_addr *listen_addr);
|
||||
int (*listen_addr_add)(struct spdk_nvmf_transport *transport,
|
||||
struct spdk_nvmf_listen_addr *listen_addr);
|
||||
|
||||
/**
|
||||
* Instruct to remove listening on the address provided. This
|
||||
* may be called multiple times.
|
||||
*/
|
||||
int (*listen_addr_remove)(struct spdk_nvmf_listen_addr *listen_addr);
|
||||
int (*listen_addr_remove)(struct spdk_nvmf_transport *transport,
|
||||
struct spdk_nvmf_listen_addr *listen_addr);
|
||||
|
||||
/**
|
||||
* Fill out a discovery log entry for a specific listen address.
|
||||
*/
|
||||
void (*listen_addr_discover)(struct spdk_nvmf_listen_addr *listen_addr,
|
||||
void (*listen_addr_discover)(struct spdk_nvmf_transport *transport,
|
||||
struct spdk_nvmf_listen_addr *listen_addr,
|
||||
struct spdk_nvmf_discovery_log_page_entry *entry);
|
||||
|
||||
/**
|
||||
* Create a new ctrlr
|
||||
*/
|
||||
struct spdk_nvmf_ctrlr *(*ctrlr_init)(void);
|
||||
struct spdk_nvmf_ctrlr *(*ctrlr_init)(struct spdk_nvmf_transport *transport);
|
||||
|
||||
/**
|
||||
* Destroy a ctrlr
|
||||
@ -123,11 +132,12 @@ struct spdk_nvmf_transport {
|
||||
bool (*qpair_is_idle)(struct spdk_nvmf_qpair *qpair);
|
||||
};
|
||||
|
||||
int spdk_nvmf_transport_init(void);
|
||||
int spdk_nvmf_transport_fini(void);
|
||||
struct spdk_nvmf_transport *spdk_nvmf_transport_create(struct spdk_nvmf_tgt *tgt,
|
||||
enum spdk_nvme_transport_type type);
|
||||
int spdk_nvmf_transport_destroy(struct spdk_nvmf_transport *transport);
|
||||
|
||||
const struct spdk_nvmf_transport *spdk_nvmf_transport_get(enum spdk_nvme_transport_type type);
|
||||
void spdk_nvmf_transport_poll(struct spdk_nvmf_transport *transport);
|
||||
|
||||
extern const struct spdk_nvmf_transport spdk_nvmf_transport_rdma;
|
||||
extern const struct spdk_nvmf_transport_ops spdk_nvmf_transport_rdma;
|
||||
|
||||
#endif /* SPDK_NVMF_TRANSPORT_H */
|
||||
|
@ -80,27 +80,46 @@ spdk_bdev_get_name(const struct spdk_bdev *bdev)
|
||||
}
|
||||
|
||||
static int
|
||||
test_transport1_listen_addr_add(struct spdk_nvmf_listen_addr *listen_addr)
|
||||
test_transport1_listen_addr_add(struct spdk_nvmf_transport *transport,
|
||||
struct spdk_nvmf_listen_addr *listen_addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
test_transport1_listen_addr_discover(struct spdk_nvmf_listen_addr *listen_addr,
|
||||
test_transport1_listen_addr_discover(struct spdk_nvmf_transport *transport,
|
||||
struct spdk_nvmf_listen_addr *listen_addr,
|
||||
struct spdk_nvmf_discovery_log_page_entry *entry)
|
||||
{
|
||||
entry->trtype = 42;
|
||||
}
|
||||
|
||||
static const struct spdk_nvmf_transport test_transport1 = {
|
||||
static const struct spdk_nvmf_transport_ops test_transport1_ops = {
|
||||
.listen_addr_add = test_transport1_listen_addr_add,
|
||||
.listen_addr_discover = test_transport1_listen_addr_discover,
|
||||
};
|
||||
|
||||
const struct spdk_nvmf_transport *
|
||||
spdk_nvmf_transport_get(enum spdk_nvme_transport_type trtype)
|
||||
static struct spdk_nvmf_transport test_transport1 = {
|
||||
.ops = &test_transport1_ops,
|
||||
};
|
||||
|
||||
struct spdk_nvmf_transport *
|
||||
spdk_nvmf_transport_create(struct spdk_nvmf_tgt *tgt,
|
||||
enum spdk_nvme_transport_type type)
|
||||
{
|
||||
if (type == SPDK_NVME_TRANSPORT_RDMA) {
|
||||
test_transport1.tgt = tgt;
|
||||
return &test_transport1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct spdk_nvmf_transport *
|
||||
spdk_nvmf_tgt_get_transport(struct spdk_nvmf_tgt *tgt, enum spdk_nvme_transport_type trtype)
|
||||
{
|
||||
if (trtype == SPDK_NVME_TRANSPORT_RDMA) {
|
||||
test_transport1.tgt = tgt;
|
||||
return &test_transport1;
|
||||
}
|
||||
|
||||
|
@ -67,27 +67,46 @@ spdk_nvmf_listen_addr_destroy(struct spdk_nvmf_listen_addr *addr)
|
||||
}
|
||||
|
||||
static int
|
||||
test_transport1_listen_addr_add(struct spdk_nvmf_listen_addr *listen_addr)
|
||||
test_transport1_listen_addr_add(struct spdk_nvmf_transport *transport,
|
||||
struct spdk_nvmf_listen_addr *listen_addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
test_transport1_listen_addr_discover(struct spdk_nvmf_listen_addr *listen_addr,
|
||||
test_transport1_listen_addr_discover(struct spdk_nvmf_transport *transport,
|
||||
struct spdk_nvmf_listen_addr *listen_addr,
|
||||
struct spdk_nvmf_discovery_log_page_entry *entry)
|
||||
{
|
||||
entry->trtype = 42;
|
||||
}
|
||||
|
||||
static const struct spdk_nvmf_transport test_transport1 = {
|
||||
static const struct spdk_nvmf_transport_ops test_transport1_ops = {
|
||||
.listen_addr_add = test_transport1_listen_addr_add,
|
||||
.listen_addr_discover = test_transport1_listen_addr_discover,
|
||||
};
|
||||
|
||||
const struct spdk_nvmf_transport *
|
||||
spdk_nvmf_transport_get(enum spdk_nvme_transport_type trtype)
|
||||
static struct spdk_nvmf_transport test_transport1 = {
|
||||
.ops = &test_transport1_ops,
|
||||
};
|
||||
|
||||
struct spdk_nvmf_transport *
|
||||
spdk_nvmf_transport_create(struct spdk_nvmf_tgt *tgt,
|
||||
enum spdk_nvme_transport_type type)
|
||||
{
|
||||
if (type == SPDK_NVME_TRANSPORT_RDMA) {
|
||||
test_transport1.tgt = tgt;
|
||||
return &test_transport1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct spdk_nvmf_transport *
|
||||
spdk_nvmf_tgt_get_transport(struct spdk_nvmf_tgt *tgt, enum spdk_nvme_transport_type trtype)
|
||||
{
|
||||
if (trtype == SPDK_NVME_TRANSPORT_RDMA) {
|
||||
test_transport1.tgt = tgt;
|
||||
return &test_transport1;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user