summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2019-07-15 15:33:31 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2019-07-16 09:04:40 +0200
commit84a0eccd41ee6866788fb641cce6ff82728af316 (patch)
tree128c15cfee7635d36271e328daeea216127df2ab /common
parent3b68dbcbfce830bdf91f50943e5ee41463717abf (diff)
downloadbarebox-84a0eccd41ee6866788fb641cce6ff82728af316.tar.gz
barebox-84a0eccd41ee6866788fb641cce6ff82728af316.tar.xz
ubiformat: handle write errors correctly
This is a barebox adoption of mtd-utils commit d9cbf6a ("ubiformat: handle write errors correctly"): | 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: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'common')
-rw-r--r--common/ubiformat.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/common/ubiformat.c b/common/ubiformat.c
index 4f0df6fd5c..655c5323ba 100644
--- a/common/ubiformat.c
+++ b/common/ubiformat.c
@@ -188,6 +188,7 @@ static int flash_image(struct ubiformat_args *args, struct mtd_info *mtd,
const struct ubigen_info *ui, struct ubi_scan_info *si)
{
int fd = 0, img_ebs, eb, written_ebs = 0, ret = -1, eb_cnt;
+ int skip_data_read = 0;
off_t st_size;
char *buf = NULL;
uint64_t lastprint = 0;
@@ -266,17 +267,20 @@ static int flash_image(struct ubiformat_args *args, struct mtd_info *mtd,
continue;
}
- if (args->image) {
- err = read_full(fd, buf, mtd->erasesize);
- if (err < 0) {
- sys_errmsg("failed to read eraseblock %d from image",
- written_ebs);
- goto out_close;
+ if (!skip_data_read) {
+ if (args->image) {
+ err = read_full(fd, buf, mtd->erasesize);
+ if (err < 0) {
+ sys_errmsg("failed to read eraseblock %d from image",
+ written_ebs);
+ goto out_close;
+ }
+ } else {
+ memcpy(buf, inbuf, mtd->erasesize);
+ inbuf += mtd->erasesize;
}
- } else {
- memcpy(buf, inbuf, mtd->erasesize);
- inbuf += mtd->erasesize;
}
+ skip_data_read = 0;
if (args->override_ec)
ec = args->ec;
@@ -318,6 +322,13 @@ static int flash_image(struct ubiformat_args *args, struct mtd_info *mtd,
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)