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>
This commit is contained in:
parent
45bbd0529e
commit
976bdfcae3
|
@ -596,13 +596,52 @@ static int nvm_core_init(struct nvm_dev *dev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void nvm_remove_target(struct nvm_target *t)
|
||||||
|
{
|
||||||
|
struct nvm_tgt_type *tt = t->type;
|
||||||
|
struct gendisk *tdisk = t->disk;
|
||||||
|
struct request_queue *q = tdisk->queue;
|
||||||
|
|
||||||
|
lockdep_assert_held(&nvm_lock);
|
||||||
|
|
||||||
|
del_gendisk(tdisk);
|
||||||
|
blk_cleanup_queue(q);
|
||||||
|
|
||||||
|
if (tt->exit)
|
||||||
|
tt->exit(tdisk->private_data);
|
||||||
|
|
||||||
|
put_disk(tdisk);
|
||||||
|
|
||||||
|
list_del(&t->list);
|
||||||
|
kfree(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nvm_free_mgr(struct nvm_dev *dev)
|
||||||
|
{
|
||||||
|
struct nvm_target *tgt, *tmp;
|
||||||
|
|
||||||
|
if (!dev->mt)
|
||||||
|
return;
|
||||||
|
|
||||||
|
down_write(&nvm_lock);
|
||||||
|
list_for_each_entry_safe(tgt, tmp, &nvm_targets, list) {
|
||||||
|
if (tgt->dev != dev)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
nvm_remove_target(tgt);
|
||||||
|
}
|
||||||
|
up_write(&nvm_lock);
|
||||||
|
|
||||||
|
dev->mt->unregister_mgr(dev);
|
||||||
|
dev->mt = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void nvm_free(struct nvm_dev *dev)
|
static void nvm_free(struct nvm_dev *dev)
|
||||||
{
|
{
|
||||||
if (!dev)
|
if (!dev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (dev->mt)
|
nvm_free_mgr(dev);
|
||||||
dev->mt->unregister_mgr(dev);
|
|
||||||
|
|
||||||
kfree(dev->lptbl);
|
kfree(dev->lptbl);
|
||||||
kfree(dev->lun_map);
|
kfree(dev->lun_map);
|
||||||
|
@ -808,6 +847,7 @@ static int nvm_create_target(struct nvm_dev *dev,
|
||||||
|
|
||||||
t->type = tt;
|
t->type = tt;
|
||||||
t->disk = tdisk;
|
t->disk = tdisk;
|
||||||
|
t->dev = dev;
|
||||||
|
|
||||||
down_write(&nvm_lock);
|
down_write(&nvm_lock);
|
||||||
list_add_tail(&t->list, &nvm_targets);
|
list_add_tail(&t->list, &nvm_targets);
|
||||||
|
@ -823,26 +863,6 @@ static int nvm_create_target(struct nvm_dev *dev,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nvm_remove_target(struct nvm_target *t)
|
|
||||||
{
|
|
||||||
struct nvm_tgt_type *tt = t->type;
|
|
||||||
struct gendisk *tdisk = t->disk;
|
|
||||||
struct request_queue *q = tdisk->queue;
|
|
||||||
|
|
||||||
lockdep_assert_held(&nvm_lock);
|
|
||||||
|
|
||||||
del_gendisk(tdisk);
|
|
||||||
blk_cleanup_queue(q);
|
|
||||||
|
|
||||||
if (tt->exit)
|
|
||||||
tt->exit(tdisk->private_data);
|
|
||||||
|
|
||||||
put_disk(tdisk);
|
|
||||||
|
|
||||||
list_del(&t->list);
|
|
||||||
kfree(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __nvm_configure_create(struct nvm_ioctl_create *create)
|
static int __nvm_configure_create(struct nvm_ioctl_create *create)
|
||||||
{
|
{
|
||||||
struct nvm_dev *dev;
|
struct nvm_dev *dev;
|
||||||
|
@ -1231,10 +1251,7 @@ static long nvm_ioctl_dev_factory(struct file *file, void __user *arg)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->mt) {
|
nvm_free_mgr(dev);
|
||||||
dev->mt->unregister_mgr(dev);
|
|
||||||
dev->mt = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->identity.cap & NVM_ID_DCAP_BBLKMGMT)
|
if (dev->identity.cap & NVM_ID_DCAP_BBLKMGMT)
|
||||||
return nvm_dev_factory(dev, fact.flags);
|
return nvm_dev_factory(dev, fact.flags);
|
||||||
|
|
|
@ -200,6 +200,7 @@ struct nvm_id {
|
||||||
|
|
||||||
struct nvm_target {
|
struct nvm_target {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
struct nvm_dev *dev;
|
||||||
struct nvm_tgt_type *type;
|
struct nvm_tgt_type *type;
|
||||||
struct gendisk *disk;
|
struct gendisk *disk;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue