[PATCH] NVMe: Allow reserved minors
Keith Busch
keith.busch at intel.com
Tue Jul 14 10:57:32 PDT 2015
The patch is to aid users transitioning from SCSI to NVM-Express. Some
storage applications inherited from scsi have fixed minor requirements
for partitions, so this patch allows a user to specify a number of
minors they want reserved per namespace, defaulting to 0 to match
existing functionality; set to 16 to match scsi.
Reported-by: Dammi Wickramanayake <dammi_wickramanayake at symantec.com>
Signed-off-by: Keith Busch <keith.busch at intel.com>
Cc: Matthew Wilcox <willy at linux.intel.com>
---
drivers/block/nvme-core.c | 42 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 41 insertions(+), 1 deletion(-)
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index 7920c27..e9127ad 100644
--- a/drivers/block/nvme-core.c
+++ b/drivers/block/nvme-core.c
@@ -66,6 +66,10 @@ MODULE_PARM_DESC(shutdown_timeout, "timeout in seconds for controller shutdown")
static int nvme_major;
module_param(nvme_major, int, 0);
+static unsigned char nvme_minors = 0;
+module_param_named(minors, nvme_minors, byte, 0444);
+MODULE_PARM_DESC(minors, "number of minors per nvme namespace");
+
static int nvme_char_major;
module_param(nvme_char_major, int, 0);
@@ -2052,6 +2056,33 @@ static int nvme_kthread(void *data)
return 0;
}
+static DEFINE_IDA(nvme_index_ida);
+
+static int nvme_get_ns_idx(void)
+{
+ int index, error;
+
+ do {
+ if (!ida_pre_get(&nvme_index_ida, GFP_KERNEL))
+ return -1;
+
+ spin_lock(&dev_list_lock);
+ error = ida_get_new(&nvme_index_ida, &index);
+ spin_unlock(&dev_list_lock);
+ } while (error == -EAGAIN);
+
+ if (error)
+ index = -1;
+ return index;
+}
+
+static void nvme_put_ns_idx(int index)
+{
+ spin_lock(&dev_list_lock);
+ ida_remove(&nvme_index_ida, index);
+ spin_unlock(&dev_list_lock);
+}
+
static void nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid)
{
struct nvme_ns *ns;
@@ -2089,7 +2120,13 @@ static void nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid)
blk_queue_flush(ns->queue, REQ_FLUSH | REQ_FUA);
disk->major = nvme_major;
- disk->first_minor = 0;
+ disk->minors = nvme_minors;
+
+ if (nvme_minors)
+ disk->first_minor = nvme_minors * nvme_get_ns_idx();
+ else
+ disk->first_minor = 0;
+
disk->fops = &nvme_fops;
disk->private_data = ns;
disk->queue = ns->queue;
@@ -2249,7 +2286,10 @@ static void nvme_free_namespace(struct nvme_ns *ns)
ns->disk->private_data = NULL;
spin_unlock(&dev_list_lock);
+ if (nvme_minors)
+ nvme_put_ns_idx(ns->disk->first_minor / nvme_minors);
put_disk(ns->disk);
+
kfree(ns);
}
--
1.7.10.4
More information about the Linux-nvme
mailing list