mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 22:20:50 +07:00
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
if (dev->mt)
|
||||
dev->mt->unregister_mgr(dev);
|
||||
nvm_free_mgr(dev);
|
||||
|
||||
kfree(dev->lptbl);
|
||||
kfree(dev->lun_map);
|
||||
@ -808,6 +847,7 @@ static int nvm_create_target(struct nvm_dev *dev,
|
||||
|
||||
t->type = tt;
|
||||
t->disk = tdisk;
|
||||
t->dev = dev;
|
||||
|
||||
down_write(&nvm_lock);
|
||||
list_add_tail(&t->list, &nvm_targets);
|
||||
@ -823,26 +863,6 @@ static int nvm_create_target(struct nvm_dev *dev,
|
||||
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)
|
||||
{
|
||||
struct nvm_dev *dev;
|
||||
@ -1231,10 +1251,7 @@ static long nvm_ioctl_dev_factory(struct file *file, void __user *arg)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (dev->mt) {
|
||||
dev->mt->unregister_mgr(dev);
|
||||
dev->mt = NULL;
|
||||
}
|
||||
nvm_free_mgr(dev);
|
||||
|
||||
if (dev->identity.cap & NVM_ID_DCAP_BBLKMGMT)
|
||||
return nvm_dev_factory(dev, fact.flags);
|
||||
|
@ -200,6 +200,7 @@ struct nvm_id {
|
||||
|
||||
struct nvm_target {
|
||||
struct list_head list;
|
||||
struct nvm_dev *dev;
|
||||
struct nvm_tgt_type *type;
|
||||
struct gendisk *disk;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user