--- zzzz-none-000/linux-3.10.107/drivers/mtd/ubi/fastmap.c 2017-06-27 09:49:32.000000000 +0000 +++ vr9-7490-729/linux-3.10.107/drivers/mtd/ubi/fastmap.c 2021-11-10 11:53:55.000000000 +0000 @@ -24,7 +24,8 @@ { size_t size; - size = sizeof(struct ubi_fm_hdr) + \ + size = sizeof(struct ubi_fm_sb) + \ + sizeof(struct ubi_fm_hdr) + \ sizeof(struct ubi_fm_scan_pool) + \ sizeof(struct ubi_fm_scan_pool) + \ (ubi->peb_count * sizeof(struct ubi_fm_ec)) + \ @@ -127,7 +128,7 @@ if (vol_id > av->vol_id) p = &(*p)->rb_left; - else if (vol_id > av->vol_id) + else p = &(*p)->rb_right; } @@ -329,7 +330,7 @@ if (found) av = tmp_av; else { - ubi_err("orphaned volume in fastmap pool!"); + ubi_err(ubi, "orphaned volume in fastmap pool!"); kmem_cache_free(ai->aeb_slab_cache, new_aeb); return UBI_BAD_FASTMAP; } @@ -408,28 +409,35 @@ */ for (i = 0; i < pool_size; i++) { int scrub = 0; + int image_seq; pnum = be32_to_cpu(pebs[i]); if (ubi_io_is_bad(ubi, pnum)) { - ubi_err("bad PEB in fastmap pool!"); + ubi_err(ubi, "bad PEB in fastmap pool!"); ret = UBI_BAD_FASTMAP; goto out; } err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); if (err && err != UBI_IO_BITFLIPS) { - ubi_err("unable to read EC header! PEB:%i err:%i", + ubi_err(ubi, "unable to read EC header! PEB:%i err:%i", pnum, err); ret = err > 0 ? UBI_BAD_FASTMAP : err; goto out; - } else if (ret == UBI_IO_BITFLIPS) + } else if (err == UBI_IO_BITFLIPS) scrub = 1; - if (be32_to_cpu(ech->image_seq) != ubi->image_seq) { - ubi_err("bad image seq: 0x%x, expected: 0x%x", + /* + * 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(ubi, "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; } @@ -458,8 +466,8 @@ } } if (found_orphan) { - kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); list_del(&tmp_aeb->u.list); + kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); } new_aeb = kmem_cache_alloc(ai->aeb_slab_cache, @@ -486,7 +494,7 @@ } } else { /* We are paranoid and fall back to scanning mode */ - ubi_err("fastmap pool PEBs contains damaged PEBs!"); + ubi_err(ubi, "fastmap pool PEBs contains damaged PEBs!"); ret = err > 0 ? UBI_BAD_FASTMAP : err; goto out; } @@ -581,7 +589,7 @@ goto fail_bad; if (be32_to_cpu(fmhdr->magic) != UBI_FM_HDR_MAGIC) { - ubi_err("bad fastmap header magic: 0x%x, expected: 0x%x", + ubi_err(ubi, "bad fastmap header magic: 0x%x, expected: 0x%x", be32_to_cpu(fmhdr->magic), UBI_FM_HDR_MAGIC); goto fail_bad; } @@ -591,7 +599,7 @@ if (fm_pos >= fm_size) goto fail_bad; if (be32_to_cpu(fmpl1->magic) != UBI_FM_POOL_MAGIC) { - ubi_err("bad fastmap pool magic: 0x%x, expected: 0x%x", + ubi_err(ubi, "bad fastmap pool magic: 0x%x, expected: 0x%x", be32_to_cpu(fmpl1->magic), UBI_FM_POOL_MAGIC); goto fail_bad; } @@ -601,7 +609,7 @@ if (fm_pos >= fm_size) goto fail_bad; if (be32_to_cpu(fmpl2->magic) != UBI_FM_POOL_MAGIC) { - ubi_err("bad fastmap pool magic: 0x%x, expected: 0x%x", + ubi_err(ubi, "bad fastmap pool magic: 0x%x, expected: 0x%x", be32_to_cpu(fmpl2->magic), UBI_FM_POOL_MAGIC); goto fail_bad; } @@ -612,25 +620,26 @@ fm->max_wl_pool_size = be16_to_cpu(fmpl2->max_size); if (pool_size > UBI_FM_MAX_POOL_SIZE || pool_size < 0) { - ubi_err("bad pool size: %i", pool_size); + ubi_err(ubi, "bad pool size: %i", pool_size); goto fail_bad; } if (wl_pool_size > UBI_FM_MAX_POOL_SIZE || wl_pool_size < 0) { - ubi_err("bad WL pool size: %i", wl_pool_size); + ubi_err(ubi, "bad WL pool size: %i", wl_pool_size); goto fail_bad; } if (fm->max_pool_size > UBI_FM_MAX_POOL_SIZE || fm->max_pool_size < 0) { - ubi_err("bad maximal pool size: %i", fm->max_pool_size); + ubi_err(ubi, "bad maximal pool size: %i", fm->max_pool_size); goto fail_bad; } if (fm->max_wl_pool_size > UBI_FM_MAX_POOL_SIZE || fm->max_wl_pool_size < 0) { - ubi_err("bad maximal WL pool size: %i", fm->max_wl_pool_size); + ubi_err(ubi, "bad maximal WL pool size: %i", + fm->max_wl_pool_size); goto fail_bad; } @@ -689,8 +698,7 @@ goto fail_bad; if (be32_to_cpu(fmvhdr->magic) != UBI_FM_VHDR_MAGIC) { - ubi_err("bad fastmap vol header magic: 0x%x, " \ - "expected: 0x%x", + ubi_err(ubi, "bad fastmap vol header magic: 0x%x, expected: 0x%x", be32_to_cpu(fmvhdr->magic), UBI_FM_VHDR_MAGIC); goto fail_bad; } @@ -715,8 +723,7 @@ goto fail_bad; if (be32_to_cpu(fm_eba->magic) != UBI_FM_EBA_MAGIC) { - ubi_err("bad fastmap EBA header magic: 0x%x, " \ - "expected: 0x%x", + ubi_err(ubi, "bad fastmap EBA header magic: 0x%x, expected: 0x%x", be32_to_cpu(fm_eba->magic), UBI_FM_EBA_MAGIC); goto fail_bad; } @@ -729,8 +736,10 @@ aeb = NULL; list_for_each_entry(tmp_aeb, &used, u.list) { - if (tmp_aeb->pnum == pnum) + if (tmp_aeb->pnum == pnum) { aeb = tmp_aeb; + break; + } } /* This can happen if a PEB is already in an EBA known @@ -779,7 +788,7 @@ int err; if (ubi_io_is_bad(ubi, tmp_aeb->pnum)) { - ubi_err("bad PEB in fastmap EBA orphan list"); + ubi_err(ubi, "bad PEB in fastmap EBA orphan list"); ret = UBI_BAD_FASTMAP; kfree(ech); goto fail; @@ -787,8 +796,8 @@ err = ubi_io_read_ec_hdr(ubi, tmp_aeb->pnum, ech, 0); if (err && err != UBI_IO_BITFLIPS) { - ubi_err("unable to read EC header! PEB:%i " \ - "err:%i", tmp_aeb->pnum, err); + ubi_err(ubi, "unable to read EC header! PEB:%i err:%i", + tmp_aeb->pnum, err); ret = err > 0 ? UBI_BAD_FASTMAP : err; kfree(ech); @@ -819,6 +828,10 @@ 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. @@ -834,6 +847,19 @@ fail_bad: ret = UBI_BAD_FASTMAP; fail: + list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &used, u.list) { + list_del(&tmp_aeb->u.list); + kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); + } + list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &eba_orphans, u.list) { + list_del(&tmp_aeb->u.list); + kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); + } + list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) { + list_del(&tmp_aeb->u.list); + kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); + } + return ret; } @@ -882,14 +908,14 @@ fm->to_be_tortured[0] = 1; if (be32_to_cpu(fmsb->magic) != UBI_FM_SB_MAGIC) { - ubi_err("bad super block magic: 0x%x, expected: 0x%x", + ubi_err(ubi, "bad super block magic: 0x%x, expected: 0x%x", be32_to_cpu(fmsb->magic), UBI_FM_SB_MAGIC); ret = UBI_BAD_FASTMAP; goto free_fm_sb; } if (fmsb->version != UBI_FM_FMT_VERSION) { - ubi_err("bad fastmap version: %i, expected: %i", + ubi_err(ubi, "bad fastmap version: %i, expected: %i", fmsb->version, UBI_FM_FMT_VERSION); ret = UBI_BAD_FASTMAP; goto free_fm_sb; @@ -897,15 +923,16 @@ used_blocks = be32_to_cpu(fmsb->used_blocks); if (used_blocks > UBI_FM_MAX_BLOCKS || used_blocks < 1) { - ubi_err("number of fastmap blocks is invalid: %i", used_blocks); + ubi_err(ubi, "number of fastmap blocks is invalid: %i", + used_blocks); ret = UBI_BAD_FASTMAP; goto free_fm_sb; } fm_size = ubi->leb_size * used_blocks; if (fm_size != ubi->fm_size) { - ubi_err("bad fastmap size: %zi, expected: %zi", fm_size, - ubi->fm_size); + ubi_err(ubi, "bad fastmap size: %zi, expected: %zi", + fm_size, ubi->fm_size); ret = UBI_BAD_FASTMAP; goto free_fm_sb; } @@ -923,6 +950,8 @@ } 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)) { @@ -932,7 +961,7 @@ ret = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); if (ret && ret != UBI_IO_BITFLIPS) { - ubi_err("unable to read fastmap block# %i EC (PEB: %i)", + ubi_err(ubi, "unable to read fastmap block# %i EC (PEB: %i)", i, pnum); if (ret > 0) ret = UBI_BAD_FASTMAP; @@ -940,25 +969,31 @@ } 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(ubi, "wrong image seq:%d instead of %d", + be32_to_cpu(ech->image_seq), ubi->image_seq); ret = UBI_BAD_FASTMAP; goto free_hdr; } ret = ubi_io_read_vid_hdr(ubi, pnum, vh, 0); if (ret && ret != UBI_IO_BITFLIPS) { - ubi_err("unable to read fastmap block# %i (PEB: %i)", + ubi_err(ubi, "unable to read fastmap block# %i (PEB: %i)", i, pnum); goto free_hdr; } if (i == 0) { if (be32_to_cpu(vh->vol_id) != UBI_FM_SB_VOLUME_ID) { - ubi_err("bad fastmap anchor vol_id: 0x%x," \ - " expected: 0x%x", + ubi_err(ubi, "bad fastmap anchor vol_id: 0x%x, expected: 0x%x", be32_to_cpu(vh->vol_id), UBI_FM_SB_VOLUME_ID); ret = UBI_BAD_FASTMAP; @@ -966,8 +1001,7 @@ } } else { if (be32_to_cpu(vh->vol_id) != UBI_FM_DATA_VOLUME_ID) { - ubi_err("bad fastmap data vol_id: 0x%x," \ - " expected: 0x%x", + ubi_err(ubi, "bad fastmap data vol_id: 0x%x, expected: 0x%x", be32_to_cpu(vh->vol_id), UBI_FM_DATA_VOLUME_ID); ret = UBI_BAD_FASTMAP; @@ -981,7 +1015,7 @@ ret = ubi_io_read(ubi, ubi->fm_buf + (ubi->leb_size * i), pnum, ubi->leb_start, ubi->leb_size); if (ret && ret != UBI_IO_BITFLIPS) { - ubi_err("unable to read fastmap block# %i (PEB: %i, " \ + ubi_err(ubi, "unable to read fastmap block# %i (PEB: %i, " "err: %i)", i, pnum, ret); goto free_hdr; } @@ -995,8 +1029,9 @@ fmsb2->data_crc = 0; crc = crc32(UBI_CRC32_INIT, ubi->fm_buf, fm_size); if (crc != tmp_crc) { - ubi_err("fastmap data CRC is invalid"); - ubi_err("CRC should be: 0x%x, calc: 0x%x", tmp_crc, crc); + ubi_err(ubi, "fastmap data CRC is invalid"); + ubi_err(ubi, "CRC should be: 0x%x, calc: 0x%x", + tmp_crc, crc); ret = UBI_BAD_FASTMAP; goto free_hdr; } @@ -1032,9 +1067,10 @@ ubi->fm = fm; ubi->fm_pool.max_size = ubi->fm->max_pool_size; ubi->fm_wl_pool.max_size = ubi->fm->max_wl_pool_size; - ubi_msg("attached by fastmap"); - ubi_msg("fastmap pool size: %d", ubi->fm_pool.max_size); - ubi_msg("fastmap WL pool size: %d", ubi->fm_wl_pool.max_size); + ubi_msg(ubi, "attached by fastmap"); + ubi_msg(ubi, "fastmap pool size: %d", ubi->fm_pool.max_size); + ubi_msg(ubi, "fastmap WL pool size: %d", + ubi->fm_wl_pool.max_size); ubi->fm_disabled = 0; ubi_free_vid_hdr(ubi, vh); @@ -1042,7 +1078,7 @@ out: mutex_unlock(&ubi->fm_mutex); if (ret == UBI_BAD_FASTMAP) - ubi_err("Attach by fastmap failed, doing a full scan!"); + ubi_err(ubi, "Attach by fastmap failed, doing a full scan!"); return ret; free_hdr: @@ -1238,7 +1274,7 @@ dbg_bld("writing fastmap SB to PEB %i", new_fm->e[0]->pnum); ret = ubi_io_write_vid_hdr(ubi, new_fm->e[0]->pnum, avhdr); if (ret) { - ubi_err("unable to write vid_hdr to fastmap SB!"); + ubi_err(ubi, "unable to write vid_hdr to fastmap SB!"); goto out_kfree; } @@ -1258,7 +1294,7 @@ new_fm->e[i]->pnum, be64_to_cpu(dvhdr->sqnum)); ret = ubi_io_write_vid_hdr(ubi, new_fm->e[i]->pnum, dvhdr); if (ret) { - ubi_err("unable to write vid_hdr to PEB %i!", + ubi_err(ubi, "unable to write vid_hdr to PEB %i!", new_fm->e[i]->pnum); goto out_kfree; } @@ -1268,7 +1304,7 @@ ret = ubi_io_write(ubi, fm_raw + (i * ubi->leb_size), new_fm->e[i]->pnum, ubi->leb_start, ubi->leb_size); if (ret) { - ubi_err("unable to write fastmap to PEB %i!", + ubi_err(ubi, "unable to write fastmap to PEB %i!", new_fm->e[i]->pnum); goto out_kfree; } @@ -1343,7 +1379,7 @@ 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 +1396,6 @@ 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; } @@ -1418,7 +1451,7 @@ ubi->fm = NULL; if (new_fm->used_blocks > UBI_FM_MAX_BLOCKS) { - ubi_err("fastmap too large"); + ubi_err(ubi, "fastmap too large"); ret = -ENOSPC; goto err; } @@ -1430,7 +1463,7 @@ if (!tmp_e && !old_fm) { int j; - ubi_err("could not get any free erase block"); + ubi_err(ubi, "could not get any free erase block"); for (j = 1; j < i; j++) ubi_wl_put_fm_peb(ubi, new_fm->e[j], j, 0); @@ -1446,7 +1479,7 @@ ubi_wl_put_fm_peb(ubi, new_fm->e[j], j, 0); - ubi_err("could not erase old fastmap PEB"); + ubi_err(ubi, "could not erase old fastmap PEB"); goto err; } @@ -1472,7 +1505,7 @@ ret = erase_block(ubi, old_fm->e[0]->pnum); if (ret < 0) { int i; - ubi_err("could not erase old anchor PEB"); + ubi_err(ubi, "could not erase old anchor PEB"); for (i = 1; i < new_fm->used_blocks; i++) ubi_wl_put_fm_peb(ubi, new_fm->e[i], @@ -1493,7 +1526,7 @@ } else { if (!tmp_e) { int i; - ubi_err("could not find any anchor PEB"); + ubi_err(ubi, "could not find any anchor PEB"); for (i = 1; i < new_fm->used_blocks; i++) ubi_wl_put_fm_peb(ubi, new_fm->e[i], i, 0); @@ -1523,13 +1556,13 @@ err: kfree(new_fm); - ubi_warn("Unable to write new fastmap, err=%i", ret); + ubi_warn(ubi, "Unable to write new fastmap, err=%i", ret); ret = 0; if (old_fm) { ret = invalidate_fastmap(ubi, old_fm); if (ret < 0) - ubi_err("Unable to invalidiate current fastmap!"); + ubi_err(ubi, "Unable to invalidiate current fastmap!"); else if (ret) ret = 0; }