nvmf: handle iovecs in reservation handling

Use req->iov instead of req->data in reservation handling code.

Signed-off-by: John Levon <john.levon@nutanix.com>
Change-Id: I6d79711d03f45bd5e118c6324d22decad887a788
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16199
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
John Levon 2023-01-08 00:34:35 +00:00 committed by Tomasz Zawadzki
parent 7db282dc26
commit cc3184b8b4

View File

@ -2583,9 +2583,9 @@ nvmf_ns_reservation_register(struct spdk_nvmf_ns *ns,
struct spdk_nvmf_ctrlr *ctrlr,
struct spdk_nvmf_request *req)
{
struct spdk_nvme_reservation_register_data key = { 0 };
struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
uint8_t rrega, iekey, cptpl, rtype;
struct spdk_nvme_reservation_register_data key;
struct spdk_nvmf_registrant *reg;
uint8_t status = SPDK_NVME_SC_SUCCESS;
bool update_sgroup = false;
@ -2597,8 +2597,10 @@ nvmf_ns_reservation_register(struct spdk_nvmf_ns *ns,
iekey = cmd->cdw10_bits.resv_register.iekey;
cptpl = cmd->cdw10_bits.resv_register.cptpl;
if (req->data && req->length >= sizeof(key)) {
memcpy(&key, req->data, sizeof(key));
if (req->iovcnt > 0 && req->length >= sizeof(key)) {
struct spdk_iov_xfer ix;
spdk_iov_xfer_init(&ix, req->iov, req->iovcnt);
spdk_iov_xfer_to_buf(&ix, &key, sizeof(key));
} else {
SPDK_ERRLOG("No key provided. Failing request.\n");
status = SPDK_NVME_SC_INVALID_FIELD;
@ -2733,9 +2735,9 @@ nvmf_ns_reservation_acquire(struct spdk_nvmf_ns *ns,
struct spdk_nvmf_ctrlr *ctrlr,
struct spdk_nvmf_request *req)
{
struct spdk_nvme_reservation_acquire_data key = { 0 };
struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
uint8_t racqa, iekey, rtype;
struct spdk_nvme_reservation_acquire_data key;
struct spdk_nvmf_registrant *reg;
bool all_regs = false;
uint32_t count = 0;
@ -2751,8 +2753,10 @@ nvmf_ns_reservation_acquire(struct spdk_nvmf_ns *ns,
iekey = cmd->cdw10_bits.resv_acquire.iekey;
rtype = cmd->cdw10_bits.resv_acquire.rtype;
if (req->data && req->length >= sizeof(key)) {
memcpy(&key, req->data, sizeof(key));
if (req->iovcnt > 0 && req->length >= sizeof(key)) {
struct spdk_iov_xfer ix;
spdk_iov_xfer_init(&ix, req->iov, req->iovcnt);
spdk_iov_xfer_to_buf(&ix, &key, sizeof(key));
} else {
SPDK_ERRLOG("No key provided. Failing request.\n");
status = SPDK_NVME_SC_INVALID_FIELD;
@ -2903,7 +2907,7 @@ nvmf_ns_reservation_release(struct spdk_nvmf_ns *ns,
struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
uint8_t rrela, iekey, rtype;
struct spdk_nvmf_registrant *reg;
uint64_t crkey;
uint64_t crkey = 0;
uint8_t status = SPDK_NVME_SC_SUCCESS;
bool update_sgroup = true;
struct spdk_uuid hostid_list[SPDK_NVMF_MAX_NUM_REGISTRANTS];
@ -2913,8 +2917,10 @@ nvmf_ns_reservation_release(struct spdk_nvmf_ns *ns,
iekey = cmd->cdw10_bits.resv_release.iekey;
rtype = cmd->cdw10_bits.resv_release.rtype;
if (req->data && req->length >= sizeof(crkey)) {
memcpy(&crkey, req->data, sizeof(crkey));
if (req->iovcnt > 0 && req->length >= sizeof(crkey)) {
struct spdk_iov_xfer ix;
spdk_iov_xfer_init(&ix, req->iov, req->iovcnt);
spdk_iov_xfer_to_buf(&ix, &crkey, sizeof(crkey));
} else {
SPDK_ERRLOG("No key provided. Failing request.\n");
status = SPDK_NVME_SC_INVALID_FIELD;
@ -3007,14 +3013,13 @@ nvmf_ns_reservation_report(struct spdk_nvmf_ns *ns,
{
struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
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 transfer_len, payload_len = 0;
struct spdk_nvme_reservation_status_extended_data status_data = { 0 };
struct spdk_iov_xfer ix;
uint32_t transfer_len;
uint32_t regctl = 0;
uint8_t status = SPDK_NVME_SC_SUCCESS;
if (req->data == NULL) {
if (req->iovcnt == 0) {
SPDK_ERRLOG("No data transfer specified for request. "
" Unable to transfer back response.\n");
status = SPDK_NVME_SC_INVALID_FIELD;
@ -3030,35 +3035,44 @@ nvmf_ns_reservation_report(struct spdk_nvmf_ns *ns,
/* Number of Dwords of the Reservation Status data structure to transfer */
transfer_len = (cmd->cdw10 + 1) * sizeof(uint32_t);
payload = req->data;
if (transfer_len < sizeof(struct spdk_nvme_reservation_status_extended_data)) {
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.ptpls = ns->ptpl_activated;
payload_len += sizeof(struct spdk_nvme_reservation_status_extended_data);
spdk_iov_xfer_init(&ix, req->iov, req->iovcnt);
status_data.data.gen = ns->gen;
status_data.data.rtype = ns->rtype;
status_data.data.ptpls = ns->ptpl_activated;
TAILQ_FOREACH_SAFE(reg, &ns->registrants, link, tmp) {
payload_len += sizeof(struct spdk_nvme_registered_ctrlr_extended_data);
if (payload_len > transfer_len) {
break;
}
ctrlr_data = (struct spdk_nvme_registered_ctrlr_extended_data *)
(payload + sizeof(*status_data) + sizeof(*ctrlr_data) * regctl);
/* 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, &reg->hostid);
regctl++;
}
status_data->data.regctl = regctl;
/*
* We report the number of registrants as per the spec here, even if
* the iov isn't big enough to contain them all. In that case, the
* spdk_iov_xfer_from_buf() won't actually copy any of the remaining
* data; as it keeps track of the iov cursor itself, it's simplest to
* just walk the entire list anyway.
*/
status_data.data.regctl = regctl;
spdk_iov_xfer_from_buf(&ix, &status_data, sizeof(status_data));
TAILQ_FOREACH_SAFE(reg, &ns->registrants, link, tmp) {
struct spdk_nvme_registered_ctrlr_extended_data ctrlr_data = { 0 };
/* 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, &reg->hostid);
spdk_iov_xfer_from_buf(&ix, &ctrlr_data, sizeof(ctrlr_data));
}
exit:
req->rsp->nvme_cpl.status.sct = SPDK_NVME_SCT_GENERIC;