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 <benjamin.walker@intel.com>
This commit is contained in:
parent
2cb8321a35
commit
64f6abea9c
@ -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");
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,22 +37,11 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#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);
|
||||
|
Loading…
Reference in New Issue
Block a user