aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lightnvm/core.c
diff options
context:
space:
mode:
authorMatias Bjørling <m@bjorling.me>2016-05-06 14:03:17 -0400
committerJens Axboe <axboe@fb.com>2016-05-06 14:51:10 -0400
commit976bdfcae32ea10c2c8c2ecaeb0d85873f634dad (patch)
tree479ceab3d7330f9acd8d64353ed2c238311171c1 /drivers/lightnvm/core.c
parent45bbd0529e5d50aa91a4bb5fffffc5e24df3ef7e (diff)
lightnvm: remove mgt targets on mgt removal
Targets associated with a device manager are not freed on device removal. They have to be manually removed before shutdown. Make sure any outstanding targets are freed upon shutdown. Signed-off-by: Matias Bjørling <m@bjorling.me> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/lightnvm/core.c')
-rw-r--r--drivers/lightnvm/core.c69
1 files changed, 43 insertions, 26 deletions
diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
index 1873a3bc913d..d3af77102e47 100644
--- a/drivers/lightnvm/core.c
+++ b/drivers/lightnvm/core.c
@@ -596,13 +596,52 @@ err_fmtype:
596 return ret; 596 return ret;
597} 597}
598 598
599static void nvm_remove_target(struct nvm_target *t)
600{
601 struct nvm_tgt_type *tt = t->type;
602 struct gendisk *tdisk = t->disk;
603 struct request_queue *q = tdisk->queue;
604
605 lockdep_assert_held(&nvm_lock);
606
607 del_gendisk(tdisk);
608 blk_cleanup_queue(q);
609
610 if (tt->exit)
611 tt->exit(tdisk->private_data);
612
613 put_disk(tdisk);
614
615 list_del(&t->list);
616 kfree(t);
617}
618
619static void nvm_free_mgr(struct nvm_dev *dev)
620{
621 struct nvm_target *tgt, *tmp;
622
623 if (!dev->mt)
624 return;
625
626 down_write(&nvm_lock);
627 list_for_each_entry_safe(tgt, tmp, &nvm_targets, list) {
628 if (tgt->dev != dev)
629 continue;
630
631 nvm_remove_target(tgt);
632 }
633 up_write(&nvm_lock);
634
635 dev->mt->unregister_mgr(dev);
636 dev->mt = NULL;
637}
638
599static void nvm_free(struct nvm_dev *dev) 639static void nvm_free(struct nvm_dev *dev)
600{ 640{
601 if (!dev) 641 if (!dev)
602 return; 642 return;
603 643
604 if (dev->mt) 644 nvm_free_mgr(dev);
605 dev->mt->unregister_mgr(dev);
606 645
607 kfree(dev->lptbl); 646 kfree(dev->lptbl);
608 kfree(dev->lun_map); 647 kfree(dev->lun_map);
@@ -808,6 +847,7 @@ static int nvm_create_target(struct nvm_dev *dev,
808 847
809 t->type = tt; 848 t->type = tt;
810 t->disk = tdisk; 849 t->disk = tdisk;
850 t->dev = dev;
811 851
812 down_write(&nvm_lock); 852 down_write(&nvm_lock);
813 list_add_tail(&t->list, &nvm_targets); 853 list_add_tail(&t->list, &nvm_targets);
@@ -823,26 +863,6 @@ err_t:
823 return -ENOMEM; 863 return -ENOMEM;
824} 864}
825 865
826static void nvm_remove_target(struct nvm_target *t)
827{
828 struct nvm_tgt_type *tt = t->type;
829 struct gendisk *tdisk = t->disk;
830 struct request_queue *q = tdisk->queue;
831
832 lockdep_assert_held(&nvm_lock);
833
834 del_gendisk(tdisk);
835 blk_cleanup_queue(q);
836
837 if (tt->exit)
838 tt->exit(tdisk->private_data);
839
840 put_disk(tdisk);
841
842 list_del(&t->list);
843 kfree(t);
844}
845
846static int __nvm_configure_create(struct nvm_ioctl_create *create) 866static int __nvm_configure_create(struct nvm_ioctl_create *create)
847{ 867{
848 struct nvm_dev *dev; 868 struct nvm_dev *dev;
@@ -1231,10 +1251,7 @@ static long nvm_ioctl_dev_factory(struct file *file, void __user *arg)
1231 return -EINVAL; 1251 return -EINVAL;
1232 } 1252 }
1233 1253
1234 if (dev->mt) { 1254 nvm_free_mgr(dev);
1235 dev->mt->unregister_mgr(dev);
1236 dev->mt = NULL;
1237 }
1238 1255
1239 if (dev->identity.cap & NVM_ID_DCAP_BBLKMGMT) 1256 if (dev->identity.cap & NVM_ID_DCAP_BBLKMGMT)
1240 return nvm_dev_factory(dev, fact.flags); 1257 return nvm_dev_factory(dev, fact.flags);