diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-13 01:29:38 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-13 01:29:38 -0500 |
commit | 39222c82f738190a4f09be89510a8336a73b67c8 (patch) | |
tree | ce0bd714eccc8d379e88a0d3e93bb43583f3ca1c | |
parent | fbe43ff0031ded2b8500382da17d5d815a9c3edd (diff) | |
parent | ae0d146955665411a6d4cea5e0893429cfc52807 (diff) |
Merge tag 'upstream-3.13-rc1' of git://git.infradead.org/linux-ubi
Pull UBI changes from Artem Bityutskiy:
"A bunch of fixes for the fastmap feature, which is still new and
rather experimental. It looks like it starts getting more users.
No significant changes for the "classical" non-fastmap UBI"
* tag 'upstream-3.13-rc1' of git://git.infradead.org/linux-ubi:
UBI: Add some asserts to ubi_attach_fastmap()
UBI: Fix memory leak in ubi_attach_fastmap() error path
UBI: simplify image sequence test
UBI: fastmap: fix backward compatibility with image_seq
UBI: Call scan_all() with correct offset in error case
UBI: Fix error path in scan_pool()
UBI: fix refill_wl_user_pool()
-rw-r--r-- | drivers/mtd/ubi/attach.c | 11 | ||||
-rw-r--r-- | drivers/mtd/ubi/fastmap.c | 41 | ||||
-rw-r--r-- | drivers/mtd/ubi/wl.c | 4 |
3 files changed, 43 insertions, 13 deletions
diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index c071d410488f..33bb1f2b63e4 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, | |||
900 | * number. | 900 | * number. |
901 | */ | 901 | */ |
902 | image_seq = be32_to_cpu(ech->image_seq); | 902 | image_seq = be32_to_cpu(ech->image_seq); |
903 | if (!ubi->image_seq && image_seq) | 903 | if (!ubi->image_seq) |
904 | ubi->image_seq = image_seq; | 904 | ubi->image_seq = image_seq; |
905 | if (ubi->image_seq && image_seq && | 905 | if (image_seq && ubi->image_seq != image_seq) { |
906 | ubi->image_seq != image_seq) { | ||
907 | ubi_err("bad image sequence number %d in PEB %d, expected %d", | 906 | ubi_err("bad image sequence number %d in PEB %d, expected %d", |
908 | image_seq, pnum, ubi->image_seq); | 907 | image_seq, pnum, ubi->image_seq); |
909 | ubi_dump_ec_hdr(ech); | 908 | ubi_dump_ec_hdr(ech); |
@@ -1417,9 +1416,11 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) | |||
1417 | ai = alloc_ai("ubi_aeb_slab_cache2"); | 1416 | ai = alloc_ai("ubi_aeb_slab_cache2"); |
1418 | if (!ai) | 1417 | if (!ai) |
1419 | return -ENOMEM; | 1418 | return -ENOMEM; |
1420 | } | ||
1421 | 1419 | ||
1422 | err = scan_all(ubi, ai, UBI_FM_MAX_START); | 1420 | err = scan_all(ubi, ai, 0); |
1421 | } else { | ||
1422 | err = scan_all(ubi, ai, UBI_FM_MAX_START); | ||
1423 | } | ||
1423 | } | 1424 | } |
1424 | } | 1425 | } |
1425 | #else | 1426 | #else |
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index f5aa4b02cfa6..ead861307b3c 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, | |||
407 | */ | 407 | */ |
408 | for (i = 0; i < pool_size; i++) { | 408 | for (i = 0; i < pool_size; i++) { |
409 | int scrub = 0; | 409 | int scrub = 0; |
410 | int image_seq; | ||
410 | 411 | ||
411 | pnum = be32_to_cpu(pebs[i]); | 412 | pnum = be32_to_cpu(pebs[i]); |
412 | 413 | ||
@@ -425,10 +426,16 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, | |||
425 | } else if (ret == UBI_IO_BITFLIPS) | 426 | } else if (ret == UBI_IO_BITFLIPS) |
426 | scrub = 1; | 427 | scrub = 1; |
427 | 428 | ||
428 | if (be32_to_cpu(ech->image_seq) != ubi->image_seq) { | 429 | /* |
430 | * Older UBI implementations have image_seq set to zero, so | ||
431 | * we shouldn't fail if image_seq == 0. | ||
432 | */ | ||
433 | image_seq = be32_to_cpu(ech->image_seq); | ||
434 | |||
435 | if (image_seq && (image_seq != ubi->image_seq)) { | ||
429 | ubi_err("bad image seq: 0x%x, expected: 0x%x", | 436 | ubi_err("bad image seq: 0x%x, expected: 0x%x", |
430 | be32_to_cpu(ech->image_seq), ubi->image_seq); | 437 | be32_to_cpu(ech->image_seq), ubi->image_seq); |
431 | err = UBI_BAD_FASTMAP; | 438 | ret = UBI_BAD_FASTMAP; |
432 | goto out; | 439 | goto out; |
433 | } | 440 | } |
434 | 441 | ||
@@ -819,6 +826,10 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, | |||
819 | list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) | 826 | list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) |
820 | list_move_tail(&tmp_aeb->u.list, &ai->free); | 827 | list_move_tail(&tmp_aeb->u.list, &ai->free); |
821 | 828 | ||
829 | ubi_assert(list_empty(&used)); | ||
830 | ubi_assert(list_empty(&eba_orphans)); | ||
831 | ubi_assert(list_empty(&free)); | ||
832 | |||
822 | /* | 833 | /* |
823 | * If fastmap is leaking PEBs (must not happen), raise a | 834 | * If fastmap is leaking PEBs (must not happen), raise a |
824 | * fat warning and fall back to scanning mode. | 835 | * fat warning and fall back to scanning mode. |
@@ -834,6 +845,19 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, | |||
834 | fail_bad: | 845 | fail_bad: |
835 | ret = UBI_BAD_FASTMAP; | 846 | ret = UBI_BAD_FASTMAP; |
836 | fail: | 847 | fail: |
848 | list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &used, u.list) { | ||
849 | kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); | ||
850 | list_del(&tmp_aeb->u.list); | ||
851 | } | ||
852 | list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &eba_orphans, u.list) { | ||
853 | kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); | ||
854 | list_del(&tmp_aeb->u.list); | ||
855 | } | ||
856 | list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) { | ||
857 | kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); | ||
858 | list_del(&tmp_aeb->u.list); | ||
859 | } | ||
860 | |||
837 | return ret; | 861 | return ret; |
838 | } | 862 | } |
839 | 863 | ||
@@ -923,6 +947,8 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, | |||
923 | } | 947 | } |
924 | 948 | ||
925 | for (i = 0; i < used_blocks; i++) { | 949 | for (i = 0; i < used_blocks; i++) { |
950 | int image_seq; | ||
951 | |||
926 | pnum = be32_to_cpu(fmsb->block_loc[i]); | 952 | pnum = be32_to_cpu(fmsb->block_loc[i]); |
927 | 953 | ||
928 | if (ubi_io_is_bad(ubi, pnum)) { | 954 | if (ubi_io_is_bad(ubi, pnum)) { |
@@ -940,10 +966,17 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, | |||
940 | } else if (ret == UBI_IO_BITFLIPS) | 966 | } else if (ret == UBI_IO_BITFLIPS) |
941 | fm->to_be_tortured[i] = 1; | 967 | fm->to_be_tortured[i] = 1; |
942 | 968 | ||
969 | image_seq = be32_to_cpu(ech->image_seq); | ||
943 | if (!ubi->image_seq) | 970 | if (!ubi->image_seq) |
944 | ubi->image_seq = be32_to_cpu(ech->image_seq); | 971 | ubi->image_seq = image_seq; |
945 | 972 | ||
946 | if (be32_to_cpu(ech->image_seq) != ubi->image_seq) { | 973 | /* |
974 | * Older UBI implementations have image_seq set to zero, so | ||
975 | * we shouldn't fail if image_seq == 0. | ||
976 | */ | ||
977 | if (image_seq && (image_seq != ubi->image_seq)) { | ||
978 | ubi_err("wrong image seq:%d instead of %d", | ||
979 | be32_to_cpu(ech->image_seq), ubi->image_seq); | ||
947 | ret = UBI_BAD_FASTMAP; | 980 | ret = UBI_BAD_FASTMAP; |
948 | goto free_hdr; | 981 | goto free_hdr; |
949 | } | 982 | } |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index c95bfb183c62..02317c1c0238 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) | |||
599 | return_unused_pool_pebs(ubi, pool); | 599 | return_unused_pool_pebs(ubi, pool); |
600 | 600 | ||
601 | for (pool->size = 0; pool->size < pool->max_size; pool->size++) { | 601 | for (pool->size = 0; pool->size < pool->max_size; pool->size++) { |
602 | if (!ubi->free.rb_node || | ||
603 | (ubi->free_count - ubi->beb_rsvd_pebs < 1)) | ||
604 | break; | ||
605 | |||
606 | pool->pebs[pool->size] = __wl_get_peb(ubi); | 602 | pool->pebs[pool->size] = __wl_get_peb(ubi); |
607 | if (pool->pebs[pool->size] < 0) | 603 | if (pool->pebs[pool->size] < 0) |
608 | break; | 604 | break; |