nvmf: dynamically allocate ns array
This allows the user to configure an arbitrarily large number of namespaces instead of the current hard-coded limit of 16. Change-Id: I3a29b0de10eafd682b12c54e12411d1f9d41ce85 Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com> Reviewed-on: https://review.gerrithub.io/375636 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
db24ff75fe
commit
02f088bb95
@ -117,7 +117,7 @@ spdk_add_nvmf_discovery_subsystem(void)
|
|||||||
{
|
{
|
||||||
struct nvmf_tgt_subsystem *app_subsys;
|
struct nvmf_tgt_subsystem *app_subsys;
|
||||||
|
|
||||||
app_subsys = nvmf_tgt_create_subsystem(SPDK_NVMF_DISCOVERY_NQN, SPDK_NVMF_SUBTYPE_DISCOVERY,
|
app_subsys = nvmf_tgt_create_subsystem(SPDK_NVMF_DISCOVERY_NQN, SPDK_NVMF_SUBTYPE_DISCOVERY, 0,
|
||||||
g_spdk_nvmf_tgt_conf.acceptor_lcore);
|
g_spdk_nvmf_tgt_conf.acceptor_lcore);
|
||||||
if (app_subsys == NULL) {
|
if (app_subsys == NULL) {
|
||||||
SPDK_ERRLOG("Failed creating discovery nvmf library subsystem\n");
|
SPDK_ERRLOG("Failed creating discovery nvmf library subsystem\n");
|
||||||
@ -392,7 +392,7 @@ spdk_nvmf_construct_subsystem(const char *name, int32_t lcore,
|
|||||||
lcore = spdk_nvmf_allocate_lcore(mask, lcore);
|
lcore = spdk_nvmf_allocate_lcore(mask, lcore);
|
||||||
g_last_core = lcore;
|
g_last_core = lcore;
|
||||||
|
|
||||||
app_subsys = nvmf_tgt_create_subsystem(name, SPDK_NVMF_SUBTYPE_NVME, lcore);
|
app_subsys = nvmf_tgt_create_subsystem(name, SPDK_NVMF_SUBTYPE_NVME, num_devs, lcore);
|
||||||
if (app_subsys == NULL) {
|
if (app_subsys == NULL) {
|
||||||
SPDK_ERRLOG("Subsystem creation failed\n");
|
SPDK_ERRLOG("Subsystem creation failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -185,7 +185,7 @@ nvmf_tgt_start_subsystem(struct nvmf_tgt_subsystem *app_subsys)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct nvmf_tgt_subsystem *
|
struct nvmf_tgt_subsystem *
|
||||||
nvmf_tgt_create_subsystem(const char *name, enum spdk_nvmf_subtype subtype,
|
nvmf_tgt_create_subsystem(const char *name, enum spdk_nvmf_subtype subtype, uint32_t num_ns,
|
||||||
uint32_t lcore)
|
uint32_t lcore)
|
||||||
{
|
{
|
||||||
struct spdk_nvmf_subsystem *subsystem;
|
struct spdk_nvmf_subsystem *subsystem;
|
||||||
@ -202,7 +202,7 @@ nvmf_tgt_create_subsystem(const char *name, enum spdk_nvmf_subtype subtype,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
subsystem = spdk_nvmf_create_subsystem(g_tgt, name, subtype, app_subsys, connect_cb,
|
subsystem = spdk_nvmf_create_subsystem(g_tgt, name, subtype, num_ns, app_subsys, connect_cb,
|
||||||
disconnect_cb);
|
disconnect_cb);
|
||||||
if (subsystem == NULL) {
|
if (subsystem == NULL) {
|
||||||
SPDK_ERRLOG("Subsystem creation failed\n");
|
SPDK_ERRLOG("Subsystem creation failed\n");
|
||||||
|
@ -76,7 +76,7 @@ int spdk_nvmf_parse_conf(void);
|
|||||||
void nvmf_tgt_start_subsystem(struct nvmf_tgt_subsystem *subsystem);
|
void nvmf_tgt_start_subsystem(struct nvmf_tgt_subsystem *subsystem);
|
||||||
|
|
||||||
struct nvmf_tgt_subsystem *nvmf_tgt_create_subsystem(const char *name,
|
struct nvmf_tgt_subsystem *nvmf_tgt_create_subsystem(const char *name,
|
||||||
enum spdk_nvmf_subtype subtype,
|
enum spdk_nvmf_subtype subtype, uint32_t num_ns,
|
||||||
uint32_t lcore);
|
uint32_t lcore);
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -45,8 +45,6 @@
|
|||||||
#include "spdk/nvmf_spec.h"
|
#include "spdk/nvmf_spec.h"
|
||||||
#include "spdk/queue.h"
|
#include "spdk/queue.h"
|
||||||
|
|
||||||
#define MAX_VIRTUAL_NAMESPACE 16
|
|
||||||
|
|
||||||
struct spdk_nvmf_tgt;
|
struct spdk_nvmf_tgt;
|
||||||
|
|
||||||
struct spdk_nvmf_tgt_opts {
|
struct spdk_nvmf_tgt_opts {
|
||||||
@ -113,6 +111,7 @@ struct spdk_nvmf_listen_addr {
|
|||||||
struct spdk_nvmf_subsystem *spdk_nvmf_create_subsystem(struct spdk_nvmf_tgt *tgt,
|
struct spdk_nvmf_subsystem *spdk_nvmf_create_subsystem(struct spdk_nvmf_tgt *tgt,
|
||||||
const char *nqn,
|
const char *nqn,
|
||||||
enum spdk_nvmf_subtype type,
|
enum spdk_nvmf_subtype type,
|
||||||
|
uint32_t num_ns,
|
||||||
void *cb_ctx,
|
void *cb_ctx,
|
||||||
spdk_nvmf_subsystem_connect_fn connect_cb,
|
spdk_nvmf_subsystem_connect_fn connect_cb,
|
||||||
spdk_nvmf_subsystem_disconnect_fn disconnect_cb);
|
spdk_nvmf_subsystem_disconnect_fn disconnect_cb);
|
||||||
|
@ -90,8 +90,10 @@ struct spdk_nvmf_subsystem {
|
|||||||
|
|
||||||
char sn[SPDK_NVME_CTRLR_SN_LEN + 1];
|
char sn[SPDK_NVME_CTRLR_SN_LEN + 1];
|
||||||
|
|
||||||
struct spdk_nvmf_ns ns[MAX_VIRTUAL_NAMESPACE];
|
/* Array of namespaces of size max_nsid indexed by nsid - 1 */
|
||||||
|
struct spdk_nvmf_ns *ns;
|
||||||
uint32_t max_nsid;
|
uint32_t max_nsid;
|
||||||
|
uint32_t num_allocated_nsid;
|
||||||
|
|
||||||
void *cb_ctx;
|
void *cb_ctx;
|
||||||
spdk_nvmf_subsystem_connect_fn connect_cb;
|
spdk_nvmf_subsystem_connect_fn connect_cb;
|
||||||
|
@ -133,6 +133,7 @@ struct spdk_nvmf_subsystem *
|
|||||||
spdk_nvmf_create_subsystem(struct spdk_nvmf_tgt *tgt,
|
spdk_nvmf_create_subsystem(struct spdk_nvmf_tgt *tgt,
|
||||||
const char *nqn,
|
const char *nqn,
|
||||||
enum spdk_nvmf_subtype type,
|
enum spdk_nvmf_subtype type,
|
||||||
|
uint32_t num_ns,
|
||||||
void *cb_ctx,
|
void *cb_ctx,
|
||||||
spdk_nvmf_subsystem_connect_fn connect_cb,
|
spdk_nvmf_subsystem_connect_fn connect_cb,
|
||||||
spdk_nvmf_subsystem_disconnect_fn disconnect_cb)
|
spdk_nvmf_subsystem_disconnect_fn disconnect_cb)
|
||||||
@ -143,6 +144,11 @@ spdk_nvmf_create_subsystem(struct spdk_nvmf_tgt *tgt,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type == SPDK_NVMF_SUBTYPE_DISCOVERY && num_ns != 0) {
|
||||||
|
SPDK_ERRLOG("Discovery subsystem cannot have namespaces.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
subsystem = calloc(1, sizeof(struct spdk_nvmf_subsystem));
|
subsystem = calloc(1, sizeof(struct spdk_nvmf_subsystem));
|
||||||
if (subsystem == NULL) {
|
if (subsystem == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -154,6 +160,8 @@ spdk_nvmf_create_subsystem(struct spdk_nvmf_tgt *tgt,
|
|||||||
|
|
||||||
subsystem->id = tgt->current_subsystem_id;
|
subsystem->id = tgt->current_subsystem_id;
|
||||||
subsystem->subtype = type;
|
subsystem->subtype = type;
|
||||||
|
subsystem->max_nsid = num_ns;
|
||||||
|
subsystem->num_allocated_nsid = 0;
|
||||||
subsystem->cb_ctx = cb_ctx;
|
subsystem->cb_ctx = cb_ctx;
|
||||||
subsystem->connect_cb = connect_cb;
|
subsystem->connect_cb = connect_cb;
|
||||||
subsystem->disconnect_cb = disconnect_cb;
|
subsystem->disconnect_cb = disconnect_cb;
|
||||||
@ -162,6 +170,15 @@ spdk_nvmf_create_subsystem(struct spdk_nvmf_tgt *tgt,
|
|||||||
TAILQ_INIT(&subsystem->hosts);
|
TAILQ_INIT(&subsystem->hosts);
|
||||||
TAILQ_INIT(&subsystem->ctrlrs);
|
TAILQ_INIT(&subsystem->ctrlrs);
|
||||||
|
|
||||||
|
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");
|
||||||
|
free(subsystem);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(&tgt->subsystems, subsystem, entries);
|
TAILQ_INSERT_TAIL(&tgt->subsystems, subsystem, entries);
|
||||||
tgt->discovery_genctr++;
|
tgt->discovery_genctr++;
|
||||||
|
|
||||||
@ -198,6 +215,8 @@ spdk_nvmf_delete_subsystem(struct spdk_nvmf_subsystem *subsystem)
|
|||||||
|
|
||||||
spdk_nvmf_subsystem_bdev_detach(subsystem);
|
spdk_nvmf_subsystem_bdev_detach(subsystem);
|
||||||
|
|
||||||
|
free(subsystem->ns);
|
||||||
|
|
||||||
TAILQ_REMOVE(&subsystem->tgt->subsystems, subsystem, entries);
|
TAILQ_REMOVE(&subsystem->tgt->subsystems, subsystem, entries);
|
||||||
subsystem->tgt->discovery_genctr++;
|
subsystem->tgt->discovery_genctr++;
|
||||||
|
|
||||||
@ -348,9 +367,37 @@ spdk_nvmf_subsystem_add_ns(struct spdk_nvmf_subsystem *subsystem, struct spdk_bd
|
|||||||
uint32_t i;
|
uint32_t i;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (nsid > subsystem->max_nsid ||
|
||||||
|
(nsid == 0 && subsystem->num_allocated_nsid == subsystem->max_nsid)) {
|
||||||
|
struct spdk_nvmf_ns *new_ns_array;
|
||||||
|
uint32_t new_max_nsid;
|
||||||
|
|
||||||
|
if (nsid > subsystem->max_nsid) {
|
||||||
|
new_max_nsid = nsid;
|
||||||
|
} else {
|
||||||
|
new_max_nsid = subsystem->max_nsid + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TAILQ_EMPTY(&subsystem->ctrlrs)) {
|
||||||
|
SPDK_ERRLOG("Can't extend NSID range with active connections\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_ns_array = realloc(subsystem->ns, sizeof(struct spdk_nvmf_ns) * new_max_nsid);
|
||||||
|
if (new_ns_array == NULL) {
|
||||||
|
SPDK_ERRLOG("Memory allocation error while resizing namespace array.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(new_ns_array + subsystem->max_nsid, 0,
|
||||||
|
sizeof(struct spdk_nvmf_ns) * (new_max_nsid - subsystem->max_nsid));
|
||||||
|
subsystem->ns = new_ns_array;
|
||||||
|
subsystem->max_nsid = new_max_nsid;
|
||||||
|
}
|
||||||
|
|
||||||
if (nsid == 0) {
|
if (nsid == 0) {
|
||||||
/* NSID not specified - find a free index */
|
/* NSID not specified - find a free index */
|
||||||
for (i = 0; i < MAX_VIRTUAL_NAMESPACE; i++) {
|
for (i = 0; i < subsystem->max_nsid; i++) {
|
||||||
if (_spdk_nvmf_subsystem_get_ns(subsystem, i + 1) == NULL) {
|
if (_spdk_nvmf_subsystem_get_ns(subsystem, i + 1) == NULL) {
|
||||||
nsid = i + 1;
|
nsid = i + 1;
|
||||||
break;
|
break;
|
||||||
@ -362,19 +409,13 @@ spdk_nvmf_subsystem_add_ns(struct spdk_nvmf_subsystem *subsystem, struct spdk_bd
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Specific NSID requested */
|
/* Specific NSID requested */
|
||||||
i = nsid - 1;
|
|
||||||
if (i >= MAX_VIRTUAL_NAMESPACE) {
|
|
||||||
SPDK_ERRLOG("Requested NSID %" PRIu32 " out of range\n", nsid);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_spdk_nvmf_subsystem_get_ns(subsystem, nsid)) {
|
if (_spdk_nvmf_subsystem_get_ns(subsystem, nsid)) {
|
||||||
SPDK_ERRLOG("Requested NSID %" PRIu32 " already in use\n", nsid);
|
SPDK_ERRLOG("Requested NSID %" PRIu32 " already in use\n", nsid);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ns = &subsystem->ns[i];
|
ns = &subsystem->ns[nsid - 1];
|
||||||
memset(ns, 0, sizeof(*ns));
|
memset(ns, 0, sizeof(*ns));
|
||||||
ns->bdev = bdev;
|
ns->bdev = bdev;
|
||||||
ns->id = nsid;
|
ns->id = nsid;
|
||||||
@ -392,6 +433,7 @@ spdk_nvmf_subsystem_add_ns(struct spdk_nvmf_subsystem *subsystem, struct spdk_bd
|
|||||||
nsid);
|
nsid);
|
||||||
|
|
||||||
subsystem->max_nsid = spdk_max(subsystem->max_nsid, nsid);
|
subsystem->max_nsid = spdk_max(subsystem->max_nsid, nsid);
|
||||||
|
subsystem->num_allocated_nsid++;
|
||||||
return nsid;
|
return nsid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ test_discovery_log(void)
|
|||||||
|
|
||||||
/* Add one subsystem and verify that the discovery log contains it */
|
/* Add one subsystem and verify that the discovery log contains it */
|
||||||
subsystem = spdk_nvmf_create_subsystem(&g_nvmf_tgt, "nqn.2016-06.io.spdk:subsystem1",
|
subsystem = spdk_nvmf_create_subsystem(&g_nvmf_tgt, "nqn.2016-06.io.spdk:subsystem1",
|
||||||
SPDK_NVMF_SUBTYPE_NVME,
|
SPDK_NVMF_SUBTYPE_NVME, 0,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
SPDK_CU_ASSERT_FATAL(subsystem != NULL);
|
SPDK_CU_ASSERT_FATAL(subsystem != NULL);
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ test_spdk_nvmf_subsystem_add_ns(void)
|
|||||||
{
|
{
|
||||||
struct spdk_nvmf_subsystem subsystem = {
|
struct spdk_nvmf_subsystem subsystem = {
|
||||||
.max_nsid = 0,
|
.max_nsid = 0,
|
||||||
.ns = {},
|
.ns = NULL,
|
||||||
};
|
};
|
||||||
struct spdk_bdev bdev1 = {}, bdev2 = {};
|
struct spdk_bdev bdev1 = {}, bdev2 = {};
|
||||||
uint32_t nsid;
|
uint32_t nsid;
|
||||||
@ -212,6 +212,8 @@ test_spdk_nvmf_subsystem_add_ns(void)
|
|||||||
nsid = spdk_nvmf_subsystem_add_ns(&subsystem, &bdev2, 5);
|
nsid = spdk_nvmf_subsystem_add_ns(&subsystem, &bdev2, 5);
|
||||||
CU_ASSERT(nsid == 0);
|
CU_ASSERT(nsid == 0);
|
||||||
CU_ASSERT(subsystem.max_nsid == 5);
|
CU_ASSERT(subsystem.max_nsid == 5);
|
||||||
|
|
||||||
|
free(subsystem.ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -223,7 +225,7 @@ nvmf_test_create_subsystem(void)
|
|||||||
TAILQ_INIT(&tgt.subsystems);
|
TAILQ_INIT(&tgt.subsystems);
|
||||||
|
|
||||||
strncpy(nqn, "nqn.2016-06.io.spdk:subsystem1", sizeof(nqn));
|
strncpy(nqn, "nqn.2016-06.io.spdk:subsystem1", sizeof(nqn));
|
||||||
subsystem = spdk_nvmf_create_subsystem(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME,
|
subsystem = spdk_nvmf_create_subsystem(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
SPDK_CU_ASSERT_FATAL(subsystem != NULL);
|
SPDK_CU_ASSERT_FATAL(subsystem != NULL);
|
||||||
CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
|
CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
|
||||||
@ -234,7 +236,7 @@ nvmf_test_create_subsystem(void)
|
|||||||
memset(nqn + strlen(nqn), 'a', 223 - strlen(nqn));
|
memset(nqn + strlen(nqn), 'a', 223 - strlen(nqn));
|
||||||
nqn[223] = '\0';
|
nqn[223] = '\0';
|
||||||
CU_ASSERT(strlen(nqn) == 223);
|
CU_ASSERT(strlen(nqn) == 223);
|
||||||
subsystem = spdk_nvmf_create_subsystem(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME,
|
subsystem = spdk_nvmf_create_subsystem(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
SPDK_CU_ASSERT_FATAL(subsystem != NULL);
|
SPDK_CU_ASSERT_FATAL(subsystem != NULL);
|
||||||
CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
|
CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn);
|
||||||
@ -245,7 +247,7 @@ nvmf_test_create_subsystem(void)
|
|||||||
memset(nqn + strlen(nqn), 'a', 224 - strlen(nqn));
|
memset(nqn + strlen(nqn), 'a', 224 - strlen(nqn));
|
||||||
nqn[224] = '\0';
|
nqn[224] = '\0';
|
||||||
CU_ASSERT(strlen(nqn) == 224);
|
CU_ASSERT(strlen(nqn) == 224);
|
||||||
subsystem = spdk_nvmf_create_subsystem(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME,
|
subsystem = spdk_nvmf_create_subsystem(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
CU_ASSERT(subsystem == NULL);
|
CU_ASSERT(subsystem == NULL);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user