From fb10e4d418c73096ec61d8e80e2af282a5891039 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Sat, 28 Sep 2013 15:55:10 +0200 Subject: UBI: fix refill_wl_user_pool() If no free PEBs are available refill_wl_user_pool() must not return with -ENOSPC immediately. It has to block till produce_free_peb() produced a free PEB. Reported-and-Tested-by: Richard Genoud Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/wl.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index c95bfb183c6..02317c1c023 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -599,10 +599,6 @@ static void refill_wl_user_pool(struct ubi_device *ubi) return_unused_pool_pebs(ubi, pool); for (pool->size = 0; pool->size < pool->max_size; pool->size++) { - if (!ubi->free.rb_node || - (ubi->free_count - ubi->beb_rsvd_pebs < 1)) - break; - pool->pebs[pool->size] = __wl_get_peb(ubi); if (pool->pebs[pool->size] < 0) break; -- cgit v1.2.3 From f240dca8f2fdf11d52a7bacd867e274c3b21a7d3 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Sat, 28 Sep 2013 15:55:11 +0200 Subject: UBI: Fix error path in scan_pool() We have to set "ret", not "err" in case of an error. Reported-and-tested-by: Richard Genoud Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/fastmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index f5aa4b02cfa..9b42add0553 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c @@ -428,7 +428,7 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, if (be32_to_cpu(ech->image_seq) != ubi->image_seq) { ubi_err("bad image seq: 0x%x, expected: 0x%x", be32_to_cpu(ech->image_seq), ubi->image_seq); - err = UBI_BAD_FASTMAP; + ret = UBI_BAD_FASTMAP; goto out; } -- cgit v1.2.3 From 4b3e0a25aa5518892ec8dbfafdd6a57789aa0c22 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Sat, 28 Sep 2013 15:55:12 +0200 Subject: UBI: Call scan_all() with correct offset in error case If we find an invalid fastmap we have to scan from the very beginning. Otherwise we leak the first 64 PEBs. Reported-and-tested-by: Richard Genoud Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/attach.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index c071d410488..03b32b05ab1 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -1417,9 +1417,11 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) ai = alloc_ai("ubi_aeb_slab_cache2"); if (!ai) return -ENOMEM; - } - err = scan_all(ubi, ai, UBI_FM_MAX_START); + err = scan_all(ubi, ai, 0); + } else { + err = scan_all(ubi, ai, UBI_FM_MAX_START); + } } } #else -- cgit v1.2.3 From c22301ad4fa0f4cf71e9c877d072e6f07a0bf682 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Sat, 28 Sep 2013 15:55:13 +0200 Subject: UBI: fastmap: fix backward compatibility with image_seq Some old UBI implementations (e.g. U-Boot) have not implemented the image sequence feature. So, when erase blocks are written, the image sequence in the ec header is lost (set to zero). UBI scan_all() takes this case into account (commits 32bc4820287a1a03982979515949e8ea56eac641 and 2eadaad67b2b6bd132eda105128d2d466298b8e3) But fastmap scan functions (ubi_scan_fastmap() and scan_pool()) didn't. This patch fixes the issue. Signed-off-by: Richard Genoud Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/fastmap.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index 9b42add0553..05067f52247 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c @@ -407,6 +407,7 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, */ for (i = 0; i < pool_size; i++) { int scrub = 0; + int image_seq; pnum = be32_to_cpu(pebs[i]); @@ -425,7 +426,13 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, } else if (ret == UBI_IO_BITFLIPS) scrub = 1; - if (be32_to_cpu(ech->image_seq) != ubi->image_seq) { + /* + * Older UBI implementations have image_seq set to zero, so + * we shouldn't fail if image_seq == 0. + */ + image_seq = be32_to_cpu(ech->image_seq); + + if (image_seq && (image_seq != ubi->image_seq)) { ubi_err("bad image seq: 0x%x, expected: 0x%x", be32_to_cpu(ech->image_seq), ubi->image_seq); ret = UBI_BAD_FASTMAP; @@ -923,6 +930,8 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, } for (i = 0; i < used_blocks; i++) { + int image_seq; + pnum = be32_to_cpu(fmsb->block_loc[i]); if (ubi_io_is_bad(ubi, pnum)) { @@ -940,10 +949,17 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, } else if (ret == UBI_IO_BITFLIPS) fm->to_be_tortured[i] = 1; + image_seq = be32_to_cpu(ech->image_seq); if (!ubi->image_seq) - ubi->image_seq = be32_to_cpu(ech->image_seq); + ubi->image_seq = image_seq; - if (be32_to_cpu(ech->image_seq) != ubi->image_seq) { + /* + * Older UBI implementations have image_seq set to zero, so + * we shouldn't fail if image_seq == 0. + */ + if (image_seq && (image_seq != ubi->image_seq)) { + ubi_err("wrong image seq:%d instead of %d", + be32_to_cpu(ech->image_seq), ubi->image_seq); ret = UBI_BAD_FASTMAP; goto free_hdr; } -- cgit v1.2.3 From 55b80c409a1368b8dff3c78943101bccb0ea3aa1 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Sat, 28 Sep 2013 15:55:14 +0200 Subject: UBI: simplify image sequence test The test: if (!a && b) a = b; can be symplified in: if (!a) a = b; And there's no need to test if ubi->image_seq is not null, because if it is, it is set to image_seq. So, we just test if image_seq is not null. Signed-off-by: Richard Genoud Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/attach.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index 03b32b05ab1..33bb1f2b63e 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -900,10 +900,9 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, * number. */ image_seq = be32_to_cpu(ech->image_seq); - if (!ubi->image_seq && image_seq) + if (!ubi->image_seq) ubi->image_seq = image_seq; - if (ubi->image_seq && image_seq && - ubi->image_seq != image_seq) { + if (image_seq && ubi->image_seq != image_seq) { ubi_err("bad image sequence number %d in PEB %d, expected %d", image_seq, pnum, ubi->image_seq); ubi_dump_ec_hdr(ech); -- cgit v1.2.3 From fe24c6e5f51ec5ea42d432f67618a084047a23ed Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Sat, 28 Sep 2013 15:55:15 +0200 Subject: UBI: Fix memory leak in ubi_attach_fastmap() error path On error we have to free all three temporary lists. Reported-by: Richard Genoud Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/fastmap.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index 05067f52247..4cfc8da2722 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c @@ -841,6 +841,19 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, fail_bad: ret = UBI_BAD_FASTMAP; fail: + list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &used, u.list) { + kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); + list_del(&tmp_aeb->u.list); + } + list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &eba_orphans, u.list) { + kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); + list_del(&tmp_aeb->u.list); + } + list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) { + kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); + list_del(&tmp_aeb->u.list); + } + return ret; } -- cgit v1.2.3 From ae0d146955665411a6d4cea5e0893429cfc52807 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Sat, 28 Sep 2013 15:55:16 +0200 Subject: UBI: Add some asserts to ubi_attach_fastmap() Add more paranioa asserts to make it easier to detect implementation errors. Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/fastmap.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index 4cfc8da2722..ead861307b3 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c @@ -826,6 +826,10 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) list_move_tail(&tmp_aeb->u.list, &ai->free); + ubi_assert(list_empty(&used)); + ubi_assert(list_empty(&eba_orphans)); + ubi_assert(list_empty(&free)); + /* * If fastmap is leaking PEBs (must not happen), raise a * fat warning and fall back to scanning mode. -- cgit v1.2.3