lib/nvmf: Optionalize ANA reporting feature

After supporting ANA reporting by default, Linux kernel 5.3 reported
error when parsing NVMe ANA log. The newer kernel fixed the issue
but we should optionalize ANA reporting feature to avoid error for
Linux kernel 5.3 or before.

Add a bool variable ana_reporting to struct spdk_nvmf_subsystem
and disable ANA reporting and initialization of related variables
if it is false. We can expose MNAN (Maximum Number of Allowed
Namespaces) even if ANA reporting is disabled. But MNAN is not
required if ANA reporting is disabled. So do not set MNAN if it is
false too.

Add a public API spdk_nvmf_subsystem_set_ana_reporting() to set
ana_reporting by the nvmf_create_subssytem RPC.

The next patch will add ana_reporting to nvmf_create_subsystem RPC.

Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: Icc77773b4c9513daba2f1a9fdaf951d80574f379
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/3850
Community-CI: Mellanox Build Bot
Community-CI: Broadcom CI
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Monica Kenguva <monica.kenguva@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Shuhei Matsumoto 2020-08-19 13:51:54 +09:00 committed by Tomasz Zawadzki
parent 4cc04a1251
commit 6f2265734d
5 changed files with 53 additions and 12 deletions

View File

@ -654,6 +654,20 @@ void spdk_nvmf_subsystem_allow_any_listener(
bool spdk_nvmf_subsytem_any_listener_allowed(
struct spdk_nvmf_subsystem *subsystem);
/**
* Set whether a subsystem supports Asymmetric Namespace Access (ANA)
* reporting.
*
* May only be performed on subsystems in the INACTIVE state.
*
* \param subsystem Subsystem to modify.
* \param ana_reporting true to support or false not to support ANA reporting.
*
* \return 0 on success, or negated errno value on failure.
*/
int spdk_nvmf_subsystem_set_ana_reporting(struct spdk_nvmf_subsystem *subsystem,
bool ana_reporting);
/** NVMe-oF target namespace creation options */
struct spdk_nvmf_ns_opts {
/**

View File

@ -1903,8 +1903,12 @@ nvmf_ctrlr_get_log_page(struct spdk_nvmf_request *req)
nvmf_get_firmware_slot_log_page(req->data, offset, len);
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
case SPDK_NVME_LOG_ASYMMETRIC_NAMESPACE_ACCESS:
nvmf_get_ana_log_page(ctrlr, req->data, offset, len);
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
if (subsystem->ana_reporting) {
nvmf_get_ana_log_page(ctrlr, req->data, offset, len);
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
} else {
goto invalid_log_page;
}
case SPDK_NVME_LOG_COMMAND_EFFECTS_LOG:
nvmf_get_cmds_and_effects_log_page(req->data, offset, len);
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
@ -1965,8 +1969,10 @@ spdk_nvmf_ctrlr_identify_ns(struct spdk_nvmf_ctrlr *ctrlr,
nsdata->noiob = max_num_blocks;
}
/* ANA group ID matches NSID. */
nsdata->anagrpid = ns->nsid;
if (subsystem->ana_reporting) {
/* ANA group ID matches NSID. */
nsdata->anagrpid = ns->nsid;
}
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
}
@ -2017,7 +2023,9 @@ spdk_nvmf_ctrlr_identify_ctrlr(struct spdk_nvmf_ctrlr *ctrlr, struct spdk_nvme_c
cdata->sgls = ctrlr->cdata.sgls;
cdata->fuses.compare_and_write = 1;
cdata->acwu = 1;
cdata->mnan = subsystem->max_nsid;
if (subsystem->ana_reporting) {
cdata->mnan = subsystem->max_nsid;
}
spdk_strcpy_pad(cdata->subnqn, subsystem->subnqn, sizeof(cdata->subnqn), '\0');
SPDK_DEBUGLOG(SPDK_LOG_NVMF, "ctrlr data: maxcmd 0x%x\n", cdata->maxcmd);
@ -2034,8 +2042,10 @@ spdk_nvmf_ctrlr_identify_ctrlr(struct spdk_nvmf_ctrlr *ctrlr, struct spdk_nvme_c
cdata->rab = 6;
cdata->cmic.multi_port = 1;
cdata->cmic.multi_host = 1;
/* Asymmetric Namespace Access Reporting is supported. */
cdata->cmic.ana_reporting = 1;
if (subsystem->ana_reporting) {
/* Asymmetric Namespace Access Reporting is supported. */
cdata->cmic.ana_reporting = 1;
}
cdata->oaes.ns_attribute_notices = 1;
cdata->ctratt.host_id_exhid_supported = 1;
/* TODO: Concurrent execution of multiple abort commands. */
@ -2059,11 +2069,13 @@ spdk_nvmf_ctrlr_identify_ctrlr(struct spdk_nvmf_ctrlr *ctrlr, struct spdk_nvme_c
cdata->oncs.dsm = nvmf_ctrlr_dsm_supported(ctrlr);
cdata->oncs.write_zeroes = nvmf_ctrlr_write_zeroes_supported(ctrlr);
cdata->oncs.reservations = 1;
cdata->anacap.ana_optimized_state = 1;
/* ANAGRPID does not change while namespace is attached to controller */
cdata->anacap.no_change_anagrpid = 1;
cdata->anagrpmax = subsystem->max_nsid;
cdata->nanagrpid = subsystem->max_nsid;
if (subsystem->ana_reporting) {
cdata->anacap.ana_optimized_state = 1;
/* ANAGRPID does not change while namespace is attached to controller */
cdata->anacap.no_change_anagrpid = 1;
cdata->anagrpmax = subsystem->max_nsid;
cdata->nanagrpid = subsystem->max_nsid;
}
nvmf_ctrlr_populate_oacs(ctrlr, cdata);

View File

@ -249,6 +249,7 @@ struct spdk_nvmf_subsystem {
uint16_t next_cntlid;
bool allow_any_host;
bool allow_any_listener;
bool ana_reporting;
struct spdk_nvmf_tgt *tgt;

View File

@ -79,6 +79,7 @@
spdk_nvmf_transport_poll_group_get_stat;
spdk_nvmf_transport_poll_group_free_stat;
spdk_nvmf_rdma_init_hooks;
spdk_nvmf_subsystem_set_ana_reporting;
# public functions in nvmf_cmd.h
spdk_nvmf_ctrlr_identify_ctrlr;

View File

@ -2513,3 +2513,16 @@ nvmf_ns_reservation_request(void *ctx)
update_done:
_nvmf_ns_reservation_update_done(ctrlr->subsys, (void *)req, 0);
}
int
spdk_nvmf_subsystem_set_ana_reporting(struct spdk_nvmf_subsystem *subsystem,
bool ana_reporting)
{
if (subsystem->state != SPDK_NVMF_SUBSYSTEM_INACTIVE) {
return -EAGAIN;
}
subsystem->ana_reporting = ana_reporting;
return 0;
}