bdev/nvme: change order of add/remove for discovery

If the path to a subsystem changes from one discovery
log to the next, we should add the new paths first,
and only then remove paths.  This ensures we don't
remove the last path to a subsystem, causing associated
bdevs to get unregisterd and reregistered.

This requires adding a new log_page member to
discovery_ctx, since we now need to walk the log
page to find removed paths after all the new paths
are attached.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: I99fc2e40e6f7e2e26d558ebe7bc5208fe474c0ea
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/11766
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
This commit is contained in:
Jim Harris 2022-02-25 00:22:54 +00:00 committed by Tomasz Zawadzki
parent e65549fc34
commit a96c1bfdbd

View File

@ -4147,6 +4147,7 @@ struct discovery_ctx {
struct spdk_nvme_transport_id trid;
struct spdk_poller *poller;
struct spdk_nvme_ctrlr_opts opts;
struct spdk_nvmf_discovery_log_page *log_page;
TAILQ_ENTRY(discovery_ctx) tailq;
TAILQ_HEAD(, discovery_entry_ctx) nvm_entry_ctxs;
TAILQ_HEAD(, discovery_entry_ctx) discovery_entry_ctxs;
@ -4230,35 +4231,15 @@ build_trid_from_log_page_entry(struct spdk_nvme_transport_id *trid,
}
static void
discovery_attach_controller_done(void *cb_ctx, size_t bdev_count, int rc)
discovery_remove_controllers(struct discovery_ctx *ctx)
{
struct discovery_entry_ctx *entry_ctx = cb_ctx;
struct discovery_ctx *ctx = entry_ctx->ctx;;
DISCOVERY_DEBUGLOG(ctx, "attach %s done\n", entry_ctx->name);
ctx->attach_in_progress--;
if (ctx->attach_in_progress == 0) {
discovery_complete(ctx);
}
}
static void
discovery_log_page_cb(void *cb_arg, int rc, const struct spdk_nvme_cpl *cpl,
struct spdk_nvmf_discovery_log_page *log_page)
{
struct discovery_ctx *ctx = cb_arg;
struct spdk_nvmf_discovery_log_page *log_page = ctx->log_page;
struct discovery_entry_ctx *entry_ctx, *tmp;
struct spdk_nvmf_discovery_log_page_entry *new_entry, *old_entry;
struct spdk_nvme_transport_id old_trid;
uint64_t numrec, i;
bool found;
if (rc || spdk_nvme_cpl_is_error(cpl)) {
DISCOVERY_ERRLOG(ctx, "could not get discovery log page\n");
return;
}
assert(ctx->attach_in_progress == 0);
numrec = from_le64(&log_page->numrec);
TAILQ_FOREACH_SAFE(entry_ctx, &ctx->nvm_entry_ctxs, tailq, tmp) {
found = false;
@ -4285,6 +4266,42 @@ discovery_log_page_cb(void *cb_arg, int rc, const struct spdk_nvme_cpl *cpl,
free(entry_ctx);
}
}
free(log_page);
ctx->log_page = NULL;
discovery_complete(ctx);
}
static void
discovery_attach_controller_done(void *cb_ctx, size_t bdev_count, int rc)
{
struct discovery_entry_ctx *entry_ctx = cb_ctx;
struct discovery_ctx *ctx = entry_ctx->ctx;;
DISCOVERY_DEBUGLOG(ctx, "attach %s done\n", entry_ctx->name);
ctx->attach_in_progress--;
if (ctx->attach_in_progress == 0) {
discovery_remove_controllers(ctx);
}
}
static void
discovery_log_page_cb(void *cb_arg, int rc, const struct spdk_nvme_cpl *cpl,
struct spdk_nvmf_discovery_log_page *log_page)
{
struct discovery_ctx *ctx = cb_arg;
struct discovery_entry_ctx *entry_ctx, *tmp;
struct spdk_nvmf_discovery_log_page_entry *new_entry, *old_entry;
uint64_t numrec, i;
bool found;
if (rc || spdk_nvme_cpl_is_error(cpl)) {
DISCOVERY_ERRLOG(ctx, "could not get discovery log page\n");
return;
}
ctx->log_page = log_page;
assert(ctx->attach_in_progress == 0);
numrec = from_le64(&log_page->numrec);
TAILQ_FOREACH_SAFE(entry_ctx, &ctx->discovery_entry_ctxs, tailq, tmp) {
TAILQ_REMOVE(&ctx->discovery_entry_ctxs, entry_ctx, tailq);
free(entry_ctx);
@ -4359,10 +4376,9 @@ discovery_log_page_cb(void *cb_arg, int rc, const struct spdk_nvme_cpl *cpl,
}
}
}
free(log_page);
if (ctx->attach_in_progress == 0) {
discovery_complete(ctx);
discovery_remove_controllers(ctx);
}
}