nvmf: Update poll group channel maps when a new namespace is added.

There isn't a way to remove a namespace just yet, but at least
adding one works.

Change-Id: I99416d1bc9cbc0e2303c16040d2311a07829cbea
Signed-off-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.gerrithub.io/388293
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Ben Walker 2017-11-20 10:45:39 -07:00 committed by Jim Harris
parent 48aced6ebc
commit c3080c5aa6
5 changed files with 116 additions and 2 deletions

View File

@ -416,11 +416,18 @@ spdk_nvmf_poll_group_add_subsystem(struct spdk_nvmf_poll_group *group,
if (subsystem->id >= group->num_sgroups) {
void *buf;
group->num_sgroups = subsystem->id + 1;
buf = realloc(group->sgroups, group->num_sgroups * sizeof(*sgroup));
buf = realloc(group->sgroups, (subsystem->id + 1) * sizeof(*sgroup));
if (!buf) {
return -ENOMEM;
}
/* Zero out the newly allocated memory */
memset(&group->sgroups[group->num_sgroups],
0,
(subsystem->id + 1 - group->num_sgroups) * sizeof(struct spdk_io_channel *));
group->num_sgroups = subsystem->id + 1;
group->sgroups = buf;
}
@ -468,6 +475,50 @@ spdk_nvmf_poll_group_remove_subsystem(struct spdk_nvmf_poll_group *group,
return 0;
}
int
spdk_nvmf_poll_group_add_ns(struct spdk_nvmf_poll_group *group,
struct spdk_nvmf_subsystem *subsystem,
struct spdk_nvmf_ns *ns)
{
struct spdk_nvmf_subsystem_poll_group *sgroup;
uint32_t ns_idx;
sgroup = &group->sgroups[subsystem->id];
/* The index into the channels array is (nsid - 1) */
ns_idx = ns->id - 1;
if (ns_idx >= sgroup->num_channels) {
void *buf;
buf = realloc(sgroup->channels,
ns->id * sizeof(struct spdk_io_channel *));
if (!buf) {
return -ENOMEM;
}
/* Zero out the newly allocated memory */
memset(&sgroup->channels[sgroup->num_channels],
0,
(ns->id - sgroup->num_channels) * sizeof(struct spdk_io_channel *));
sgroup->num_channels = ns->id;
sgroup->channels = buf;
}
/* The channel could have been created in response to a subsystem creation
* event already propagating through the system */
if (sgroup->channels[ns_idx] == NULL) {
sgroup->channels[ns_idx] = spdk_bdev_get_io_channel(ns->desc);
}
if (sgroup->channels[ns_idx] == NULL) {
return -1;
}
return 0;
}
SPDK_TRACE_REGISTER_FN(nvmf_trace)
{
spdk_trace_register_object(OBJECT_NVMF_IO, 'r');

View File

@ -223,6 +223,9 @@ int spdk_nvmf_poll_group_add_subsystem(struct spdk_nvmf_poll_group *group,
struct spdk_nvmf_subsystem *subsystem);
int spdk_nvmf_poll_group_remove_subsystem(struct spdk_nvmf_poll_group *group,
struct spdk_nvmf_subsystem *subsystem);
int spdk_nvmf_poll_group_add_ns(struct spdk_nvmf_poll_group *group,
struct spdk_nvmf_subsystem *subsystem,
struct spdk_nvmf_ns *ns);
void spdk_nvmf_request_exec(struct spdk_nvmf_request *req);
int spdk_nvmf_request_complete(struct spdk_nvmf_request *req);

View File

@ -393,11 +393,36 @@ spdk_nvmf_listener_get_trid(struct spdk_nvmf_listener *listener)
return &listener->trid;
}
struct spdk_nvmf_subsystem_add_ns_ctx {
struct spdk_nvmf_subsystem *subsystem;
struct spdk_nvmf_ns *ns;
};
static void
spdk_nvmf_subsystem_add_ns_done(void *io_device, void *ctx, int status)
{
free(ctx);
}
static int
spdk_nvmf_subsystem_ns_update_poll_group(void *io_device,
struct spdk_io_channel *ch,
void *c)
{
struct spdk_nvmf_poll_group *group;
struct spdk_nvmf_subsystem_add_ns_ctx *ctx = c;
group = spdk_io_channel_get_ctx(ch);
return spdk_nvmf_poll_group_add_ns(group, ctx->subsystem, ctx->ns);
}
uint32_t
spdk_nvmf_subsystem_add_ns(struct spdk_nvmf_subsystem *subsystem, struct spdk_bdev *bdev,
uint32_t nsid)
{
struct spdk_nvmf_ns *ns;
struct spdk_nvmf_subsystem_add_ns_ctx *ctx;
uint32_t i;
int rc;
@ -473,6 +498,25 @@ spdk_nvmf_subsystem_add_ns(struct spdk_nvmf_subsystem *subsystem, struct spdk_bd
subsystem->max_nsid = spdk_max(subsystem->max_nsid, nsid);
subsystem->num_allocated_nsid++;
ctx = calloc(1, sizeof(*ctx));
if (!ctx) {
return -ENOMEM;
}
ctx->subsystem = subsystem;
ctx->ns = ns;
/* Send a message to each poll group to notify it that a new namespace
* is available.
* TODO: This call does not currently allow the user to wait for these
* messages to propagate. It also does not protect against two calls
* to this function overlapping
*/
spdk_for_each_channel(subsystem->tgt,
spdk_nvmf_subsystem_ns_update_poll_group,
ctx,
spdk_nvmf_subsystem_add_ns_done);
return nsid;
}

View File

@ -136,6 +136,14 @@ spdk_nvmf_poll_group_remove_subsystem(struct spdk_nvmf_poll_group *group,
return 0;
}
int
spdk_nvmf_poll_group_add_ns(struct spdk_nvmf_poll_group *group,
struct spdk_nvmf_subsystem *subsystem,
struct spdk_nvmf_ns *ns)
{
return 0;
}
int
spdk_nvmf_subsystem_bdev_attach(struct spdk_nvmf_subsystem *subsystem)
{

View File

@ -109,6 +109,14 @@ spdk_nvmf_poll_group_remove_subsystem(struct spdk_nvmf_poll_group *group,
return 0;
}
int
spdk_nvmf_poll_group_add_ns(struct spdk_nvmf_poll_group *group,
struct spdk_nvmf_subsystem *subsystem,
struct spdk_nvmf_ns *ns)
{
return 0;
}
int
spdk_nvme_transport_id_parse_trtype(enum spdk_nvme_transport_type *trtype, const char *str)
{