Commit 793c7cfc authored by Christoph Hellwig's avatar Christoph Hellwig

nvmet: track and limit the number of namespaces per subsystem

TP 4004 introduces a new 'Maximum Number of Allocated Namespaces' field
in the Identify controller data to help the host size resources.  Put
an upper limit on the supported namespaces to be able to support this
value as supporting 32-bits worth of namespaces would lead to very
large buffers.  The limit is completely arbitrary at this point.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarKeith Busch <keith.busch@intel.com>
Reviewed-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Reviewed-by: default avatarJohannes Thumshirn <jthumshirn@suse.de>
parent 4ee43280
...@@ -252,6 +252,7 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req) ...@@ -252,6 +252,7 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
id->maxcmd = cpu_to_le16(NVMET_MAX_CMD); id->maxcmd = cpu_to_le16(NVMET_MAX_CMD);
id->nn = cpu_to_le32(ctrl->subsys->max_nsid); id->nn = cpu_to_le32(ctrl->subsys->max_nsid);
id->mnan = cpu_to_le32(NVMET_MAX_NAMESPACES);
id->oncs = cpu_to_le16(NVME_CTRL_ONCS_DSM | id->oncs = cpu_to_le16(NVME_CTRL_ONCS_DSM |
NVME_CTRL_ONCS_WRITE_ZEROES); NVME_CTRL_ONCS_WRITE_ZEROES);
......
...@@ -337,9 +337,13 @@ static void nvmet_ns_dev_disable(struct nvmet_ns *ns) ...@@ -337,9 +337,13 @@ static void nvmet_ns_dev_disable(struct nvmet_ns *ns)
int nvmet_ns_enable(struct nvmet_ns *ns) int nvmet_ns_enable(struct nvmet_ns *ns)
{ {
struct nvmet_subsys *subsys = ns->subsys; struct nvmet_subsys *subsys = ns->subsys;
int ret = 0; int ret;
mutex_lock(&subsys->lock); mutex_lock(&subsys->lock);
ret = -EMFILE;
if (subsys->nr_namespaces == NVMET_MAX_NAMESPACES)
goto out_unlock;
ret = 0;
if (ns->enabled) if (ns->enabled)
goto out_unlock; goto out_unlock;
...@@ -374,6 +378,7 @@ int nvmet_ns_enable(struct nvmet_ns *ns) ...@@ -374,6 +378,7 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
list_add_tail_rcu(&ns->dev_link, &old->dev_link); list_add_tail_rcu(&ns->dev_link, &old->dev_link);
} }
subsys->nr_namespaces++;
nvmet_ns_changed(subsys, ns->nsid); nvmet_ns_changed(subsys, ns->nsid);
ns->enabled = true; ns->enabled = true;
...@@ -414,6 +419,7 @@ void nvmet_ns_disable(struct nvmet_ns *ns) ...@@ -414,6 +419,7 @@ void nvmet_ns_disable(struct nvmet_ns *ns)
percpu_ref_exit(&ns->ref); percpu_ref_exit(&ns->ref);
mutex_lock(&subsys->lock); mutex_lock(&subsys->lock);
subsys->nr_namespaces--;
nvmet_ns_changed(subsys, ns->nsid); nvmet_ns_changed(subsys, ns->nsid);
nvmet_ns_dev_disable(ns); nvmet_ns_dev_disable(ns);
out_unlock: out_unlock:
......
...@@ -170,6 +170,7 @@ struct nvmet_subsys { ...@@ -170,6 +170,7 @@ struct nvmet_subsys {
struct kref ref; struct kref ref;
struct list_head namespaces; struct list_head namespaces;
unsigned int nr_namespaces;
unsigned int max_nsid; unsigned int max_nsid;
struct list_head ctrls; struct list_head ctrls;
...@@ -362,6 +363,13 @@ u32 nvmet_get_log_page_len(struct nvme_command *cmd); ...@@ -362,6 +363,13 @@ u32 nvmet_get_log_page_len(struct nvme_command *cmd);
#define NVMET_QUEUE_SIZE 1024 #define NVMET_QUEUE_SIZE 1024
#define NVMET_NR_QUEUES 128 #define NVMET_NR_QUEUES 128
#define NVMET_MAX_CMD NVMET_QUEUE_SIZE #define NVMET_MAX_CMD NVMET_QUEUE_SIZE
/*
* Nice round number that makes a list of nsids fit into a page.
* Should become tunable at some point in the future.
*/
#define NVMET_MAX_NAMESPACES 1024
#define NVMET_KAS 10 #define NVMET_KAS 10
#define NVMET_DISC_KATO 120 #define NVMET_DISC_KATO 120
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment