Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754330Ab3DPGsU (ORCPT ); Tue, 16 Apr 2013 02:48:20 -0400 Received: from mx7.zte.com.cn ([202.103.147.169]:51811 "EHLO zte.com.cn" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753567Ab3DPGsT (ORCPT ); Tue, 16 Apr 2013 02:48:19 -0400 X-Greylist: delayed 982 seconds by postgrey-1.27 at vger.kernel.org; Tue, 16 Apr 2013 02:48:19 EDT To: richard.weinberger@gmail.com, Artem.Bityutskiy@nokia.com Cc: linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org, liu.dong3@zte.com.cn, cui.yunfeng@zte.com.cn Subject: [PATCH] UBI: fix memory leak when use fastmap MIME-Version: 1.0 X-KeepSent: 977C9455:A4106C5F-48257B4F:0022FF01; type=4; name=$KeepSent X-Mailer: Lotus Notes Release 6.5.6 March 06, 2007 Message-ID: From: wang.bo116@zte.com.cn Date: Tue, 16 Apr 2013 14:31:14 +0800 X-MIMETrack: Serialize by Router on notes_smtp/zte_ltd(Release 8.5.3FP1 HF212|May 23, 2012) at 2013-04-16 14:31:07, Serialize complete at 2013-04-16 14:31:07 Content-Type: text/plain; charset="US-ASCII" X-MAIL: mse02.zte.com.cn r3G6VKF4046649 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4944 Lines: 161 UBI: fix memory leak when use fastmap When use ubi fastmap, there is a memory leak which will make destroy_ai() called in ubi_attach fail. The following patch base on linux-3.9-rc6 fix this problem. diff -uprN old_ubi/attach.c new_ubi/attach.c --- old_ubi/attach.c 2013-04-08 03:49:54.000000000 +0000 +++ new_ubi/attach.c 2013-04-16 03:22:47.343750000 +0000 @@ -1212,6 +1212,30 @@ static void destroy_ai(struct ubi_attach kfree(ai); } +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; +} + /** * scan_all - scan entire MTD device. * @ubi: UBI device description object @@ -1315,8 +1339,13 @@ static int scan_fast(struct ubi_device * int err, pnum, fm_anchor = -1; unsigned long long max_sqnum = 0; + struct ubi_attach_info *fastmap_temp_ai = NULL; err = -ENOMEM; + fastmap_temp_ai = alloc_ai("ubi_scan_fastmap_slab_cache"); + if (!fastmap_temp_ai) + goto out; + ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); if (!ech) goto out; @@ -1331,7 +1360,7 @@ static int scan_fast(struct ubi_device * cond_resched(); dbg_gen("process PEB %d", pnum); - err = scan_peb(ubi, ai, pnum, &vol_id, &sqnum); + err = scan_peb(ubi, fastmap_temp_ai, pnum, &vol_id, &sqnum); if (err < 0) goto out_vidh; @@ -1343,6 +1372,7 @@ static int scan_fast(struct ubi_device * ubi_free_vid_hdr(ubi, vidh); kfree(ech); + destroy_ai(fastmap_temp_ai); if (fm_anchor < 0) return UBI_NO_FASTMAP; @@ -1351,6 +1381,7 @@ static int scan_fast(struct ubi_device * out_vidh: ubi_free_vid_hdr(ubi, vidh); + destroy_ai(fastmap_temp_ai); out_ech: kfree(ech); out: @@ -1359,29 +1390,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. @@ -1419,7 +1427,7 @@ int ubi_attach(struct ubi_device *ubi, i return -ENOMEM; } - err = scan_all(ubi, ai, UBI_FM_MAX_START); + err = scan_all(ubi, ai, 0); } } #else diff -uprN old_ubi/fastmap.c new_ubi/fastmap.c --- old_ubi/fastmap.c 2013-04-08 03:49:54.000000000 +0000 +++ new_ubi/fastmap.c 2013-04-16 03:22:17.468750000 +0000 @@ -552,21 +552,8 @@ static int ubi_attach_fastmap(struct 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); Signed-off-by: Wang bo Tested-by: Wang bo Reviewed-by: Cui Yunfeng -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/