nvmf: add namespace reservation report command support
For number of registered controllers field in Reservation Status Data Structure, we caculate all the controllers in the subsystem which Host Identifier are same with existing registrants. Change-Id: Ib4de22c7020dbd8294f448f23c0c5c8c142629dd Signed-off-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/436939 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
4cd6544d44
commit
4b55682e3a
@ -2130,6 +2130,7 @@ spdk_nvmf_ctrlr_process_io_cmd(struct spdk_nvmf_request *req)
|
||||
case SPDK_NVME_OPC_RESERVATION_REGISTER:
|
||||
case SPDK_NVME_OPC_RESERVATION_ACQUIRE:
|
||||
case SPDK_NVME_OPC_RESERVATION_RELEASE:
|
||||
case SPDK_NVME_OPC_RESERVATION_REPORT:
|
||||
spdk_thread_send_msg(ctrlr->subsys->thread, spdk_nvmf_ns_reservation_request, req);
|
||||
return SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS;
|
||||
default:
|
||||
|
@ -1705,6 +1705,76 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
nvmf_ns_reservation_report(struct spdk_nvmf_ns *ns,
|
||||
struct spdk_nvmf_ctrlr *ctrlr,
|
||||
struct spdk_nvmf_request *req)
|
||||
{
|
||||
struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
|
||||
struct spdk_nvmf_subsystem *subsystem = ctrlr->subsys;
|
||||
struct spdk_nvmf_ctrlr *ctrlr_tmp;
|
||||
struct spdk_nvmf_registrant *reg, *tmp;
|
||||
struct spdk_nvme_reservation_status_extended_data *status_data;
|
||||
struct spdk_nvme_registered_ctrlr_extended_data *ctrlr_data;
|
||||
uint8_t *payload;
|
||||
uint32_t len, count = 0;
|
||||
uint32_t regctl = 0;
|
||||
uint8_t status = SPDK_NVME_SC_SUCCESS;
|
||||
|
||||
/* NVMeoF uses Extended Data Structure */
|
||||
if ((cmd->cdw11 & 0x00000001u) == 0) {
|
||||
SPDK_ERRLOG("NVMeoF uses extended controller data structure, "
|
||||
"please set EDS bit in cdw11 and try again\n");
|
||||
status = SPDK_NVME_SC_INVALID_FIELD;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Get number of registerd controllers, one Host may have more than
|
||||
* one controller based on different ports.
|
||||
*/
|
||||
TAILQ_FOREACH(ctrlr_tmp, &subsystem->ctrlrs, link) {
|
||||
reg = nvmf_ns_reservation_get_registrant(ns, &ctrlr_tmp->hostid);
|
||||
if (reg) {
|
||||
regctl++;
|
||||
}
|
||||
}
|
||||
|
||||
len = sizeof(*status_data) + sizeof(*ctrlr_data) * regctl;
|
||||
payload = calloc(1, len);
|
||||
if (!payload) {
|
||||
status = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status_data = (struct spdk_nvme_reservation_status_extended_data *)payload;
|
||||
status_data->data.gen = ns->gen;
|
||||
status_data->data.rtype = ns->rtype;
|
||||
status_data->data.regctl = regctl;
|
||||
/* TODO: Don't support Persist Through Power Loss State for now */
|
||||
status_data->data.ptpls = 0;
|
||||
|
||||
TAILQ_FOREACH_SAFE(reg, &ns->registrants, link, tmp) {
|
||||
assert(count <= regctl);
|
||||
ctrlr_data = (struct spdk_nvme_registered_ctrlr_extended_data *)
|
||||
(payload + sizeof(*status_data) + sizeof(*ctrlr_data) * count);
|
||||
/* Set to 0xffffh for dynamic controller */
|
||||
ctrlr_data->cntlid = 0xffff;
|
||||
ctrlr_data->rcsts.status = (ns->holder == reg) ? true : false;
|
||||
ctrlr_data->rkey = reg->rkey;
|
||||
spdk_uuid_copy((struct spdk_uuid *)ctrlr_data->hostid, ®->hostid);
|
||||
count++;
|
||||
}
|
||||
|
||||
memcpy(req->data, payload, spdk_min(len, (cmd->cdw10 + 1) * sizeof(uint32_t)));
|
||||
free(payload);
|
||||
|
||||
exit:
|
||||
req->rsp->nvme_cpl.status.sct = SPDK_NVME_SCT_GENERIC;
|
||||
req->rsp->nvme_cpl.status.sc = status;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
spdk_nvmf_ns_reservation_complete(void *ctx)
|
||||
{
|
||||
@ -1737,6 +1807,9 @@ spdk_nvmf_ns_reservation_request(void *ctx)
|
||||
case SPDK_NVME_OPC_RESERVATION_RELEASE:
|
||||
nvmf_ns_reservation_release(ns, ctrlr, req);
|
||||
break;
|
||||
case SPDK_NVME_OPC_RESERVATION_REPORT:
|
||||
nvmf_ns_reservation_report(ns, ctrlr, req);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user