diff mbox

UBI: fastmap: fix backward compatibility with image_seq

Message ID 1380286316-29911-1-git-send-email-richard.genoud@gmail.com
State Accepted
Commit c22301ad4fa0f4cf71e9c877d072e6f07a0bf682
Headers show

Commit Message

Richard Genoud Sept. 27, 2013, 12:51 p.m. UTC
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 <richard.genoud@gmail.com>
---
 drivers/mtd/ubi/fastmap.c |   22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

Comments

Richard Weinberger Sept. 27, 2013, 1:09 p.m. UTC | #1
Am 27.09.2013 14:51, schrieb Richard Genoud:
> 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 <richard.genoud@gmail.com>
> ---

W00t! Good catch!

Acked-by: Richard Weinberger <richard@nod.at>
Richard Genoud Sept. 27, 2013, 1:16 p.m. UTC | #2
2013/9/27 Richard Weinberger <richard@nod.at>:
> Am 27.09.2013 14:51, schrieb Richard Genoud:
>> 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 <richard.genoud@gmail.com>
>> ---
>
> W00t! Good catch!
>
> Acked-by: Richard Weinberger <richard@nod.at>
Thanks :)


There's still an error when the image sequence is bad:
[   35.632812] UBI error: scan_pool: bad image seq: 0x0, expected: 0x6e452f03
[   35.640625] UBI error: ubi_scan_fastmap: Attach by fastmap failed,
doing a full scan!
[   35.648437] kmem_cache_destroy ubi_ainf_peb_slab: Slab cache still
has objects  <- the destroy_ai in line 1415
[   35.656250] CPU: 0 PID: 486 Comm: ubiattach Not tainted 3.11.1 #38
[   35.656250] [<c001283c>] (unwind_backtrace+0x0/0xe0) from
[<c0010a24>] (show_stack+0x10/0x14)
[   35.671875] [<c0010a24>] (show_stack+0x10/0x14) from [<c019b9e4>]
(destroy_ai+0x230/0x244)
[   35.679687] [<c019b9e4>] (destroy_ai+0x230/0x244) from [<c019d334>]
(ubi_attach+0x1f8/0x390)
[   35.687500] [<c019d334>] (ubi_attach+0x1f8/0x390) from [<c0191a18>]
(ubi_attach_mtd_dev+0x2b8/0x86c)
[   35.695312] [<c0191a18>] (ubi_attach_mtd_dev+0x2b8/0x86c) from
[<c0192208>] (ctrl_cdev_ioctl+0xd0/0x184)
[   35.703125] [<c0192208>] (ctrl_cdev_ioctl+0xd0/0x184) from
[<c007ef4c>] (vfs_ioctl+0x28/0x3c)
[   35.710937] [<c007ef4c>] (vfs_ioctl+0x28/0x3c) from [<c007f974>]
(do_vfs_ioctl+0x4e8/0x54c)
[   35.718750] [<c007f974>] (do_vfs_ioctl+0x4e8/0x54c) from
[<c007fa0c>] (SyS_ioctl+0x34/0x58)
[   35.726562] [<c007fa0c>] (SyS_ioctl+0x34/0x58) from [<c000e3c0>]
(ret_fast_syscall+0x0/0x2c)

I'll look into that

Richard
Richard Weinberger Sept. 27, 2013, 1:21 p.m. UTC | #3
Am 27.09.2013 15:16, schrieb Richard Genoud:
> 2013/9/27 Richard Weinberger <richard@nod.at>:
>> Am 27.09.2013 14:51, schrieb Richard Genoud:
>>> 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 <richard.genoud@gmail.com>
>>> ---
>>
>> W00t! Good catch!
>>
>> Acked-by: Richard Weinberger <richard@nod.at>
> Thanks :)
> 
> 
> There's still an error when the image sequence is bad:
> [   35.632812] UBI error: scan_pool: bad image seq: 0x0, expected: 0x6e452f03
> [   35.640625] UBI error: ubi_scan_fastmap: Attach by fastmap failed,
> doing a full scan!
> [   35.648437] kmem_cache_destroy ubi_ainf_peb_slab: Slab cache still
> has objects  <- the destroy_ai in line 1415

*grrr*, the problem here is that not all allocations which are done via
kmem_cache_alloc(ai->aeb_slab_cache, ...) got kfree()'d.

Thanks,
//richard
Richard Genoud Sept. 27, 2013, 2:53 p.m. UTC | #4
2013/9/27 Richard Weinberger <richard@nod.at>:
> Am 27.09.2013 15:16, schrieb Richard Genoud:
>> 2013/9/27 Richard Weinberger <richard@nod.at>:
>>> Am 27.09.2013 14:51, schrieb Richard Genoud:
>>>> 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 <richard.genoud@gmail.com>
>>>> ---
>>>
>>> W00t! Good catch!
>>>
>>> Acked-by: Richard Weinberger <richard@nod.at>
>> Thanks :)
>>
>>
>> There's still an error when the image sequence is bad:
>> [   35.632812] UBI error: scan_pool: bad image seq: 0x0, expected: 0x6e452f03
>> [   35.640625] UBI error: ubi_scan_fastmap: Attach by fastmap failed,
>> doing a full scan!
>> [   35.648437] kmem_cache_destroy ubi_ainf_peb_slab: Slab cache still
>> has objects  <- the destroy_ai in line 1415
>
> *grrr*, the problem here is that not all allocations which are done via
> kmem_cache_alloc(ai->aeb_slab_cache, ...) got kfree()'d.
>
> Thanks,
> //richard

My first guess is in fastmap.c, function scan_pool(), in the loop "for
(i = 0; i < pool_size; i++)"
there's some "add_aeb()" and "new_aeb = kmem_cache_alloc()"
And on error, I don't see a loop backward to free those ones.


Richard.
diff mbox

Patch

diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index 9b42add..05067f5 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;
 		}