From 5ef4414f4bc26a19cfd5cd11aee9697a863e4d51 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 19 Aug 2013 08:48:12 +0200 Subject: [PATCH 1/2] UBI: Fix PEB leak in wear_leveling_worker() get_peb_for_wl() removes the PEB from the free list. If the WL subsystem detects that no wear leveling is needed it cancels the operation and drops the gained PEB. In this case we have to put the PEB back into the free list. This issue was introduced with commit ed4b7021c (UBI: remove PEB from free tree in get_peb_for_wl()). Cc: # 3.7.x Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/wl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 5df49d3cb5c7..c95bfb183c62 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1069,6 +1069,9 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) { dbg_wl("no WL needed: min used EC %d, max free EC %d", e1->ec, e2->ec); + + /* Give the unused PEB back */ + wl_tree_add(e2, &ubi->free); goto out_cancel; } self_check_in_wl_tree(ubi, e1, &ubi->used); From 8930fa500f55215f0211db9b78255e727ac3f282 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 19 Aug 2013 22:31:49 +0200 Subject: [PATCH 2/2] UBI: Fix invalidate_fastmap() Onging tests uncovered that invalidate_fastmap() is broken. It must not call ubi_wl_put_fm_peb() because all PEBs used by the old fastmap have already been put back. Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/fastmap.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index 154275182b4b..f5aa4b02cfa6 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c @@ -1343,7 +1343,7 @@ static int erase_block(struct ubi_device *ubi, int pnum) static int invalidate_fastmap(struct ubi_device *ubi, struct ubi_fastmap_layout *fm) { - int ret, i; + int ret; struct ubi_vid_hdr *vh; ret = erase_block(ubi, fm->e[0]->pnum); @@ -1360,9 +1360,6 @@ static int invalidate_fastmap(struct ubi_device *ubi, vh->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); ret = ubi_io_write_vid_hdr(ubi, fm->e[0]->pnum, vh); - for (i = 0; i < fm->used_blocks; i++) - ubi_wl_put_fm_peb(ubi, fm->e[i], i, fm->to_be_tortured[i]); - return ret; }