nvme: restart discovery log when genctr changes

Each portion of the discovery log has a header which
includes a 'genctr'. This number indicates the
current generation of the discovery log. If this
number changes during the process of fetching the
discovery log in multiple chunks, wait for the
current fetch to complete, but then start over.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: I5f8623593b7f935eecc37a98daf92e7d8c0dd566
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/10813
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
Jim Harris 2021-12-21 23:18:29 +00:00 committed by Tomasz Zawadzki
parent 6a520ae644
commit 1ea419ecd7

View File

@ -44,11 +44,37 @@ struct nvme_discovery_ctx {
uint32_t outstanding_commands;
};
static void
get_log_page_completion_final(void *cb_arg, const struct spdk_nvme_cpl *cpl)
{
struct nvme_discovery_ctx *ctx = cb_arg;
int rc;
if (spdk_nvme_cpl_is_error(cpl)) {
free(ctx->log_page);
ctx->cb_fn(ctx->cb_arg, 0, cpl, NULL);
free(ctx);
return;
}
/* Compare original genctr with latest genctr. If it changed, we need to restart. */
if (ctx->log_page->genctr == ctx->genctr) {
ctx->cb_fn(ctx->cb_arg, 0, cpl, ctx->log_page);
} else {
free(ctx->log_page);
rc = spdk_nvme_ctrlr_get_discovery_log_page(ctx->ctrlr, ctx->cb_fn, ctx->cb_arg);
if (rc != 0) {
ctx->cb_fn(ctx->cb_arg, rc, NULL, NULL);
}
}
free(ctx);
}
static void
get_log_page_completion(void *cb_arg, const struct spdk_nvme_cpl *cpl)
{
struct nvme_discovery_ctx *ctx = cb_arg;
struct spdk_nvmf_discovery_log_page *log_page;
int rc;
if (spdk_nvme_cpl_is_error(cpl)) {
/* Only save the cpl for the first error that we encounter. */
@ -61,16 +87,21 @@ get_log_page_completion(void *cb_arg, const struct spdk_nvme_cpl *cpl)
return;
}
if (!spdk_nvme_cpl_is_error(&ctx->cpl)) {
log_page = ctx->log_page;
} else {
/* We had an error, so don't return the log page to the caller. */
log_page = NULL;
if (spdk_nvme_cpl_is_error(&ctx->cpl)) {
free(ctx->log_page);
ctx->cb_fn(ctx->cb_arg, 0, &ctx->cpl, NULL);
free(ctx);
return;
}
ctx->cb_fn(ctx->cb_arg, 0, &ctx->cpl, log_page);
free(ctx);
rc = spdk_nvme_ctrlr_cmd_get_log_page(ctx->ctrlr, SPDK_NVME_LOG_DISCOVERY, 0,
&ctx->genctr, sizeof(ctx->genctr), 0,
get_log_page_completion_final, ctx);
if (rc != 0) {
free(ctx->log_page);
ctx->cb_fn(ctx->cb_arg, rc, NULL, NULL);
free(ctx);
}
}
static void