nvmf: extract some codes in functions.
This patch is used to solve https://github.com/spdk/spdk/issues/235 in the later patch. Change-Id: I8ef6d3effbff7a6b27e82c397969687d0000542b Signed-off-by: Ziye Yang <optimistyzy@gmail.com> Reviewed-on: https://review.gerrithub.io/399349 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
parent
0dd001465f
commit
114a91fdea
158
lib/nvmf/ctrlr.c
158
lib/nvmf/ctrlr.c
@ -152,6 +152,96 @@ spdk_nvmf_invalid_connect_response(struct spdk_nvmf_fabric_connect_rsp *rsp,
|
|||||||
#define SPDK_NVMF_INVALID_CONNECT_DATA(rsp, field) \
|
#define SPDK_NVMF_INVALID_CONNECT_DATA(rsp, field) \
|
||||||
spdk_nvmf_invalid_connect_response(rsp, 1, offsetof(struct spdk_nvmf_fabric_connect_data, field))
|
spdk_nvmf_invalid_connect_response(rsp, 1, offsetof(struct spdk_nvmf_fabric_connect_data, field))
|
||||||
|
|
||||||
|
static void
|
||||||
|
ctrlr_add_qpair_and_update_rsp(struct spdk_nvmf_qpair *qpair,
|
||||||
|
struct spdk_nvmf_ctrlr *ctrlr,
|
||||||
|
struct spdk_nvmf_fabric_connect_rsp *rsp)
|
||||||
|
{
|
||||||
|
qpair->ctrlr = ctrlr;
|
||||||
|
ctrlr->num_qpairs++;
|
||||||
|
TAILQ_INSERT_HEAD(&ctrlr->qpairs, qpair, link);
|
||||||
|
|
||||||
|
rsp->status.sc = SPDK_NVME_SC_SUCCESS;
|
||||||
|
rsp->status_code_specific.success.cntlid = ctrlr->cntlid;
|
||||||
|
SPDK_DEBUGLOG(SPDK_LOG_NVMF, "connect capsule response: cntlid = 0x%04x\n",
|
||||||
|
rsp->status_code_specific.success.cntlid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
spdk_nvmf_ctrlr_add_io_qpair(void *ctx)
|
||||||
|
{
|
||||||
|
struct spdk_nvmf_request *req = ctx;
|
||||||
|
struct spdk_nvmf_fabric_connect_cmd *cmd = &req->cmd->connect_cmd;
|
||||||
|
struct spdk_nvmf_fabric_connect_rsp *rsp = &req->rsp->connect_rsp;
|
||||||
|
struct spdk_nvmf_qpair *qpair = req->qpair;
|
||||||
|
struct spdk_nvmf_ctrlr *ctrlr = qpair->ctrlr;
|
||||||
|
|
||||||
|
/* Unit test will check qpair->ctrlr after calling spdk_nvmf_ctrlr_connect.
|
||||||
|
* For error case, the value should be NULL. So set it to NULL at first.
|
||||||
|
*/
|
||||||
|
qpair->ctrlr = NULL;
|
||||||
|
|
||||||
|
if (ctrlr->subsys->subtype == SPDK_NVMF_SUBTYPE_DISCOVERY) {
|
||||||
|
SPDK_ERRLOG("I/O connect not allowed on discovery controller\n");
|
||||||
|
SPDK_NVMF_INVALID_CONNECT_CMD(rsp, qid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ctrlr->vcprop.cc.bits.en) {
|
||||||
|
SPDK_ERRLOG("Got I/O connect before ctrlr was enabled\n");
|
||||||
|
SPDK_NVMF_INVALID_CONNECT_CMD(rsp, qid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (1u << ctrlr->vcprop.cc.bits.iosqes != sizeof(struct spdk_nvme_cmd)) {
|
||||||
|
SPDK_ERRLOG("Got I/O connect with invalid IOSQES %u\n",
|
||||||
|
ctrlr->vcprop.cc.bits.iosqes);
|
||||||
|
SPDK_NVMF_INVALID_CONNECT_CMD(rsp, qid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (1u << ctrlr->vcprop.cc.bits.iocqes != sizeof(struct spdk_nvme_cpl)) {
|
||||||
|
SPDK_ERRLOG("Got I/O connect with invalid IOCQES %u\n",
|
||||||
|
ctrlr->vcprop.cc.bits.iocqes);
|
||||||
|
SPDK_NVMF_INVALID_CONNECT_CMD(rsp, qid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spdk_nvmf_ctrlr_get_qpair(ctrlr, cmd->qid)) {
|
||||||
|
SPDK_ERRLOG("Got I/O connect with duplicate QID %u\n", cmd->qid);
|
||||||
|
rsp->status.sct = SPDK_NVME_SCT_GENERIC;
|
||||||
|
rsp->status.sc = SPDK_NVME_SC_COMMAND_SEQUENCE_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if we would exceed ctrlr connection limit */
|
||||||
|
if (ctrlr->num_qpairs >= ctrlr->max_qpairs_allowed) {
|
||||||
|
SPDK_ERRLOG("qpair limit %d\n", ctrlr->num_qpairs);
|
||||||
|
rsp->status.sct = SPDK_NVME_SCT_COMMAND_SPECIFIC;
|
||||||
|
rsp->status.sc = SPDK_NVMF_FABRIC_SC_CONTROLLER_BUSY;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrlr_add_qpair_and_update_rsp(qpair, ctrlr, rsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ctrlr_delete_qpair(void *ctx)
|
||||||
|
{
|
||||||
|
struct spdk_nvmf_qpair *qpair = ctx;
|
||||||
|
struct spdk_nvmf_ctrlr *ctrlr = qpair->ctrlr;
|
||||||
|
|
||||||
|
assert(ctrlr != NULL);
|
||||||
|
|
||||||
|
ctrlr->num_qpairs--;
|
||||||
|
TAILQ_REMOVE(&ctrlr->qpairs, qpair, link);
|
||||||
|
spdk_nvmf_transport_qpair_fini(qpair);
|
||||||
|
|
||||||
|
if (ctrlr->num_qpairs == 0) {
|
||||||
|
ctrlr_destruct(ctrlr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
spdk_nvmf_ctrlr_connect(struct spdk_nvmf_request *req)
|
spdk_nvmf_ctrlr_connect(struct spdk_nvmf_request *req)
|
||||||
{
|
{
|
||||||
@ -256,6 +346,9 @@ spdk_nvmf_ctrlr_connect(struct spdk_nvmf_request *req)
|
|||||||
rsp->status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR;
|
rsp->status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR;
|
||||||
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
|
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctrlr_add_qpair_and_update_rsp(qpair, ctrlr, rsp);
|
||||||
|
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
|
||||||
} else {
|
} else {
|
||||||
SPDK_DEBUGLOG(SPDK_LOG_NVMF, "Connect I/O Queue for controller id 0x%x\n", data->cntlid);
|
SPDK_DEBUGLOG(SPDK_LOG_NVMF, "Connect I/O Queue for controller id 0x%x\n", data->cntlid);
|
||||||
|
|
||||||
@ -266,73 +359,16 @@ spdk_nvmf_ctrlr_connect(struct spdk_nvmf_request *req)
|
|||||||
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
|
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctrlr->subsys->subtype == SPDK_NVMF_SUBTYPE_DISCOVERY) {
|
qpair->ctrlr = ctrlr;
|
||||||
SPDK_ERRLOG("I/O connect not allowed on discovery controller\n");
|
spdk_nvmf_ctrlr_add_io_qpair(req);
|
||||||
SPDK_NVMF_INVALID_CONNECT_CMD(rsp, qid);
|
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
|
||||||
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ctrlr->vcprop.cc.bits.en) {
|
|
||||||
SPDK_ERRLOG("Got I/O connect before ctrlr was enabled\n");
|
|
||||||
SPDK_NVMF_INVALID_CONNECT_CMD(rsp, qid);
|
|
||||||
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (1u << ctrlr->vcprop.cc.bits.iosqes != sizeof(struct spdk_nvme_cmd)) {
|
|
||||||
SPDK_ERRLOG("Got I/O connect with invalid IOSQES %u\n",
|
|
||||||
ctrlr->vcprop.cc.bits.iosqes);
|
|
||||||
SPDK_NVMF_INVALID_CONNECT_CMD(rsp, qid);
|
|
||||||
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (1u << ctrlr->vcprop.cc.bits.iocqes != sizeof(struct spdk_nvme_cpl)) {
|
|
||||||
SPDK_ERRLOG("Got I/O connect with invalid IOCQES %u\n",
|
|
||||||
ctrlr->vcprop.cc.bits.iocqes);
|
|
||||||
SPDK_NVMF_INVALID_CONNECT_CMD(rsp, qid);
|
|
||||||
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spdk_nvmf_ctrlr_get_qpair(ctrlr, cmd->qid)) {
|
|
||||||
SPDK_ERRLOG("Got I/O connect with duplicate QID %u\n", cmd->qid);
|
|
||||||
rsp->status.sct = SPDK_NVME_SCT_GENERIC;
|
|
||||||
rsp->status.sc = SPDK_NVME_SC_COMMAND_SEQUENCE_ERROR;
|
|
||||||
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check if we would exceed ctrlr connection limit */
|
|
||||||
if (ctrlr->num_qpairs >= ctrlr->max_qpairs_allowed) {
|
|
||||||
SPDK_ERRLOG("qpair limit %d\n", ctrlr->num_qpairs);
|
|
||||||
rsp->status.sct = SPDK_NVME_SCT_COMMAND_SPECIFIC;
|
|
||||||
rsp->status.sc = SPDK_NVMF_FABRIC_SC_CONTROLLER_BUSY;
|
|
||||||
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctrlr->num_qpairs++;
|
|
||||||
TAILQ_INSERT_HEAD(&ctrlr->qpairs, qpair, link);
|
|
||||||
qpair->ctrlr = ctrlr;
|
|
||||||
|
|
||||||
rsp->status.sc = SPDK_NVME_SC_SUCCESS;
|
|
||||||
rsp->status_code_specific.success.cntlid = ctrlr->cntlid;
|
|
||||||
SPDK_DEBUGLOG(SPDK_LOG_NVMF, "connect capsule response: cntlid = 0x%04x\n",
|
|
||||||
rsp->status_code_specific.success.cntlid);
|
|
||||||
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
spdk_nvmf_ctrlr_disconnect(struct spdk_nvmf_qpair *qpair)
|
spdk_nvmf_ctrlr_disconnect(struct spdk_nvmf_qpair *qpair)
|
||||||
{
|
{
|
||||||
struct spdk_nvmf_ctrlr *ctrlr = qpair->ctrlr;
|
ctrlr_delete_qpair(qpair);
|
||||||
|
|
||||||
assert(ctrlr != NULL);
|
|
||||||
ctrlr->num_qpairs--;
|
|
||||||
TAILQ_REMOVE(&ctrlr->qpairs, qpair, link);
|
|
||||||
|
|
||||||
spdk_nvmf_transport_qpair_fini(qpair);
|
|
||||||
|
|
||||||
if (ctrlr->num_qpairs == 0) {
|
|
||||||
ctrlr_destruct(ctrlr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct spdk_nvmf_qpair *
|
struct spdk_nvmf_qpair *
|
||||||
|
Loading…
Reference in New Issue
Block a user