1
0
Fork 0

lightnvm: avoid memory leak when lun_map kcalloc fails

A memory leak occurs if the lower page table is initialized and the
following dev->lun_map fails on allocation.

Rearrange the initialization of lower page table to allow dev->lun_map
to fail gracefully without memory leak.

Reviewed by: Johannes Thumshirn <jthumshirn@suse.de>
Move kfree of dev->lun_map to nvm_free()
Signed-off-by: Matias Bjørling <m@bjorling.me>
Signed-off-by: Jens Axboe <axboe@fb.com>
hifive-unleashed-5.1
Matias Bjørling 2016-05-06 20:02:59 +02:00 committed by Jens Axboe
parent 22e8c9766a
commit 7f7c5d03c0
1 changed files with 30 additions and 23 deletions

View File

@ -504,6 +504,7 @@ static int nvm_core_init(struct nvm_dev *dev)
{
struct nvm_id *id = &dev->identity;
struct nvm_id_group *grp = &id->groups[0];
int ret;
/* device values */
dev->nr_chnls = grp->num_ch;
@ -522,33 +523,16 @@ static int nvm_core_init(struct nvm_dev *dev)
dev->plane_mode = NVM_PLANE_SINGLE;
dev->max_rq_size = dev->ops->max_phys_sect * dev->sec_size;
if (grp->mtype != 0) {
pr_err("nvm: memory type not supported\n");
return -EINVAL;
}
switch (grp->fmtype) {
case NVM_ID_FMTYPE_SLC:
if (nvm_init_slc_tbl(dev, grp))
return -ENOMEM;
break;
case NVM_ID_FMTYPE_MLC:
if (nvm_init_mlc_tbl(dev, grp))
return -ENOMEM;
break;
default:
pr_err("nvm: flash type not supported\n");
return -EINVAL;
}
if (!dev->lps_per_blk)
pr_info("nvm: lower page programming table missing\n");
if (grp->mpos & 0x020202)
dev->plane_mode = NVM_PLANE_DOUBLE;
if (grp->mpos & 0x040404)
dev->plane_mode = NVM_PLANE_QUAD;
if (grp->mtype != 0) {
pr_err("nvm: memory type not supported\n");
return -EINVAL;
}
/* calculated values */
dev->sec_per_pl = dev->sec_per_pg * dev->nr_planes;
dev->sec_per_blk = dev->sec_per_pl * dev->pgs_per_blk;
@ -560,11 +544,34 @@ static int nvm_core_init(struct nvm_dev *dev)
sizeof(unsigned long), GFP_KERNEL);
if (!dev->lun_map)
return -ENOMEM;
switch (grp->fmtype) {
case NVM_ID_FMTYPE_SLC:
if (nvm_init_slc_tbl(dev, grp)) {
ret = -ENOMEM;
goto err_fmtype;
}
break;
case NVM_ID_FMTYPE_MLC:
if (nvm_init_mlc_tbl(dev, grp)) {
ret = -ENOMEM;
goto err_fmtype;
}
break;
default:
pr_err("nvm: flash type not supported\n");
ret = -EINVAL;
goto err_fmtype;
}
INIT_LIST_HEAD(&dev->online_targets);
mutex_init(&dev->mlock);
spin_lock_init(&dev->lock);
return 0;
err_fmtype:
kfree(dev->lun_map);
return ret;
}
static void nvm_free(struct nvm_dev *dev)
@ -576,6 +583,7 @@ static void nvm_free(struct nvm_dev *dev)
dev->mt->unregister_mgr(dev);
kfree(dev->lptbl);
kfree(dev->lun_map);
}
static int nvm_init(struct nvm_dev *dev)
@ -705,7 +713,6 @@ void nvm_unregister(char *disk_name)
up_write(&nvm_lock);
nvm_exit(dev);
kfree(dev->lun_map);
kfree(dev);
}
EXPORT_SYMBOL(nvm_unregister);