Commit 39222c82 authored by Linus Torvalds's avatar Linus Torvalds

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()
parents fbe43ff0 ae0d1469
...@@ -900,10 +900,9 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, ...@@ -900,10 +900,9 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
* number. * number.
*/ */
image_seq = be32_to_cpu(ech->image_seq); image_seq = be32_to_cpu(ech->image_seq);
if (!ubi->image_seq && image_seq) if (!ubi->image_seq)
ubi->image_seq = image_seq; ubi->image_seq = image_seq;
if (ubi->image_seq && image_seq && if (image_seq && ubi->image_seq != image_seq) {
ubi->image_seq != image_seq) {
ubi_err("bad image sequence number %d in PEB %d, expected %d", ubi_err("bad image sequence number %d in PEB %d, expected %d",
image_seq, pnum, ubi->image_seq); image_seq, pnum, ubi->image_seq);
ubi_dump_ec_hdr(ech); ubi_dump_ec_hdr(ech);
...@@ -1417,11 +1416,13 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) ...@@ -1417,11 +1416,13 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)
ai = alloc_ai("ubi_aeb_slab_cache2"); ai = alloc_ai("ubi_aeb_slab_cache2");
if (!ai) if (!ai)
return -ENOMEM; return -ENOMEM;
}
err = scan_all(ubi, ai, 0);
} else {
err = scan_all(ubi, ai, UBI_FM_MAX_START); err = scan_all(ubi, ai, UBI_FM_MAX_START);
} }
} }
}
#else #else
err = scan_all(ubi, ai, 0); err = scan_all(ubi, ai, 0);
#endif #endif
......
...@@ -407,6 +407,7 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, ...@@ -407,6 +407,7 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai,
*/ */
for (i = 0; i < pool_size; i++) { for (i = 0; i < pool_size; i++) {
int scrub = 0; int scrub = 0;
int image_seq;
pnum = be32_to_cpu(pebs[i]); pnum = be32_to_cpu(pebs[i]);
...@@ -425,10 +426,16 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, ...@@ -425,10 +426,16 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai,
} else if (ret == UBI_IO_BITFLIPS) } else if (ret == UBI_IO_BITFLIPS)
scrub = 1; 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", ubi_err("bad image seq: 0x%x, expected: 0x%x",
be32_to_cpu(ech->image_seq), ubi->image_seq); be32_to_cpu(ech->image_seq), ubi->image_seq);
err = UBI_BAD_FASTMAP; ret = UBI_BAD_FASTMAP;
goto out; goto out;
} }
...@@ -819,6 +826,10 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, ...@@ -819,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_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list)
list_move_tail(&tmp_aeb->u.list, &ai->free); 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 * If fastmap is leaking PEBs (must not happen), raise a
* fat warning and fall back to scanning mode. * fat warning and fall back to scanning mode.
...@@ -834,6 +845,19 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, ...@@ -834,6 +845,19 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
fail_bad: fail_bad:
ret = UBI_BAD_FASTMAP; ret = UBI_BAD_FASTMAP;
fail: 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; return ret;
} }
...@@ -923,6 +947,8 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, ...@@ -923,6 +947,8 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
} }
for (i = 0; i < used_blocks; i++) { for (i = 0; i < used_blocks; i++) {
int image_seq;
pnum = be32_to_cpu(fmsb->block_loc[i]); pnum = be32_to_cpu(fmsb->block_loc[i]);
if (ubi_io_is_bad(ubi, pnum)) { 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,10 +966,17 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
} else if (ret == UBI_IO_BITFLIPS) } else if (ret == UBI_IO_BITFLIPS)
fm->to_be_tortured[i] = 1; fm->to_be_tortured[i] = 1;
image_seq = be32_to_cpu(ech->image_seq);
if (!ubi->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; ret = UBI_BAD_FASTMAP;
goto free_hdr; goto free_hdr;
} }
......
...@@ -599,10 +599,6 @@ static void refill_wl_user_pool(struct ubi_device *ubi) ...@@ -599,10 +599,6 @@ static void refill_wl_user_pool(struct ubi_device *ubi)
return_unused_pool_pebs(ubi, pool); return_unused_pool_pebs(ubi, pool);
for (pool->size = 0; pool->size < pool->max_size; pool->size++) { 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); pool->pebs[pool->size] = __wl_get_peb(ubi);
if (pool->pebs[pool->size] < 0) if (pool->pebs[pool->size] < 0)
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment