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
|
* going away. If this is the AQ connection then
|
||||||
* set state for other connections to abort.
|
* set state for other connections to abort.
|
||||||
*/
|
*/
|
||||||
nvmf_disconnect((void *)conn, conn->sess);
|
nvmf_disconnect(conn->sess, conn);
|
||||||
|
|
||||||
if (conn->type == CONN_TYPE_AQ) {
|
if (conn->type == CONN_TYPE_AQ) {
|
||||||
SPDK_TRACELOG(SPDK_TRACE_DEBUG, "AQ connection destruct, trigger session closure\n");
|
SPDK_TRACELOG(SPDK_TRACE_DEBUG, "AQ connection destruct, trigger session closure\n");
|
||||||
|
@ -59,10 +59,6 @@ struct spdk_nvmf_conn {
|
|||||||
|
|
||||||
struct nvmf_session *sess;
|
struct nvmf_session *sess;
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* values saved from fabric connect and private data
|
|
||||||
*/
|
|
||||||
uint16_t qid;
|
uint16_t qid;
|
||||||
uint16_t cntlid;
|
uint16_t cntlid;
|
||||||
|
|
||||||
|
@ -434,14 +434,18 @@ nvmf_process_connect(struct spdk_nvmf_request *req)
|
|||||||
|
|
||||||
response = &req->rsp->connect_rsp;
|
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) {
|
if (session != NULL) {
|
||||||
conn->sess = session;
|
conn->sess = session;
|
||||||
conn->qid = connect->qid;
|
if (conn->type == CONN_TYPE_AQ) {
|
||||||
if (connect->qid > 0) {
|
|
||||||
conn->type = CONN_TYPE_IOQ; /* I/O Connection */
|
|
||||||
} else {
|
|
||||||
/* When session first created, set some attributes */
|
|
||||||
nvmf_init_conn_properites(conn, session, response);
|
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 *
|
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_cmd *connect,
|
||||||
struct spdk_nvmf_fabric_connect_data *connect_data,
|
struct spdk_nvmf_fabric_connect_data *connect_data,
|
||||||
struct spdk_nvmf_fabric_connect_rsp *response)
|
struct spdk_nvmf_fabric_connect_rsp *response)
|
||||||
{
|
{
|
||||||
struct nvmf_session *session;
|
struct nvmf_session *session;
|
||||||
struct nvmf_connection_entry *connection = NULL;
|
|
||||||
|
|
||||||
connection = calloc(1, sizeof(struct nvmf_connection_entry));
|
if (conn->type == CONN_TYPE_AQ) {
|
||||||
if (connection == NULL)
|
/* For admin connections, establish a new session */
|
||||||
goto connect_fail;
|
SPDK_TRACELOG(SPDK_TRACE_NVMF, "CONNECT Admin Queue for controller id %d\n", conn->cntlid);
|
||||||
|
if (conn->cntlid != 0xFFFF) {
|
||||||
/* Figure out if this is the first connect and we
|
/* This NVMf target only supports dynamic mode. */
|
||||||
* need to allocate an nvmf_session or if this is
|
SPDK_ERRLOG("The NVMf target only supports dynamic mode.\n");
|
||||||
* 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);
|
|
||||||
response->status.sc = SPDK_NVMF_FABRIC_SC_INVALID_PARAM;
|
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 {
|
} else {
|
||||||
SPDK_TRACELOG(SPDK_TRACE_NVMF, "IOQ connect capsule\n");
|
SPDK_TRACELOG(SPDK_TRACE_NVMF, "CONNECT I/O Queue for controller id %d\n", conn->cntlid);
|
||||||
/* locate the existing session */
|
|
||||||
session = nvmf_find_session_by_id(connect_data->subnqn, connect_data->cntlid);
|
session = nvmf_find_session_by_id(connect_data->subnqn, connect_data->cntlid);
|
||||||
if (session == NULL) {
|
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;
|
response->status.sc = SPDK_NVMF_FABRIC_SC_RESTART_DISCOVERY;
|
||||||
goto connect_fail;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if we would exceed session connection limit */
|
/* check if we would exceed session connection limit */
|
||||||
if (session->num_connections >= session->max_connections_allowed) {
|
if (session->num_connections >= session->max_connections_allowed) {
|
||||||
SPDK_ERRLOG("connection limit %d\n", session->num_connections);
|
SPDK_ERRLOG("connection limit %d\n", session->num_connections);
|
||||||
response->status.sc = SPDK_NVMF_FABRIC_SC_CONTROLLER_BUSY;
|
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++;
|
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_code_specific.success.cntlid = session->cntlid;
|
||||||
response->status.sc = 0;
|
response->status.sc = 0;
|
||||||
|
|
||||||
return session;
|
return session;
|
||||||
|
|
||||||
connect_fail:
|
|
||||||
if (connection)
|
|
||||||
free(connection);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nvmf_disconnect(void *fabric_conn,
|
nvmf_disconnect(struct nvmf_session *session,
|
||||||
struct nvmf_session *session)
|
struct spdk_nvmf_conn *conn)
|
||||||
{
|
{
|
||||||
struct nvmf_connection_entry *conn, *tconn, *rconn = NULL;
|
if (session) {
|
||||||
|
if (session->num_connections > 0) {
|
||||||
/* Indication from the fabric transport that a
|
session->num_connections--;
|
||||||
* specific connection has gone way. If the
|
TAILQ_REMOVE(&session->connections, conn, link);
|
||||||
* 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 (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--;
|
if (session->num_connections == 0) {
|
||||||
TAILQ_REMOVE(&session->connections, rconn, entries);
|
nvmf_delete_session(session);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,22 +37,11 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "conn.h"
|
||||||
#include "request.h"
|
#include "request.h"
|
||||||
#include "spdk/nvmf_spec.h"
|
#include "spdk/nvmf_spec.h"
|
||||||
#include "spdk/queue.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 a virtual controller limit to the number of QPs supported */
|
||||||
#define MAX_SESSION_IO_QUEUES 64
|
#define MAX_SESSION_IO_QUEUES 64
|
||||||
|
|
||||||
@ -76,7 +65,7 @@ struct nvmf_session {
|
|||||||
} vcprop; /* virtual controller properties */
|
} vcprop; /* virtual controller properties */
|
||||||
struct spdk_nvme_ctrlr_data vcdata; /* virtual controller data */
|
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 num_connections;
|
||||||
int max_connections_allowed;
|
int max_connections_allowed;
|
||||||
|
|
||||||
@ -86,13 +75,13 @@ struct nvmf_session {
|
|||||||
};
|
};
|
||||||
|
|
||||||
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_cmd *connect,
|
||||||
struct spdk_nvmf_fabric_connect_data *connect_data,
|
struct spdk_nvmf_fabric_connect_data *connect_data,
|
||||||
struct spdk_nvmf_fabric_connect_rsp *response);
|
struct spdk_nvmf_fabric_connect_rsp *response);
|
||||||
|
|
||||||
void
|
void
|
||||||
nvmf_disconnect(void *fabric_conn, struct nvmf_session *session);
|
nvmf_disconnect(struct nvmf_session *session, struct spdk_nvmf_conn *conn);
|
||||||
|
|
||||||
void
|
void
|
||||||
nvmf_init_session_properties(struct nvmf_session *session, int aq_depth);
|
nvmf_init_session_properties(struct nvmf_session *session, int aq_depth);
|
||||||
|
Loading…
Reference in New Issue
Block a user