int num_ch;
 };
 
+static void nvm_free(struct kref *ref);
+
 static struct nvm_target *nvm_find_target(struct nvm_dev *dev, const char *name)
 {
        struct nvm_target *tgt;
        }
        __nvm_remove_target(t, true);
        mutex_unlock(&dev->mlock);
+       kref_put(&dev->ref, nvm_free);
 
        return 0;
 }
        return ret;
 }
 
-static void nvm_free(struct nvm_dev *dev)
+static void nvm_free(struct kref *ref)
 {
-       if (!dev)
-               return;
+       struct nvm_dev *dev = container_of(ref, struct nvm_dev, ref);
 
        if (dev->dma_pool)
                dev->ops->destroy_dma_pool(dev->dma_pool);
 
-       nvm_unregister_map(dev);
+       if (dev->rmap)
+               nvm_unregister_map(dev);
+
        kfree(dev->lun_map);
        kfree(dev);
 }
 
 struct nvm_dev *nvm_alloc_dev(int node)
 {
-       return kzalloc_node(sizeof(struct nvm_dev), GFP_KERNEL, node);
+       struct nvm_dev *dev;
+
+       dev = kzalloc_node(sizeof(struct nvm_dev), GFP_KERNEL, node);
+       if (dev)
+               kref_init(&dev->ref);
+
+       return dev;
 }
 EXPORT_SYMBOL(nvm_alloc_dev);
 
 {
        int ret, exp_pool_size;
 
-       if (!dev->q || !dev->ops)
+       if (!dev->q || !dev->ops) {
+               kref_put(&dev->ref, nvm_free);
                return -EINVAL;
+       }
 
        ret = nvm_init(dev);
-       if (ret)
+       if (ret) {
+               kref_put(&dev->ref, nvm_free);
                return ret;
+       }
 
        exp_pool_size = max_t(int, PAGE_SIZE,
                              (NVM_MAX_VLBA * (sizeof(u64) + dev->geo.sos)));
                                                  exp_pool_size);
        if (!dev->dma_pool) {
                pr_err("nvm: could not create dma pool\n");
-               nvm_free(dev);
+               kref_put(&dev->ref, nvm_free);
                return -ENOMEM;
        }
 
                if (t->dev->parent != dev)
                        continue;
                __nvm_remove_target(t, false);
+               kref_put(&dev->ref, nvm_free);
        }
        mutex_unlock(&dev->mlock);
 
        list_del(&dev->devices);
        up_write(&nvm_lock);
 
-       nvm_free(dev);
+       kref_put(&dev->ref, nvm_free);
 }
 EXPORT_SYMBOL(nvm_unregister);
 
 static int __nvm_configure_create(struct nvm_ioctl_create *create)
 {
        struct nvm_dev *dev;
+       int ret;
 
        down_write(&nvm_lock);
        dev = nvm_find_nvm_dev(create->dev);
                return -EINVAL;
        }
 
-       return nvm_create_tgt(dev, create);
+       kref_get(&dev->ref);
+       ret = nvm_create_tgt(dev, create);
+       if (ret)
+               kref_put(&dev->ref, nvm_free);
+
+       return ret;
 }
 
 static long nvm_ioctl_info(struct file *file, void __user *arg)