提交 762796bc 编写于 作者: M Matias Bjørling 提交者: Jens Axboe

lightnvm: fix media mgr registration

This patch fixes two issues during media manager registration.

1. The ppa pool can be used at media manager registration. Allocate the
ppa pool before that.

2. If a media manager can't be found, this should not lead to the
device being unallocated. A media manager can be registered later, that
can manage the device. Only warn if a media manager fails
initialization.
Signed-off-by: NMatias Bjørling <m@bjorling.me>
Signed-off-by: NJens Axboe <axboe@fb.com>
上级 16f26c3a
...@@ -97,15 +97,47 @@ static struct nvmm_type *nvm_find_mgr_type(const char *name) ...@@ -97,15 +97,47 @@ static struct nvmm_type *nvm_find_mgr_type(const char *name)
return NULL; return NULL;
} }
struct nvmm_type *nvm_init_mgr(struct nvm_dev *dev)
{
struct nvmm_type *mt;
int ret;
lockdep_assert_held(&nvm_lock);
list_for_each_entry(mt, &nvm_mgrs, list) {
ret = mt->register_mgr(dev);
if (ret < 0) {
pr_err("nvm: media mgr failed to init (%d) on dev %s\n",
ret, dev->name);
return NULL; /* initialization failed */
} else if (ret > 0)
return mt;
}
return NULL;
}
int nvm_register_mgr(struct nvmm_type *mt) int nvm_register_mgr(struct nvmm_type *mt)
{ {
struct nvm_dev *dev;
int ret = 0; int ret = 0;
down_write(&nvm_lock); down_write(&nvm_lock);
if (nvm_find_mgr_type(mt->name)) if (nvm_find_mgr_type(mt->name)) {
ret = -EEXIST; ret = -EEXIST;
else goto finish;
} else {
list_add(&mt->list, &nvm_mgrs); list_add(&mt->list, &nvm_mgrs);
}
/* try to register media mgr if any device have none configured */
list_for_each_entry(dev, &nvm_devices, devices) {
if (dev->mt)
continue;
dev->mt = nvm_init_mgr(dev);
}
finish:
up_write(&nvm_lock); up_write(&nvm_lock);
return ret; return ret;
...@@ -123,26 +155,6 @@ void nvm_unregister_mgr(struct nvmm_type *mt) ...@@ -123,26 +155,6 @@ void nvm_unregister_mgr(struct nvmm_type *mt)
} }
EXPORT_SYMBOL(nvm_unregister_mgr); EXPORT_SYMBOL(nvm_unregister_mgr);
/* register with device with a supported manager */
static int register_mgr(struct nvm_dev *dev)
{
struct nvmm_type *mt;
int ret = 0;
list_for_each_entry(mt, &nvm_mgrs, list) {
ret = mt->register_mgr(dev);
if (ret > 0) {
dev->mt = mt;
break; /* successfully initialized */
}
}
if (!ret)
pr_info("nvm: no compatible nvm manager found.\n");
return ret;
}
static struct nvm_dev *nvm_find_nvm_dev(const char *name) static struct nvm_dev *nvm_find_nvm_dev(const char *name)
{ {
struct nvm_dev *dev; struct nvm_dev *dev;
...@@ -271,14 +283,6 @@ static int nvm_init(struct nvm_dev *dev) ...@@ -271,14 +283,6 @@ static int nvm_init(struct nvm_dev *dev)
goto err; goto err;
} }
down_write(&nvm_lock);
ret = register_mgr(dev);
up_write(&nvm_lock);
if (ret < 0)
goto err;
if (!ret)
return 0;
pr_info("nvm: registered %s [%u/%u/%u/%u/%u/%u]\n", pr_info("nvm: registered %s [%u/%u/%u/%u/%u/%u]\n",
dev->name, dev->sec_per_pg, dev->nr_planes, dev->name, dev->sec_per_pg, dev->nr_planes,
dev->pgs_per_blk, dev->blks_per_lun, dev->nr_luns, dev->pgs_per_blk, dev->blks_per_lun, dev->nr_luns,
...@@ -334,7 +338,9 @@ int nvm_register(struct request_queue *q, char *disk_name, ...@@ -334,7 +338,9 @@ int nvm_register(struct request_queue *q, char *disk_name,
} }
} }
/* register device with a supported media manager */
down_write(&nvm_lock); down_write(&nvm_lock);
dev->mt = nvm_init_mgr(dev);
list_add(&dev->devices, &nvm_devices); list_add(&dev->devices, &nvm_devices);
up_write(&nvm_lock); up_write(&nvm_lock);
...@@ -379,19 +385,13 @@ static int nvm_create_target(struct nvm_dev *dev, ...@@ -379,19 +385,13 @@ static int nvm_create_target(struct nvm_dev *dev,
struct nvm_tgt_type *tt; struct nvm_tgt_type *tt;
struct nvm_target *t; struct nvm_target *t;
void *targetdata; void *targetdata;
int ret = 0;
down_write(&nvm_lock);
if (!dev->mt) { if (!dev->mt) {
ret = register_mgr(dev); pr_info("nvm: device has no media manager registered.\n");
if (!ret) return -ENODEV;
ret = -ENODEV;
if (ret < 0) {
up_write(&nvm_lock);
return ret;
}
} }
down_write(&nvm_lock);
tt = nvm_find_target_type(create->tgttype); tt = nvm_find_target_type(create->tgttype);
if (!tt) { if (!tt) {
pr_err("nvm: target type %s not found\n", create->tgttype); pr_err("nvm: target type %s not found\n", create->tgttype);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册