UBI: Fastmap: Fix memory leak while attaching
Currently we leak a few ubi_ainf_pebs while attaching. Signed-off-by: Richard Weinberger <richard@nod.at>
This commit is contained in:
parent
84b678f497
commit
98105d0819
|
@ -1301,67 +1301,6 @@ out_ech:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_MTD_UBI_FASTMAP
|
|
||||||
|
|
||||||
/**
|
|
||||||
* scan_fastmap - try to find a fastmap and attach from it.
|
|
||||||
* @ubi: UBI device description object
|
|
||||||
* @ai: attach info object
|
|
||||||
*
|
|
||||||
* Returns 0 on success, negative return values indicate an internal
|
|
||||||
* error.
|
|
||||||
* UBI_NO_FASTMAP denotes that no fastmap was found.
|
|
||||||
* UBI_BAD_FASTMAP denotes that the found fastmap was invalid.
|
|
||||||
*/
|
|
||||||
static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai)
|
|
||||||
{
|
|
||||||
int err, pnum, fm_anchor = -1;
|
|
||||||
unsigned long long max_sqnum = 0;
|
|
||||||
|
|
||||||
err = -ENOMEM;
|
|
||||||
|
|
||||||
ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
|
|
||||||
if (!ech)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
|
|
||||||
if (!vidh)
|
|
||||||
goto out_ech;
|
|
||||||
|
|
||||||
for (pnum = 0; pnum < UBI_FM_MAX_START; pnum++) {
|
|
||||||
int vol_id = -1;
|
|
||||||
unsigned long long sqnum = -1;
|
|
||||||
cond_resched();
|
|
||||||
|
|
||||||
dbg_gen("process PEB %d", pnum);
|
|
||||||
err = scan_peb(ubi, ai, pnum, &vol_id, &sqnum);
|
|
||||||
if (err < 0)
|
|
||||||
goto out_vidh;
|
|
||||||
|
|
||||||
if (vol_id == UBI_FM_SB_VOLUME_ID && sqnum > max_sqnum) {
|
|
||||||
max_sqnum = sqnum;
|
|
||||||
fm_anchor = pnum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ubi_free_vid_hdr(ubi, vidh);
|
|
||||||
kfree(ech);
|
|
||||||
|
|
||||||
if (fm_anchor < 0)
|
|
||||||
return UBI_NO_FASTMAP;
|
|
||||||
|
|
||||||
return ubi_scan_fastmap(ubi, ai, fm_anchor);
|
|
||||||
|
|
||||||
out_vidh:
|
|
||||||
ubi_free_vid_hdr(ubi, vidh);
|
|
||||||
out_ech:
|
|
||||||
kfree(ech);
|
|
||||||
out:
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct ubi_attach_info *alloc_ai(const char *slab_name)
|
static struct ubi_attach_info *alloc_ai(const char *slab_name)
|
||||||
{
|
{
|
||||||
struct ubi_attach_info *ai;
|
struct ubi_attach_info *ai;
|
||||||
|
@ -1386,6 +1325,72 @@ static struct ubi_attach_info *alloc_ai(const char *slab_name)
|
||||||
return ai;
|
return ai;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_MTD_UBI_FASTMAP
|
||||||
|
|
||||||
|
/**
|
||||||
|
* scan_fastmap - try to find a fastmap and attach from it.
|
||||||
|
* @ubi: UBI device description object
|
||||||
|
* @ai: attach info object
|
||||||
|
*
|
||||||
|
* Returns 0 on success, negative return values indicate an internal
|
||||||
|
* error.
|
||||||
|
* UBI_NO_FASTMAP denotes that no fastmap was found.
|
||||||
|
* UBI_BAD_FASTMAP denotes that the found fastmap was invalid.
|
||||||
|
*/
|
||||||
|
static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info **ai)
|
||||||
|
{
|
||||||
|
int err, pnum, fm_anchor = -1;
|
||||||
|
unsigned long long max_sqnum = 0;
|
||||||
|
|
||||||
|
err = -ENOMEM;
|
||||||
|
|
||||||
|
ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
|
||||||
|
if (!ech)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
|
||||||
|
if (!vidh)
|
||||||
|
goto out_ech;
|
||||||
|
|
||||||
|
for (pnum = 0; pnum < UBI_FM_MAX_START; pnum++) {
|
||||||
|
int vol_id = -1;
|
||||||
|
unsigned long long sqnum = -1;
|
||||||
|
cond_resched();
|
||||||
|
|
||||||
|
dbg_gen("process PEB %d", pnum);
|
||||||
|
err = scan_peb(ubi, *ai, pnum, &vol_id, &sqnum);
|
||||||
|
if (err < 0)
|
||||||
|
goto out_vidh;
|
||||||
|
|
||||||
|
if (vol_id == UBI_FM_SB_VOLUME_ID && sqnum > max_sqnum) {
|
||||||
|
max_sqnum = sqnum;
|
||||||
|
fm_anchor = pnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ubi_free_vid_hdr(ubi, vidh);
|
||||||
|
kfree(ech);
|
||||||
|
|
||||||
|
if (fm_anchor < 0)
|
||||||
|
return UBI_NO_FASTMAP;
|
||||||
|
|
||||||
|
destroy_ai(*ai);
|
||||||
|
*ai = alloc_ai("ubi_aeb_slab_cache");
|
||||||
|
if (!*ai)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
return ubi_scan_fastmap(ubi, *ai, fm_anchor);
|
||||||
|
|
||||||
|
out_vidh:
|
||||||
|
ubi_free_vid_hdr(ubi, vidh);
|
||||||
|
out_ech:
|
||||||
|
kfree(ech);
|
||||||
|
out:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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)
|
||||||
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,
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue