nvmf: stub out Abort command support

Add handling of the Abort command in virtual subsystems.  This doesn't
actually abort any requests - the spdk_nvmf_request_abort()
implementation just fails all abort requests - but at least this gives
us a place to hook up actual abort handling later.

Change-Id: Iafaa393c6f9e7f404af91747cbd81c64ab4810bb
Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-on: https://review.gerrithub.io/365905
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Daniel Verkamp 2017-06-16 10:06:09 -07:00
parent 27becf40d0
commit 2d34864a61
6 changed files with 103 additions and 0 deletions

View File

@ -311,3 +311,10 @@ spdk_nvmf_request_exec(struct spdk_nvmf_request *req)
return 0;
}
int
spdk_nvmf_request_abort(struct spdk_nvmf_request *req)
{
/* TODO: implement abort, at least for commands that are still queued in software */
return -1;
}

View File

@ -73,4 +73,6 @@ spdk_nvmf_request_exec(struct spdk_nvmf_request *req);
int spdk_nvmf_request_complete(struct spdk_nvmf_request *req);
int spdk_nvmf_request_abort(struct spdk_nvmf_request *req);
#endif

View File

@ -273,6 +273,7 @@ spdk_nvmf_session_connect(struct spdk_nvmf_conn *conn,
return;
}
conn->sq_head_max = cmd->sqsize;
conn->qid = cmd->qid;
if (cmd->qid == 0) {
conn->type = CONN_TYPE_AQ;
@ -405,6 +406,26 @@ spdk_nvmf_session_disconnect(struct spdk_nvmf_conn *conn)
}
}
struct spdk_nvmf_conn *
spdk_nvmf_session_get_conn(struct spdk_nvmf_session *session, uint16_t qid)
{
struct spdk_nvmf_conn *conn;
TAILQ_FOREACH(conn, &session->connections, link) {
if (conn->qid == qid) {
return conn;
}
}
return NULL;
}
struct spdk_nvmf_request *
spdk_nvmf_conn_get_request(struct spdk_nvmf_conn *conn, uint16_t cid)
{
/* TODO: track list of outstanding requests in conn? */
return NULL;
}
static uint64_t
nvmf_prop_get_cap(struct spdk_nvmf_session *session)
{

View File

@ -55,6 +55,7 @@ struct spdk_nvmf_conn {
struct spdk_nvmf_session *sess;
enum conn_type type;
uint16_t qid;
uint16_t sq_head;
uint16_t sq_head_max;
@ -102,6 +103,10 @@ void spdk_nvmf_session_connect(struct spdk_nvmf_conn *conn,
struct spdk_nvmf_fabric_connect_data *data,
struct spdk_nvmf_fabric_connect_rsp *rsp);
struct spdk_nvmf_conn *spdk_nvmf_session_get_conn(struct spdk_nvmf_session *session, uint16_t qid);
struct spdk_nvmf_request *spdk_nvmf_conn_get_request(struct spdk_nvmf_conn *conn, uint16_t cid);
void
spdk_nvmf_property_get(struct spdk_nvmf_session *session,
struct spdk_nvmf_fabric_prop_get_cmd *cmd,

View File

@ -286,6 +286,53 @@ nvmf_virtual_ctrlr_identify(struct spdk_nvmf_request *req)
}
}
static int
nvmf_virtual_ctrlr_abort(struct spdk_nvmf_request *req)
{
struct spdk_nvmf_session *session = req->conn->sess;
struct spdk_nvme_cpl *rsp = &req->rsp->nvme_cpl;
struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
uint32_t cdw10 = cmd->cdw10;
uint16_t cid = cdw10 >> 16;
uint16_t sqid = cdw10 & 0xFFFFu;
struct spdk_nvmf_conn *conn;
struct spdk_nvmf_request *req_to_abort;
SPDK_TRACELOG(SPDK_TRACE_NVMF, "abort sqid=%u cid=%u\n", sqid, cid);
rsp->cdw0 = 1; /* Command not aborted */
conn = spdk_nvmf_session_get_conn(session, sqid);
if (conn == NULL) {
SPDK_TRACELOG(SPDK_TRACE_NVMF, "sqid %u not found\n", sqid);
rsp->status.sct = SPDK_NVME_SCT_GENERIC;
rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD;
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
}
/*
* NOTE: This relies on the assumption that all connections for a session will be handled
* on the same thread. If this assumption becomes untrue, this will need to pass a message
* to the thread handling conn, and the abort will need to be asynchronous.
*/
req_to_abort = spdk_nvmf_conn_get_request(conn, cid);
if (req_to_abort == NULL) {
SPDK_TRACELOG(SPDK_TRACE_NVMF, "cid %u not found\n", cid);
rsp->status.sct = SPDK_NVME_SCT_GENERIC;
rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD;
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
}
if (spdk_nvmf_request_abort(req_to_abort) == 0) {
SPDK_TRACELOG(SPDK_TRACE_NVMF, "abort session=%p req=%p sqid=%u cid=%u successful\n",
session, req_to_abort, sqid, cid);
rsp->cdw0 = 0; /* Command successfully aborted */
}
rsp->status.sct = SPDK_NVME_SCT_GENERIC;
rsp->status.sc = SPDK_NVME_SC_SUCCESS;
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
}
static int
nvmf_virtual_ctrlr_get_features(struct spdk_nvmf_request *req)
{
@ -351,6 +398,8 @@ nvmf_virtual_ctrlr_process_admin_cmd(struct spdk_nvmf_request *req)
return nvmf_virtual_ctrlr_get_log_page(req);
case SPDK_NVME_OPC_IDENTIFY:
return nvmf_virtual_ctrlr_identify(req);
case SPDK_NVME_OPC_ABORT:
return nvmf_virtual_ctrlr_abort(req);
case SPDK_NVME_OPC_GET_FEATURES:
return nvmf_virtual_ctrlr_get_features(req);
case SPDK_NVME_OPC_SET_FEATURES:

View File

@ -39,6 +39,19 @@
SPDK_LOG_REGISTER_TRACE_FLAG("nvmf", SPDK_TRACE_NVMF)
struct spdk_nvmf_conn *
spdk_nvmf_session_get_conn(struct spdk_nvmf_session *session, uint16_t qid)
{
return NULL;
}
struct spdk_nvmf_request *
spdk_nvmf_conn_get_request(struct spdk_nvmf_conn *conn, uint16_t cid)
{
return NULL;
}
int
spdk_nvmf_session_get_features_number_of_queues(struct spdk_nvmf_request *req)
{
@ -97,6 +110,12 @@ spdk_nvmf_request_complete(struct spdk_nvmf_request *req)
return -1;
}
int
spdk_nvmf_request_abort(struct spdk_nvmf_request *req)
{
return -1;
}
const char *
spdk_bdev_get_name(const struct spdk_bdev *bdev)
{