From 64f6abea9c2750e336ec8bfeca561988ec94c7e5 Mon Sep 17 00:00:00 2001 From: Ben Walker Date: Thu, 30 Jun 2016 11:18:52 -0700 Subject: [PATCH] nvmf: Sessions now contain a list of connections. There was an extra layer of indirection complicating things for no reason. This removes it. Change-Id: I8d4e654eb17f8f6ec028d775329794f0745fb0f7 Signed-off-by: Ben Walker --- lib/nvmf/conn.c | 2 +- lib/nvmf/conn.h | 4 -- lib/nvmf/request.c | 16 ++++--- lib/nvmf/session.c | 107 ++++++++++++--------------------------------- lib/nvmf/session.h | 19 ++------ 5 files changed, 44 insertions(+), 104 deletions(-) diff --git a/lib/nvmf/conn.c b/lib/nvmf/conn.c index 3e7d005ed..00c867cd8 100644 --- a/lib/nvmf/conn.c +++ b/lib/nvmf/conn.c @@ -250,7 +250,7 @@ _conn_destruct(spdk_event_t event) * going away. If this is the AQ connection then * set state for other connections to abort. */ - nvmf_disconnect((void *)conn, conn->sess); + nvmf_disconnect(conn->sess, conn); if (conn->type == CONN_TYPE_AQ) { SPDK_TRACELOG(SPDK_TRACE_DEBUG, "AQ connection destruct, trigger session closure\n"); diff --git a/lib/nvmf/conn.h b/lib/nvmf/conn.h index 82f551c77..dfd90de65 100644 --- a/lib/nvmf/conn.h +++ b/lib/nvmf/conn.h @@ -59,10 +59,6 @@ struct spdk_nvmf_conn { struct nvmf_session *sess; - - /* - * values saved from fabric connect and private data - */ uint16_t qid; uint16_t cntlid; diff --git a/lib/nvmf/request.c b/lib/nvmf/request.c index dc5888226..0b8aefbb3 100644 --- a/lib/nvmf/request.c +++ b/lib/nvmf/request.c @@ -434,14 +434,18 @@ nvmf_process_connect(struct spdk_nvmf_request *req) response = &req->rsp->connect_rsp; - session = nvmf_connect((void *)conn, connect, connect_data, response); + conn->qid = connect->qid; + conn->cntlid = connect_data->cntlid; + if (conn->qid > 0) { + conn->type = CONN_TYPE_IOQ; + } else { + conn->type = CONN_TYPE_AQ; + } + + session = nvmf_connect(conn, connect, connect_data, response); if (session != NULL) { conn->sess = session; - conn->qid = connect->qid; - if (connect->qid > 0) { - conn->type = CONN_TYPE_IOQ; /* I/O Connection */ - } else { - /* When session first created, set some attributes */ + if (conn->type == CONN_TYPE_AQ) { nvmf_init_conn_properites(conn, session, response); } } diff --git a/lib/nvmf/session.c b/lib/nvmf/session.c index 10bca623a..ef3f560b3 100644 --- a/lib/nvmf/session.c +++ b/lib/nvmf/session.c @@ -236,116 +236,67 @@ nvmf_find_session_by_id(const char *subnqn, uint16_t cntl_id) } struct nvmf_session * -nvmf_connect(void *fabric_conn, +nvmf_connect(struct spdk_nvmf_conn *conn, struct spdk_nvmf_fabric_connect_cmd *connect, struct spdk_nvmf_fabric_connect_data *connect_data, struct spdk_nvmf_fabric_connect_rsp *response) { struct nvmf_session *session; - struct nvmf_connection_entry *connection = NULL; - connection = calloc(1, sizeof(struct nvmf_connection_entry)); - if (connection == NULL) - goto connect_fail; - - /* Figure out if this is the first connect and we - * need to allocate an nvmf_session or if this is - * a subsequent connect for an I/O queue and we need - * to return an existing session - */ - if (connect->qid == 0) { - /* first connect for AQ connection */ - SPDK_TRACELOG(SPDK_TRACE_NVMF, "AQ connect capsule\n"); - if (connect_data->cntlid == 0xffff) { - /* no nvmf session/controller association, allocate one */ - session = nvmf_create_session(connect_data->subnqn); - if (session == NULL) { - SPDK_ERRLOG("create session failed\n"); - response->status.sc = SPDK_NVMF_FABRIC_SC_CONTROLLER_BUSY; - goto connect_fail; - } - } else { - SPDK_ERRLOG("nvmf AQ connection attempt to cntlid %d\n", connect_data->cntlid); + if (conn->type == CONN_TYPE_AQ) { + /* For admin connections, establish a new session */ + SPDK_TRACELOG(SPDK_TRACE_NVMF, "CONNECT Admin Queue for controller id %d\n", conn->cntlid); + if (conn->cntlid != 0xFFFF) { + /* This NVMf target only supports dynamic mode. */ + SPDK_ERRLOG("The NVMf target only supports dynamic mode.\n"); response->status.sc = SPDK_NVMF_FABRIC_SC_INVALID_PARAM; - goto connect_fail; + return NULL; + } + + session = nvmf_create_session(connect_data->subnqn); + if (session == NULL) { + response->status.sc = SPDK_NVMF_FABRIC_SC_CONTROLLER_BUSY; + return NULL; } - connection->is_aq_conn = 1; } else { - SPDK_TRACELOG(SPDK_TRACE_NVMF, "IOQ connect capsule\n"); - /* locate the existing session */ + SPDK_TRACELOG(SPDK_TRACE_NVMF, "CONNECT I/O Queue for controller id %d\n", conn->cntlid); session = nvmf_find_session_by_id(connect_data->subnqn, connect_data->cntlid); if (session == NULL) { - SPDK_ERRLOG("invalid nvmf cntlid %d\n", connect_data->cntlid); + SPDK_ERRLOG("Unknown controller id %d\n", conn->cntlid); response->status.sc = SPDK_NVMF_FABRIC_SC_RESTART_DISCOVERY; - goto connect_fail; + return NULL; } + /* check if we would exceed session connection limit */ if (session->num_connections >= session->max_connections_allowed) { SPDK_ERRLOG("connection limit %d\n", session->num_connections); response->status.sc = SPDK_NVMF_FABRIC_SC_CONTROLLER_BUSY; - goto connect_fail; + return NULL; } - - if (session->is_valid == 0) { - SPDK_ERRLOG("session invalid or at IO connection limit %d\n", session->num_connections); - response->status.sc = SPDK_NVMF_FABRIC_SC_RESTART_DISCOVERY; - goto connect_fail; - } - connection->is_aq_conn = 0; } - connection->fabric_conn = fabric_conn; - session->num_connections++; - TAILQ_INSERT_HEAD(&session->connections, connection, entries); + TAILQ_INSERT_HEAD(&session->connections, conn, link); response->status_code_specific.success.cntlid = session->cntlid; response->status.sc = 0; return session; - -connect_fail: - if (connection) - free(connection); - return NULL; } void -nvmf_disconnect(void *fabric_conn, - struct nvmf_session *session) +nvmf_disconnect(struct nvmf_session *session, + struct spdk_nvmf_conn *conn) { - struct nvmf_connection_entry *conn, *tconn, *rconn = NULL; - - /* Indication from the fabric transport that a - * specific connection has gone way. If the - * connection is the AQ connection then expect - * that the complete session will go away - */ - if (session == NULL) { - SPDK_TRACELOG(SPDK_TRACE_NVMF, "nvmf_disconnect: session not active!\n"); - return; - } - - TAILQ_FOREACH_SAFE(conn, &session->connections, entries, tconn) { - if (conn->fabric_conn == fabric_conn) { - rconn = conn; - break; + if (session) { + if (session->num_connections > 0) { + session->num_connections--; + TAILQ_REMOVE(&session->connections, conn, link); } - } - if (rconn == NULL) { - SPDK_ERRLOG("Session connection did not exist!\n"); - return; - } - SPDK_TRACELOG(SPDK_TRACE_NVMF, "Disconnect NVMf conn %p, sess %p\n", rconn, session); - session->num_connections--; - TAILQ_REMOVE(&session->connections, rconn, entries); - free(rconn); - - if (session->num_connections == 0) { - SPDK_TRACELOG(SPDK_TRACE_NVMF, "Session connection count 0, deleting session %p!\n", - session); - nvmf_delete_session(session); + if (session->num_connections == 0) { + nvmf_delete_session(session); + } } } diff --git a/lib/nvmf/session.h b/lib/nvmf/session.h index 85f338f77..b104ad98f 100644 --- a/lib/nvmf/session.h +++ b/lib/nvmf/session.h @@ -37,22 +37,11 @@ #include #include +#include "conn.h" #include "request.h" #include "spdk/nvmf_spec.h" #include "spdk/queue.h" -/* - * This structure maintains local NVMf library specific connection - * state that includes an opaque pointer back to its parent fabric - * transport connection context. - */ -struct nvmf_connection_entry { - void *fabric_conn; - int is_aq_conn; - - TAILQ_ENTRY(nvmf_connection_entry) entries; -}; - /* define a virtual controller limit to the number of QPs supported */ #define MAX_SESSION_IO_QUEUES 64 @@ -76,7 +65,7 @@ struct nvmf_session { } vcprop; /* virtual controller properties */ struct spdk_nvme_ctrlr_data vcdata; /* virtual controller data */ - TAILQ_HEAD(connection_q, nvmf_connection_entry) connections; + TAILQ_HEAD(connection_q, spdk_nvmf_conn) connections; int num_connections; int max_connections_allowed; @@ -86,13 +75,13 @@ struct nvmf_session { }; struct nvmf_session * -nvmf_connect(void *fabric_conn, +nvmf_connect(struct spdk_nvmf_conn *conn, struct spdk_nvmf_fabric_connect_cmd *connect, struct spdk_nvmf_fabric_connect_data *connect_data, struct spdk_nvmf_fabric_connect_rsp *response); void -nvmf_disconnect(void *fabric_conn, struct nvmf_session *session); +nvmf_disconnect(struct nvmf_session *session, struct spdk_nvmf_conn *conn); void nvmf_init_session_properties(struct nvmf_session *session, int aq_depth);