]> git.karo-electronics.de Git - linux-beck.git/commitdiff
UBI: Fastmap: Fix memory leak while attaching
authorRichard Weinberger <richard@nod.at>
Mon, 6 Oct 2014 13:39:01 +0000 (15:39 +0200)
committerRichard Weinberger <richard@nod.at>
Thu, 26 Mar 2015 21:45:57 +0000 (22:45 +0100)
Currently we leak a few ubi_ainf_pebs while attaching.

Signed-off-by: Richard Weinberger <richard@nod.at>
drivers/mtd/ubi/attach.c
drivers/mtd/ubi/fastmap.c

index b5e154856994edc8ecdaaec8a23294bd1bf1ed70..ef619c3a75d36a9bcb93b1a6130ba0f685f44fc5 100644 (file)
@@ -1301,6 +1301,30 @@ out_ech:
        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
 
 /**
@@ -1313,7 +1337,7 @@ out_ech:
  * 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)
+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;
@@ -1334,7 +1358,7 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai)
                cond_resched();
 
                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)
                        goto out_vidh;
 
@@ -1350,7 +1374,12 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai)
        if (fm_anchor < 0)
                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:
        ubi_free_vid_hdr(ubi, vidh);
@@ -1362,30 +1391,6 @@ out:
 
 #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: UBI device descriptor
@@ -1413,7 +1418,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)
        if (force_scan)
                err = scan_all(ubi, ai, 0);
        else {
-               err = scan_fast(ubi, ai);
+               err = scan_fast(ubi, &ai);
                if (err > 0) {
                        if (err != UBI_NO_FASTMAP) {
                                destroy_ai(ai);
index 95077026ad535f8cc50beb3e5dbc67e65ca1d3c6..600c4f9683e9ea79eebb6dc02229b54e40914c15 100644 (file)
@@ -561,21 +561,8 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
        INIT_LIST_HEAD(&used);
        INIT_LIST_HEAD(&free);
        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->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);
        ai->max_sqnum = fmsb->sqnum;
        fm_pos += sizeof(struct ubi_fm_sb);