lightnvm: refactor dev->online_target to global nvm_targets
authorSimon A. F. Lund <slund@cnexlabs.com>
Fri, 6 May 2016 18:03:03 +0000 (20:03 +0200)
committerJens Axboe <axboe@fb.com>
Fri, 6 May 2016 18:51:10 +0000 (12:51 -0600)
A target name must be unique. However, a per-device registration of
targets is maintained on a dev->online_targets list, with a per-device
search for targets upon registration.

This results in a name collision when two targets, with the same name,
are created on two different targets, where the per-device list is not
shared.

Signed-off-by: Simon A. F. Lund <slund@cnexlabs.com>
Signed-off-by: Matias Bjørling <m@bjorling.me>
Signed-off-by: Jens Axboe <axboe@fb.com>
drivers/lightnvm/core.c
include/linux/lightnvm.h

index 240b473..0296223 100644 (file)
 static LIST_HEAD(nvm_tgt_types);
 static LIST_HEAD(nvm_mgrs);
 static LIST_HEAD(nvm_devices);
+static LIST_HEAD(nvm_targets);
 static DECLARE_RWSEM(nvm_lock);
 
+static struct nvm_target *nvm_find_target(const char *name)
+{
+       struct nvm_target *tgt;
+
+       list_for_each_entry(tgt, &nvm_targets, list)
+               if (!strcmp(name, tgt->disk->disk_name))
+                       return tgt;
+
+       return NULL;
+}
+
 static struct nvm_tgt_type *nvm_find_target_type(const char *name)
 {
        struct nvm_tgt_type *tt;
@@ -564,7 +576,6 @@ static int nvm_core_init(struct nvm_dev *dev)
                goto err_fmtype;
        }
 
-       INIT_LIST_HEAD(&dev->online_targets);
        mutex_init(&dev->mlock);
        spin_lock_init(&dev->lock);
 
@@ -744,12 +755,11 @@ static int nvm_create_target(struct nvm_dev *dev,
                return -EINVAL;
        }
 
-       list_for_each_entry(t, &dev->online_targets, list) {
-               if (!strcmp(create->tgtname, t->disk->disk_name)) {
-                       pr_err("nvm: target name already exists.\n");
-                       up_write(&nvm_lock);
-                       return -EINVAL;
-               }
+       t = nvm_find_target(create->tgtname);
+       if (t) {
+               pr_err("nvm: target name already exists.\n");
+               up_write(&nvm_lock);
+               return -EINVAL;
        }
        up_write(&nvm_lock);
 
@@ -789,7 +799,7 @@ static int nvm_create_target(struct nvm_dev *dev,
        t->disk = tdisk;
 
        down_write(&nvm_lock);
-       list_add_tail(&t->list, &dev->online_targets);
+       list_add_tail(&t->list, &nvm_targets);
        up_write(&nvm_lock);
 
        return 0;
@@ -852,26 +862,19 @@ static int __nvm_configure_create(struct nvm_ioctl_create *create)
 
 static int __nvm_configure_remove(struct nvm_ioctl_remove *remove)
 {
-       struct nvm_target *t = NULL;
-       struct nvm_dev *dev;
-       int ret = -1;
+       struct nvm_target *t;
 
        down_write(&nvm_lock);
-       list_for_each_entry(dev, &nvm_devices, devices)
-               list_for_each_entry(t, &dev->online_targets, list) {
-                       if (!strcmp(remove->tgtname, t->disk->disk_name)) {
-                               nvm_remove_target(t);
-                               ret = 0;
-                               break;
-                       }
-               }
-       up_write(&nvm_lock);
-
-       if (ret) {
+       t = nvm_find_target(remove->tgtname);
+       if (!t) {
                pr_err("nvm: target \"%s\" doesn't exist.\n", remove->tgtname);
+               up_write(&nvm_lock);
                return -EINVAL;
        }
 
+       nvm_remove_target(t);
+       up_write(&nvm_lock);
+
        return 0;
 }
 
index 497da91..5eabdba 100644 (file)
@@ -308,7 +308,6 @@ struct nvm_dev {
        struct nvm_dev_ops *ops;
 
        struct list_head devices;
-       struct list_head online_targets;
 
        /* Media manager */
        struct nvmm_type *mt;