diff options
Diffstat (limited to 'drivers/mtd/ubi/scan.c')
-rw-r--r-- | drivers/mtd/ubi/scan.c | 136 |
1 files changed, 47 insertions, 89 deletions
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 96d410e106a..967bb4406df 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -19,9 +19,9 @@ */ /* - * UBI scanning unit. + * UBI scanning sub-system. * - * This unit is responsible for scanning the flash media, checking UBI + * This sub-system is responsible for scanning the flash media, checking UBI * headers and providing complete information about the UBI flash image. * * The scanning information is represented by a &struct ubi_scan_info' object. @@ -93,8 +93,7 @@ static int add_to_list(struct ubi_scan_info *si, int pnum, int ec, } /** - * validate_vid_hdr - check that volume identifier header is correct and - * consistent. + * validate_vid_hdr - check volume identifier header. * @vid_hdr: the volume identifier header to check * @sv: information about the volume this logical eraseblock belongs to * @pnum: physical eraseblock number the VID header came from @@ -103,7 +102,7 @@ static int add_to_list(struct ubi_scan_info *si, int pnum, int ec, * non-zero if an inconsistency was found and zero if not. * * Note, UBI does sanity check of everything it reads from the flash media. - * Most of the checks are done in the I/O unit. Here we check that the + * Most of the checks are done in the I/O sub-system. Here we check that the * information in the VID header is consistent to the information in other VID * headers of the same volume. */ @@ -247,45 +246,21 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_scan_leb *seb, struct ubi_vid_hdr *vh = NULL; unsigned long long sqnum2 = be64_to_cpu(vid_hdr->sqnum); - if (seb->sqnum == 0 && sqnum2 == 0) { - long long abs, v1 = seb->leb_ver, v2 = be32_to_cpu(vid_hdr->leb_ver); - + if (sqnum2 == seb->sqnum) { /* - * UBI constantly increases the logical eraseblock version - * number and it can overflow. Thus, we have to bear in mind - * that versions that are close to %0xFFFFFFFF are less then - * versions that are close to %0. - * - * The UBI WL unit guarantees that the number of pending tasks - * is not greater then %0x7FFFFFFF. So, if the difference - * between any two versions is greater or equivalent to - * %0x7FFFFFFF, there was an overflow and the logical - * eraseblock with lower version is actually newer then the one - * with higher version. - * - * FIXME: but this is anyway obsolete and will be removed at - * some point. + * This must be a really ancient UBI image which has been + * created before sequence numbers support has been added. At + * that times we used 32-bit LEB versions stored in logical + * eraseblocks. That was before UBI got into mainline. We do not + * support these images anymore. Well, those images will work + * still work, but only if no unclean reboots happened. */ - dbg_bld("using old crappy leb_ver stuff"); - - if (v1 == v2) { - ubi_err("PEB %d and PEB %d have the same version %lld", - seb->pnum, pnum, v1); - return -EINVAL; - } - - abs = v1 - v2; - if (abs < 0) - abs = -abs; + ubi_err("unsupported on-flash UBI format\n"); + return -EINVAL; + } - if (abs < 0x7FFFFFFF) - /* Non-overflow situation */ - second_is_newer = (v2 > v1); - else - second_is_newer = (v2 < v1); - } else - /* Obviously the LEB with lower sequence counter is older */ - second_is_newer = sqnum2 > seb->sqnum; + /* Obviously the LEB with lower sequence counter is older */ + second_is_newer = !!(sqnum2 > seb->sqnum); /* * Now we know which copy is newer. If the copy flag of the PEB with @@ -293,7 +268,7 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_scan_leb *seb, * check data CRC. For the second PEB we already have the VID header, * for the first one - we'll need to re-read it from flash. * - * FIXME: this may be optimized so that we wouldn't read twice. + * Note: this may be optimized so that we wouldn't read twice. */ if (second_is_newer) { @@ -379,8 +354,7 @@ out_free_vidh: } /** - * ubi_scan_add_used - add information about a physical eraseblock to the - * scanning information. + * ubi_scan_add_used - add physical eraseblock to the scanning information. * @ubi: UBI device description object * @si: scanning information * @pnum: the physical eraseblock number @@ -400,7 +374,6 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, int bitflips) { int err, vol_id, lnum; - uint32_t leb_ver; unsigned long long sqnum; struct ubi_scan_volume *sv; struct ubi_scan_leb *seb; @@ -409,10 +382,9 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, vol_id = be32_to_cpu(vid_hdr->vol_id); lnum = be32_to_cpu(vid_hdr->lnum); sqnum = be64_to_cpu(vid_hdr->sqnum); - leb_ver = be32_to_cpu(vid_hdr->leb_ver); - dbg_bld("PEB %d, LEB %d:%d, EC %d, sqnum %llu, ver %u, bitflips %d", - pnum, vol_id, lnum, ec, sqnum, leb_ver, bitflips); + dbg_bld("PEB %d, LEB %d:%d, EC %d, sqnum %llu, bitflips %d", + pnum, vol_id, lnum, ec, sqnum, bitflips); sv = add_volume(si, vol_id, pnum, vid_hdr); if (IS_ERR(sv) < 0) @@ -445,25 +417,20 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, */ dbg_bld("this LEB already exists: PEB %d, sqnum %llu, " - "LEB ver %u, EC %d", seb->pnum, seb->sqnum, - seb->leb_ver, seb->ec); - - /* - * Make sure that the logical eraseblocks have different - * versions. Otherwise the image is bad. - */ - if (seb->leb_ver == leb_ver && leb_ver != 0) { - ubi_err("two LEBs with same version %u", leb_ver); - ubi_dbg_dump_seb(seb, 0); - ubi_dbg_dump_vid_hdr(vid_hdr); - return -EINVAL; - } + "EC %d", seb->pnum, seb->sqnum, seb->ec); /* * Make sure that the logical eraseblocks have different * sequence numbers. Otherwise the image is bad. * - * FIXME: remove 'sqnum != 0' check when leb_ver is removed. + * However, if the sequence number is zero, we assume it must + * be an ancient UBI image from the era when UBI did not have + * sequence numbers. We still can attach these images, unless + * there is a need to distinguish between old and new + * eraseblocks, in which case we'll refuse the image in + * 'compare_lebs()'. In other words, we attach old clean + * images, but refuse attaching old images with duplicated + * logical eraseblocks because there was an unclean reboot. */ if (seb->sqnum == sqnum && sqnum != 0) { ubi_err("two LEBs with same sequence number %llu", @@ -503,7 +470,6 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, seb->pnum = pnum; seb->scrub = ((cmp_res & 2) || bitflips); seb->sqnum = sqnum; - seb->leb_ver = leb_ver; if (sv->highest_lnum == lnum) sv->last_data_size = @@ -540,7 +506,6 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, seb->lnum = lnum; seb->sqnum = sqnum; seb->scrub = bitflips; - seb->leb_ver = leb_ver; if (sv->highest_lnum <= lnum) { sv->highest_lnum = lnum; @@ -554,8 +519,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, } /** - * ubi_scan_find_sv - find information about a particular volume in the - * scanning information. + * ubi_scan_find_sv - find volume in the scanning information. * @si: scanning information * @vol_id: the requested volume ID * @@ -584,8 +548,7 @@ struct ubi_scan_volume *ubi_scan_find_sv(const struct ubi_scan_info *si, } /** - * ubi_scan_find_seb - find information about a particular logical - * eraseblock in the volume scanning information. + * ubi_scan_find_seb - find LEB in the volume scanning information. * @sv: a pointer to the volume scanning information * @lnum: the requested logical eraseblock * @@ -645,9 +608,9 @@ void ubi_scan_rm_volume(struct ubi_scan_info *si, struct ubi_scan_volume *sv) * * This function erases physical eraseblock 'pnum', and writes the erase * counter header to it. This function should only be used on UBI device - * initialization stages, when the EBA unit had not been yet initialized. This - * function returns zero in case of success and a negative error code in case - * of failure. + * initialization stages, when the EBA sub-system had not been yet initialized. + * This function returns zero in case of success and a negative error code in + * case of failure. */ int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_scan_info *si, int pnum, int ec) @@ -687,9 +650,10 @@ out_free: * @si: scanning information * * This function returns a free physical eraseblock. It is supposed to be - * called on the UBI initialization stages when the wear-leveling unit is not - * initialized yet. This function picks a physical eraseblocks from one of the - * lists, writes the EC header if it is needed, and removes it from the list. + * called on the UBI initialization stages when the wear-leveling sub-system is + * not initialized yet. This function picks a physical eraseblocks from one of + * the lists, writes the EC header if it is needed, and removes it from the + * list. * * This function returns scanning physical eraseblock information in case of * success and an error code in case of failure. @@ -742,8 +706,7 @@ struct ubi_scan_leb *ubi_scan_get_free_peb(struct ubi_device *ubi, } /** - * process_eb - read UBI headers, check them and add corresponding data - * to the scanning information. + * process_eb - read, check UBI headers, and add them to scanning information. * @ubi: UBI device description object * @si: scanning information * @pnum: the physical eraseblock number @@ -751,7 +714,8 @@ struct ubi_scan_leb *ubi_scan_get_free_peb(struct ubi_device *ubi, * This function returns a zero if the physical eraseblock was successfully * handled and a negative error code in case of failure. */ -static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum) +static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, + int pnum) { long long uninitialized_var(ec); int err, bitflips = 0, vol_id, ec_corr = 0; @@ -764,8 +728,9 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum return err; else if (err) { /* - * FIXME: this is actually duty of the I/O unit to initialize - * this, but MTD does not provide enough information. + * FIXME: this is actually duty of the I/O sub-system to + * initialize this, but MTD does not provide enough + * information. */ si->bad_peb_count += 1; return 0; @@ -930,7 +895,7 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) for (pnum = 0; pnum < ubi->peb_count; pnum++) { cond_resched(); - dbg_msg("process PEB %d", pnum); + dbg_gen("process PEB %d", pnum); err = process_eb(ubi, si, pnum); if (err < 0) goto out_vidh; @@ -1079,8 +1044,7 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si) #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID /** - * paranoid_check_si - check if the scanning information is correct and - * consistent. + * paranoid_check_si - check the scanning information. * @ubi: UBI device description object * @si: scanning information * @@ -1265,11 +1229,6 @@ static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si) ubi_err("bad data_pad %d", sv->data_pad); goto bad_vid_hdr; } - - if (seb->leb_ver != be32_to_cpu(vidh->leb_ver)) { - ubi_err("bad leb_ver %u", seb->leb_ver); - goto bad_vid_hdr; - } } if (!last_seb) @@ -1299,8 +1258,7 @@ static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si) if (err < 0) { kfree(buf); return err; - } - else if (err) + } else if (err) buf[pnum] = 1; } |