Commit 98105d08 authored by Richard Weinberger's avatar Richard Weinberger

UBI: Fastmap: Fix memory leak while attaching

Currently we leak a few ubi_ainf_pebs while attaching.
Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
parent 84b678f4
...@@ -1301,6 +1301,30 @@ static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai, ...@@ -1301,6 +1301,30 @@ static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai,
return err; return err;
} }
static struct ubi_attach_info *alloc_ai(const char *slab_name)
{
struct ubi_attach_info *ai;
ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL);
if (!ai)
return ai;
INIT_LIST_HEAD(&ai->corr);
INIT_LIST_HEAD(&ai->free);
INIT_LIST_HEAD(&ai->erase);
INIT_LIST_HEAD(&ai->alien);
ai->volumes = RB_ROOT;
ai->aeb_slab_cache = kmem_cache_create(slab_name,
sizeof(struct ubi_ainf_peb),
0, 0, NULL);
if (!ai->aeb_slab_cache) {
kfree(ai);
ai = NULL;
}
return ai;
}
#ifdef CONFIG_MTD_UBI_FASTMAP #ifdef CONFIG_MTD_UBI_FASTMAP
/** /**
...@@ -1313,7 +1337,7 @@ static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai, ...@@ -1313,7 +1337,7 @@ static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai,
* UBI_NO_FASTMAP denotes that no fastmap was found. * UBI_NO_FASTMAP denotes that no fastmap was found.
* UBI_BAD_FASTMAP denotes that the found fastmap was invalid. * UBI_BAD_FASTMAP denotes that the found fastmap was invalid.
*/ */
static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai) static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info **ai)
{ {
int err, pnum, fm_anchor = -1; int err, pnum, fm_anchor = -1;
unsigned long long max_sqnum = 0; unsigned long long max_sqnum = 0;
...@@ -1334,7 +1358,7 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai) ...@@ -1334,7 +1358,7 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai)
cond_resched(); cond_resched();
dbg_gen("process PEB %d", pnum); dbg_gen("process PEB %d", pnum);
err = scan_peb(ubi, ai, pnum, &vol_id, &sqnum); err = scan_peb(ubi, *ai, pnum, &vol_id, &sqnum);
if (err < 0) if (err < 0)
goto out_vidh; goto out_vidh;
...@@ -1350,7 +1374,12 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai) ...@@ -1350,7 +1374,12 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai)
if (fm_anchor < 0) if (fm_anchor < 0)
return UBI_NO_FASTMAP; return UBI_NO_FASTMAP;
return ubi_scan_fastmap(ubi, ai, fm_anchor); destroy_ai(*ai);
*ai = alloc_ai("ubi_aeb_slab_cache");
if (!*ai)
return -ENOMEM;
return ubi_scan_fastmap(ubi, *ai, fm_anchor);
out_vidh: out_vidh:
ubi_free_vid_hdr(ubi, vidh); ubi_free_vid_hdr(ubi, vidh);
...@@ -1362,30 +1391,6 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai) ...@@ -1362,30 +1391,6 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai)
#endif #endif
static struct ubi_attach_info *alloc_ai(const char *slab_name)
{
struct ubi_attach_info *ai;
ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL);
if (!ai)
return ai;
INIT_LIST_HEAD(&ai->corr);
INIT_LIST_HEAD(&ai->free);
INIT_LIST_HEAD(&ai->erase);
INIT_LIST_HEAD(&ai->alien);
ai->volumes = RB_ROOT;
ai->aeb_slab_cache = kmem_cache_create(slab_name,
sizeof(struct ubi_ainf_peb),
0, 0, NULL);
if (!ai->aeb_slab_cache) {
kfree(ai);
ai = NULL;
}
return ai;
}
/** /**
* ubi_attach - attach an MTD device. * ubi_attach - attach an MTD device.
* @ubi: UBI device descriptor * @ubi: UBI device descriptor
...@@ -1413,7 +1418,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) ...@@ -1413,7 +1418,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)
if (force_scan) if (force_scan)
err = scan_all(ubi, ai, 0); err = scan_all(ubi, ai, 0);
else { else {
err = scan_fast(ubi, ai); err = scan_fast(ubi, &ai);
if (err > 0) { if (err > 0) {
if (err != UBI_NO_FASTMAP) { if (err != UBI_NO_FASTMAP) {
destroy_ai(ai); destroy_ai(ai);
......
...@@ -561,21 +561,8 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, ...@@ -561,21 +561,8 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
INIT_LIST_HEAD(&used); INIT_LIST_HEAD(&used);
INIT_LIST_HEAD(&free); INIT_LIST_HEAD(&free);
INIT_LIST_HEAD(&eba_orphans); INIT_LIST_HEAD(&eba_orphans);
INIT_LIST_HEAD(&ai->corr);
INIT_LIST_HEAD(&ai->free);
INIT_LIST_HEAD(&ai->erase);
INIT_LIST_HEAD(&ai->alien);
ai->volumes = RB_ROOT;
ai->min_ec = UBI_MAX_ERASECOUNTER; ai->min_ec = UBI_MAX_ERASECOUNTER;
ai->aeb_slab_cache = kmem_cache_create("ubi_ainf_peb_slab",
sizeof(struct ubi_ainf_peb),
0, 0, NULL);
if (!ai->aeb_slab_cache) {
ret = -ENOMEM;
goto fail;
}
fmsb = (struct ubi_fm_sb *)(fm_raw); fmsb = (struct ubi_fm_sb *)(fm_raw);
ai->max_sqnum = fmsb->sqnum; ai->max_sqnum = fmsb->sqnum;
fm_pos += sizeof(struct ubi_fm_sb); fm_pos += sizeof(struct ubi_fm_sb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment