diff --git a/lib/nvmf/ctrlr_discovery.c b/lib/nvmf/ctrlr_discovery.c index 30f9fba11..9021e5465 100644 --- a/lib/nvmf/ctrlr_discovery.c +++ b/lib/nvmf/ctrlr_discovery.c @@ -56,6 +56,7 @@ nvmf_update_discovery_log(struct spdk_nvmf_tgt *tgt) struct spdk_nvmf_discovery_log_page_entry *entry; struct spdk_nvmf_discovery_log_page *disc_log; size_t cur_size; + uint32_t sid; SPDK_DEBUGLOG(SPDK_TRACE_NVMF, "Generating log page for genctr %" PRIu64 "\n", tgt->discovery_genctr); @@ -67,7 +68,12 @@ nvmf_update_discovery_log(struct spdk_nvmf_tgt *tgt) return; } - TAILQ_FOREACH(subsystem, &tgt->subsystems, entries) { + for (sid = 0; sid < tgt->max_sid; sid++) { + subsystem = tgt->subsystems[sid]; + if (subsystem == NULL) { + continue; + } + if (subsystem->subtype == SPDK_NVMF_SUBTYPE_DISCOVERY) { continue; } diff --git a/lib/nvmf/nvmf.c b/lib/nvmf/nvmf.c index 8454a0481..aa5b6fc20 100644 --- a/lib/nvmf/nvmf.c +++ b/lib/nvmf/nvmf.c @@ -87,7 +87,8 @@ spdk_nvmf_tgt_create(struct spdk_nvmf_tgt_opts *opts) tgt->discovery_genctr = 0; tgt->discovery_log_page = NULL; tgt->discovery_log_page_size = 0; - TAILQ_INIT(&tgt->subsystems); + tgt->subsystems = NULL; + tgt->max_sid = 0; TAILQ_INIT(&tgt->transports); SPDK_DEBUGLOG(SPDK_TRACE_NVMF, "Max Queue Pairs Per Controller: %d\n", @@ -113,6 +114,11 @@ spdk_nvmf_tgt_destroy(struct spdk_nvmf_tgt *tgt) if (tgt->discovery_log_page) { free(tgt->discovery_log_page); } + + if (tgt->subsystems) { + free(tgt->subsystems); + } + free(tgt); } @@ -149,12 +155,18 @@ struct spdk_nvmf_subsystem * spdk_nvmf_tgt_find_subsystem(struct spdk_nvmf_tgt *tgt, const char *subnqn) { struct spdk_nvmf_subsystem *subsystem; + uint32_t sid; if (!subnqn) { return NULL; } - TAILQ_FOREACH(subsystem, &tgt->subsystems, entries) { + for (sid = 0; sid < tgt->max_sid; sid++) { + subsystem = tgt->subsystems[sid]; + if (subsystem == NULL) { + continue; + } + if (strcmp(subnqn, subsystem->subnqn) == 0) { return subsystem; } diff --git a/lib/nvmf/nvmf_internal.h b/lib/nvmf/nvmf_internal.h index 219a7ea57..ec399ad19 100644 --- a/lib/nvmf/nvmf_internal.h +++ b/lib/nvmf/nvmf_internal.h @@ -51,7 +51,11 @@ struct spdk_nvmf_tgt { struct spdk_thread *master_thread; uint64_t discovery_genctr; - TAILQ_HEAD(, spdk_nvmf_subsystem) subsystems; + + /* Array of subsystem pointers of size max_sid indexed by sid */ + struct spdk_nvmf_subsystem **subsystems; + uint32_t max_sid; + struct spdk_nvmf_discovery_log_page *discovery_log_page; size_t discovery_log_page_size; TAILQ_HEAD(, spdk_nvmf_transport) transports; @@ -171,6 +175,7 @@ struct spdk_nvmf_ctrlr { }; struct spdk_nvmf_subsystem { + uint32_t id; char subnqn[SPDK_NVMF_NQN_MAX_LEN + 1]; enum spdk_nvmf_subtype subtype; uint16_t next_cntlid; diff --git a/lib/nvmf/subsystem.c b/lib/nvmf/subsystem.c index e68a6fa93..14a2bb0c5 100644 --- a/lib/nvmf/subsystem.c +++ b/lib/nvmf/subsystem.c @@ -94,6 +94,7 @@ spdk_nvmf_create_subsystem(struct spdk_nvmf_tgt *tgt, uint32_t num_ns) { struct spdk_nvmf_subsystem *subsystem; + uint32_t sid; if (!spdk_nvmf_valid_nqn(nqn)) { return NULL; @@ -104,12 +105,31 @@ spdk_nvmf_create_subsystem(struct spdk_nvmf_tgt *tgt, return NULL; } + /* Find a free subsystem id (sid) */ + for (sid = 0; sid < tgt->max_sid; sid++) { + if (tgt->subsystems[sid] == NULL) { + break; + } + } + if (sid == tgt->max_sid) { + struct spdk_nvmf_subsystem **subsys_array; + /* No free slots. Add more. */ + tgt->max_sid++; + subsys_array = realloc(tgt->subsystems, tgt->max_sid * sizeof(struct spdk_nvmf_subsystem *)); + if (!subsys_array) { + tgt->max_sid--; + return NULL; + } + tgt->subsystems = subsys_array; + } + subsystem = calloc(1, sizeof(struct spdk_nvmf_subsystem)); if (subsystem == NULL) { return NULL; } subsystem->tgt = tgt; + subsystem->id = sid; subsystem->subtype = type; subsystem->max_nsid = num_ns; subsystem->num_allocated_nsid = 0; @@ -128,7 +148,7 @@ spdk_nvmf_create_subsystem(struct spdk_nvmf_tgt *tgt, } } - TAILQ_INSERT_TAIL(&tgt->subsystems, subsystem, entries); + tgt->subsystems[sid] = subsystem; tgt->discovery_genctr++; return subsystem; @@ -166,7 +186,7 @@ spdk_nvmf_delete_subsystem(struct spdk_nvmf_subsystem *subsystem) free(subsystem->ns); - TAILQ_REMOVE(&subsystem->tgt->subsystems, subsystem, entries); + subsystem->tgt->subsystems[subsystem->id] = NULL; subsystem->tgt->discovery_genctr++; free(subsystem); diff --git a/test/unit/lib/nvmf/ctrlr_discovery.c/ctrlr_discovery_ut.c b/test/unit/lib/nvmf/ctrlr_discovery.c/ctrlr_discovery_ut.c index 0b2d52fa3..d277d5a77 100644 --- a/test/unit/lib/nvmf/ctrlr_discovery.c/ctrlr_discovery_ut.c +++ b/test/unit/lib/nvmf/ctrlr_discovery.c/ctrlr_discovery_ut.c @@ -164,8 +164,6 @@ test_discovery_log(void) struct spdk_nvmf_discovery_log_page_entry *entry; struct spdk_nvme_transport_id trid = {}; - TAILQ_INIT(&tgt.subsystems); - /* Add one subsystem and verify that the discovery log contains it */ subsystem = spdk_nvmf_create_subsystem(&tgt, "nqn.2016-06.io.spdk:subsystem1", SPDK_NVMF_SUBTYPE_NVME, 0); @@ -217,6 +215,7 @@ test_discovery_log(void) sizeof(*entry)); CU_ASSERT(entry->trtype == 42); spdk_nvmf_delete_subsystem(subsystem); + free(tgt.subsystems); free(tgt.discovery_log_page); } diff --git a/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c b/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c index 1148e28de..2d8dc5dfb 100644 --- a/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c +++ b/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c @@ -203,7 +203,6 @@ nvmf_test_create_subsystem(void) struct spdk_nvmf_tgt tgt = {}; char nqn[256]; struct spdk_nvmf_subsystem *subsystem; - TAILQ_INIT(&tgt.subsystems); strncpy(nqn, "nqn.2016-06.io.spdk:subsystem1", sizeof(nqn)); subsystem = spdk_nvmf_create_subsystem(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); @@ -228,6 +227,8 @@ nvmf_test_create_subsystem(void) CU_ASSERT(strlen(nqn) == 224); subsystem = spdk_nvmf_create_subsystem(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); CU_ASSERT(subsystem == NULL); + + free(tgt.subsystems); } int main(int argc, char **argv)