diff --git a/lib/nvmf/ctrlr_discovery.c b/lib/nvmf/ctrlr_discovery.c index 331d4ab0c..1727e6ce9 100644 --- a/lib/nvmf/ctrlr_discovery.c +++ b/lib/nvmf/ctrlr_discovery.c @@ -168,7 +168,7 @@ nvmf_generate_discovery_log(struct spdk_nvmf_tgt *tgt, const char *hostnqn, size entry = &disc_log->entries[numrec]; memset(entry, 0, sizeof(*entry)); - entry->portid = numrec; + entry->portid = listener->id; entry->cntlid = 0xffff; entry->asqsz = listener->transport->opts.max_aq_depth; entry->subtype = subsystem->subtype; diff --git a/lib/nvmf/nvmf_internal.h b/lib/nvmf/nvmf_internal.h index a3ebdd205..6bb3987f6 100644 --- a/lib/nvmf/nvmf_internal.h +++ b/lib/nvmf/nvmf_internal.h @@ -106,6 +106,7 @@ struct spdk_nvmf_subsystem_listener { struct spdk_nvmf_transport *transport; enum spdk_nvme_ana_state *ana_state; uint64_t ana_state_change_count; + uint16_t id; TAILQ_ENTRY(spdk_nvmf_subsystem_listener) link; }; @@ -278,6 +279,8 @@ struct spdk_nvmf_ctrlr { TAILQ_ENTRY(spdk_nvmf_ctrlr) link; }; +#define NVMF_MAX_LISTENERS_PER_SUBSYSTEM 16 + struct spdk_nvmf_subsystem { struct spdk_thread *thread; @@ -319,6 +322,7 @@ struct spdk_nvmf_subsystem { pthread_mutex_t mutex; TAILQ_HEAD(, spdk_nvmf_host) hosts; TAILQ_HEAD(, spdk_nvmf_subsystem_listener) listeners; + struct spdk_bit_array *used_listener_ids; TAILQ_ENTRY(spdk_nvmf_subsystem) entries; diff --git a/lib/nvmf/subsystem.c b/lib/nvmf/subsystem.c index 3945fdf21..e441699c1 100644 --- a/lib/nvmf/subsystem.c +++ b/lib/nvmf/subsystem.c @@ -45,6 +45,7 @@ #include "spdk/uuid.h" #include "spdk/json.h" #include "spdk/file.h" +#include "spdk/bit_array.h" #define __SPDK_BDEV_MODULE_ONLY #include "spdk/bdev_module.h" @@ -297,12 +298,19 @@ spdk_nvmf_subsystem_create(struct spdk_nvmf_tgt *tgt, TAILQ_INIT(&subsystem->listeners); TAILQ_INIT(&subsystem->hosts); TAILQ_INIT(&subsystem->ctrlrs); + subsystem->used_listener_ids = spdk_bit_array_create(NVMF_MAX_LISTENERS_PER_SUBSYSTEM); + if (subsystem->used_listener_ids == NULL) { + pthread_mutex_destroy(&subsystem->mutex); + free(subsystem); + return NULL; + } if (num_ns != 0) { subsystem->ns = calloc(num_ns, sizeof(struct spdk_nvmf_ns *)); if (subsystem->ns == NULL) { SPDK_ERRLOG("Namespace memory allocation failed\n"); pthread_mutex_destroy(&subsystem->mutex); + spdk_bit_array_free(&subsystem->used_listener_ids); free(subsystem); return NULL; } @@ -311,6 +319,7 @@ spdk_nvmf_subsystem_create(struct spdk_nvmf_tgt *tgt, SPDK_ERRLOG("ANA group memory allocation failed\n"); pthread_mutex_destroy(&subsystem->mutex); free(subsystem->ns); + spdk_bit_array_free(&subsystem->used_listener_ids); free(subsystem); return NULL; } @@ -359,6 +368,7 @@ _nvmf_subsystem_remove_listener(struct spdk_nvmf_subsystem *subsystem, TAILQ_REMOVE(&subsystem->listeners, listener, link); nvmf_update_discovery_log(listener->subsystem->tgt, NULL); free(listener->ana_state); + spdk_bit_array_clear(subsystem->used_listener_ids, listener->id); free(listener); } @@ -405,6 +415,8 @@ _nvmf_subsystem_destroy(struct spdk_nvmf_subsystem *subsystem) pthread_mutex_destroy(&subsystem->mutex); + spdk_bit_array_free(&subsystem->used_listener_ids); + if (subsystem->async_destroy) { async_destroy_cb = subsystem->async_destroy_cb; async_destroy_cb_arg = subsystem->async_destroy_cb_arg; @@ -1068,6 +1080,7 @@ spdk_nvmf_subsystem_add_listener(struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_subsystem_listener *listener; struct spdk_nvmf_listener *tr_listener; uint32_t i; + uint32_t id; int rc = 0; assert(cb_fn != NULL); @@ -1117,6 +1130,18 @@ spdk_nvmf_subsystem_add_listener(struct spdk_nvmf_subsystem *subsystem, return; } + id = spdk_bit_array_find_first_clear(subsystem->used_listener_ids, 0); + if (id == UINT32_MAX) { + SPDK_ERRLOG("Cannot add any more listeners\n"); + free(listener->ana_state); + free(listener); + cb_fn(cb_arg, -EINVAL); + return; + } + + spdk_bit_array_set(subsystem->used_listener_ids, id); + listener->id = id; + for (i = 0; i < subsystem->max_nsid; i++) { listener->ana_state[i] = SPDK_NVME_ANA_OPTIMIZED_STATE; }