diff --git a/lib/nvmf/ctrlr.c b/lib/nvmf/ctrlr.c index 5e92405ad..19b505731 100644 --- a/lib/nvmf/ctrlr.c +++ b/lib/nvmf/ctrlr.c @@ -1016,6 +1016,63 @@ spdk_nvmf_ctrlr_get_features_host_identifier(struct spdk_nvmf_request *req) return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; } +static int +spdk_nvmf_ctrlr_get_features_reservation_notification_mask(struct spdk_nvmf_request *req) +{ + struct spdk_nvmf_ctrlr *ctrlr = req->qpair->ctrlr; + struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; + struct spdk_nvme_cpl *rsp = &req->rsp->nvme_cpl; + struct spdk_nvmf_ns *ns; + + SPDK_DEBUGLOG(SPDK_LOG_NVMF, "get Features - Reservation Notificaton Mask\n"); + + if (cmd->nsid == 0xffffffffu) { + SPDK_ERRLOG("get Features - Invalid Namespace ID\n"); + rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD; + return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; + } + + ns = _spdk_nvmf_subsystem_get_ns(ctrlr->subsys, cmd->nsid); + if (ns == NULL) { + SPDK_ERRLOG("Set Features - Invalid Namespace ID\n"); + rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD; + return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; + } + rsp->cdw0 = ns->mask; + + return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; +} + +static int +spdk_nvmf_ctrlr_set_features_reservation_notification_mask(struct spdk_nvmf_request *req) +{ + struct spdk_nvmf_ctrlr *ctrlr = req->qpair->ctrlr; + struct spdk_nvmf_subsystem *subsystem = ctrlr->subsys; + struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; + struct spdk_nvme_cpl *rsp = &req->rsp->nvme_cpl; + struct spdk_nvmf_ns *ns; + + SPDK_DEBUGLOG(SPDK_LOG_NVMF, "Set Features - Reservation Notificaton Mask\n"); + + if (cmd->nsid == 0xffffffffu) { + for (ns = spdk_nvmf_subsystem_get_first_ns(subsystem); ns != NULL; + ns = spdk_nvmf_subsystem_get_next_ns(subsystem, ns)) { + ns->mask = cmd->cdw11; + } + return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; + } + + ns = _spdk_nvmf_subsystem_get_ns(ctrlr->subsys, cmd->nsid); + if (ns == NULL) { + SPDK_ERRLOG("Set Features - Invalid Namespace ID\n"); + rsp->status.sc = SPDK_NVME_SC_INVALID_FIELD; + return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; + } + ns->mask = cmd->cdw11; + + return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; +} + static int spdk_nvmf_ctrlr_get_features_reservation_persistence(struct spdk_nvmf_request *req) { @@ -1764,6 +1821,8 @@ spdk_nvmf_ctrlr_get_features(struct spdk_nvmf_request *req) return get_features_generic(req, ctrlr->feat.keep_alive_timer.raw); case SPDK_NVME_FEAT_HOST_IDENTIFIER: return spdk_nvmf_ctrlr_get_features_host_identifier(req); + case SPDK_NVME_FEAT_HOST_RESERVE_MASK: + return spdk_nvmf_ctrlr_get_features_reservation_notification_mask(req); case SPDK_NVME_FEAT_HOST_RESERVE_PERSIST: return spdk_nvmf_ctrlr_get_features_reservation_persistence(req); default: @@ -1802,6 +1861,8 @@ spdk_nvmf_ctrlr_set_features(struct spdk_nvmf_request *req) return spdk_nvmf_ctrlr_set_features_keep_alive_timer(req); case SPDK_NVME_FEAT_HOST_IDENTIFIER: return spdk_nvmf_ctrlr_set_features_host_identifier(req); + case SPDK_NVME_FEAT_HOST_RESERVE_MASK: + return spdk_nvmf_ctrlr_set_features_reservation_notification_mask(req); case SPDK_NVME_FEAT_HOST_RESERVE_PERSIST: return spdk_nvmf_ctrlr_set_features_reservation_persistence(req); default: diff --git a/lib/nvmf/nvmf_internal.h b/lib/nvmf/nvmf_internal.h index c9d18c553..812f0d09f 100644 --- a/lib/nvmf/nvmf_internal.h +++ b/lib/nvmf/nvmf_internal.h @@ -177,6 +177,8 @@ struct spdk_nvmf_ns { struct spdk_bdev *bdev; struct spdk_bdev_desc *desc; struct spdk_nvmf_ns_opts opts; + /* reservation notificaton mask */ + uint32_t mask; }; struct spdk_nvmf_qpair {