diff options
author | Artem Bityutskiy <artem.bityutskiy@intel.com> | 2011-09-11 13:52:08 +0300 |
---|---|---|
committer | Artem Bityutskiy <artem.bityutskiy@intel.com> | 2011-09-19 07:52:49 +0300 |
commit | d9cbf6a5b3e6d535eed2e9b28257562ba9e2a515 (patch) | |
tree | 00a7e34e73f4abbceb8f78e1befc6dcd562ce327 | |
parent | bf01f2960ba82468b1b25f00e044fd0c3ee0770a (diff) |
ubiformat: handle write errors correctly
This issue was reported and analyzed by
Anton Olofsson <anol.martinsson@gmail.com>:
when ubiformat encounters a write error while flashing the UBI image (which may
come from a file of from stdout), it correctly marks the faulty eraseblock as
bad and skips it. However, it also incorrectly drops the data buffer which was
supposed to be written, and reads next block of data.
This patch fixes this issue - in case of a write error, we preserve the current
data and write it to the next eraseblock, instead of dropping it.
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@intel.com>
-rw-r--r-- | ubi-utils/ubiformat.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/ubi-utils/ubiformat.c b/ubi-utils/ubiformat.c index bfa1730..c396b09 100644 --- a/ubi-utils/ubiformat.c +++ b/ubi-utils/ubiformat.c @@ -442,7 +442,7 @@ static int mark_bad(const struct mtd_dev_info *mtd, struct ubi_scan_info *si, in static int flash_image(libmtd_t libmtd, const struct mtd_dev_info *mtd, const struct ubigen_info *ui, struct ubi_scan_info *si) { - int fd, img_ebs, eb, written_ebs = 0, divisor; + int fd, img_ebs, eb, written_ebs = 0, divisor, skip_data_read = 0; off_t st_size; fd = open_file(&st_size); @@ -501,12 +501,15 @@ static int flash_image(libmtd_t libmtd, const struct mtd_dev_info *mtd, continue; } - err = read_all(fd, buf, mtd->eb_size); - if (err) { - sys_errmsg("failed to read eraseblock %d from \"%s\"", - written_ebs, args.image); - goto out_close; + if (!skip_data_read) { + err = read_all(fd, buf, mtd->eb_size); + if (err) { + sys_errmsg("failed to read eraseblock %d from \"%s\"", + written_ebs, args.image); + goto out_close; + } } + skip_data_read = 0; if (args.override_ec) ec = args.ec; @@ -546,6 +549,13 @@ static int flash_image(libmtd_t libmtd, const struct mtd_dev_info *mtd, if (mark_bad(mtd, si, eb)) goto out_close; } + + /* + * We have to make sure that we do not read next block + * of data from the input image or stdin - we have to + * write buf first instead. + */ + skip_data_read = 1; continue; } if (++written_ebs >= img_ebs) |