[PATCH 1/2] ubiformat: Factor out a write_eraseblock function
Sascha Hauer
s.hauer at pengutronix.de
Wed Oct 22 00:48:30 PDT 2014
The format and the flash_image function share some code. Factor out a
write_erasblock function. This makes the code a bit shorter and makes
it easy to skip flashing a block for fastmap support.
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
ubi-utils/ubiformat.c | 241 +++++++++++++++++++++++---------------------------
1 file changed, 111 insertions(+), 130 deletions(-)
diff --git a/ubi-utils/ubiformat.c b/ubi-utils/ubiformat.c
index 21409ca..2269cdf 100644
--- a/ubi-utils/ubiformat.c
+++ b/ubi-utils/ubiformat.c
@@ -415,6 +415,105 @@ static int mark_bad(const struct mtd_dev_info *mtd, struct ubi_scan_info *si, in
return consecutive_bad_check(eb);
}
+/*
+ * Write a single eraseblock. When buf is given its content is written to the
+ * eraseblock. When buf is NULL only the ec header is written. Returns 0 on
+ * success, 1 if this block should be skipped or -1 when an error occured.
+ */
+static int write_eraseblock(libmtd_t libmtd, const struct mtd_dev_info *mtd,
+ const struct ubigen_info *ui, struct ubi_scan_info *si, int eb,
+ void *buf, int written_ebs)
+{
+ int err, write_size;
+ struct ubi_ec_hdr *hdr = NULL;
+ long long ec;
+
+ if (args.override_ec)
+ ec = args.ec;
+ else if (si->ec[eb] <= EC_MAX)
+ ec = si->ec[eb] + 1;
+ else
+ ec = si->mean_ec;
+
+ if (args.verbose) {
+ normsg_cont("eraseblock %d: erase", eb);
+ fflush(stdout);
+ }
+
+ err = mtd_erase(libmtd, mtd, args.node_fd, eb);
+ if (err) {
+ if (!args.quiet)
+ printf("\n");
+
+ sys_errmsg("failed to erase eraseblock %d", eb);
+ if (errno != EIO)
+ return -1;
+
+ if (mark_bad(mtd, si, eb))
+ return -1;
+
+ return 1;
+ }
+
+ if (buf) {
+ write_size = mtd->eb_size;
+ err = change_ech((struct ubi_ec_hdr *)buf, ui->image_seq, ec);
+ if (err) {
+ errmsg("bad EC header at eraseblock %d of \"%s\"",
+ written_ebs, args.image);
+ return -1;
+ }
+ write_size = drop_ffs(mtd, buf, mtd->eb_size);
+ } else {
+ write_size = UBI_EC_HDR_SIZE + mtd->subpage_size - 1;
+ write_size /= mtd->subpage_size;
+ write_size *= mtd->subpage_size;
+
+ hdr = malloc(write_size);
+ if (!hdr)
+ return sys_errmsg("cannot allocate %d bytes of memory", write_size);
+ memset(hdr, 0xFF, write_size);
+
+ ubigen_init_ec_hdr(ui, hdr, ec);
+
+ buf = hdr;
+ }
+
+ if (args.verbose) {
+ printf(", write %sEC %lld\n", hdr ? "" : "data, ", ec);
+ fflush(stdout);
+ }
+
+ err = mtd_write(libmtd, mtd, args.node_fd, eb, 0, buf,
+ write_size, NULL, 0, 0);
+ if (err) {
+ if (!args.quiet && !args.verbose)
+ printf("\n");
+ sys_errmsg("cannot write eraseblock %d", eb);
+
+ if (errno != EIO) {
+ if (args.subpage_size != mtd->min_io_size)
+ normsg("may be sub-page size is "
+ "incorrect?");
+ err = -1;
+ goto out;
+ }
+
+ err = mtd_torture(libmtd, mtd, args.node_fd, eb);
+ if (err) {
+ if (mark_bad(mtd, si, eb)) {
+ err = -1;
+ goto out;
+ }
+ }
+ err = 1;
+ }
+
+out:
+ free(hdr);
+ return err;
+}
+
static int flash_image(libmtd_t libmtd, const struct mtd_dev_info *mtd,
const struct ubigen_info *ui, struct ubi_scan_info *si)
{
@@ -442,9 +541,8 @@ static int flash_image(libmtd_t libmtd, const struct mtd_dev_info *mtd,
verbose(args.verbose, "will write %d eraseblocks", img_ebs);
divisor = img_ebs;
for (eb = 0; eb < mtd->eb_cnt; eb++) {
- int err, new_len;
+ int err;
char buf[mtd->eb_size];
- long long ec;
if (!args.quiet && !args.verbose) {
printf("\r" PROGRAM_NAME ": flashing eraseblock %d -- %2lld %% complete ",
@@ -457,26 +555,6 @@ static int flash_image(libmtd_t libmtd, const struct mtd_dev_info *mtd,
continue;
}
- if (args.verbose) {
- normsg_cont("eraseblock %d: erase", eb);
- fflush(stdout);
- }
-
- err = mtd_erase(libmtd, mtd, args.node_fd, eb);
- if (err) {
- if (!args.quiet)
- printf("\n");
- sys_errmsg("failed to erase eraseblock %d", eb);
-
- if (errno != EIO)
- goto out_close;
-
- if (mark_bad(mtd, si, eb))
- goto out_close;
-
- continue;
- }
-
if (!skip_data_read) {
err = read_all(fd, buf, mtd->eb_size);
if (err) {
@@ -487,46 +565,11 @@ static int flash_image(libmtd_t libmtd, const struct mtd_dev_info *mtd,
}
skip_data_read = 0;
- if (args.override_ec)
- ec = args.ec;
- else if (si->ec[eb] <= EC_MAX)
- ec = si->ec[eb] + 1;
- else
- ec = si->mean_ec;
-
- if (args.verbose) {
- printf(", change EC to %lld", ec);
- fflush(stdout);
- }
-
- err = change_ech((struct ubi_ec_hdr *)buf, ui->image_seq, ec);
- if (err) {
- errmsg("bad EC header at eraseblock %d of \"%s\"",
- written_ebs, args.image);
+ err = write_eraseblock(libmtd, mtd, ui, si, eb, buf, written_ebs);
+ if (err < 0)
goto out_close;
- }
-
- if (args.verbose) {
- printf(", write data\n");
- fflush(stdout);
- }
-
- new_len = drop_ffs(mtd, buf, mtd->eb_size);
-
- err = mtd_write(libmtd, mtd, args.node_fd, eb, 0, buf, new_len,
- NULL, 0, 0);
- if (err) {
- sys_errmsg("cannot write eraseblock %d", eb);
-
- if (errno != EIO)
- goto out_close;
-
- err = mtd_torture(libmtd, mtd, args.node_fd, eb);
- if (err) {
- if (mark_bad(mtd, si, eb))
- goto out_close;
- }
+ if (err > 0) {
/*
* We have to make sure that we do not read next block
* of data from the input image or stdin - we have to
@@ -553,20 +596,11 @@ static int format(libmtd_t libmtd, const struct mtd_dev_info *mtd,
const struct ubigen_info *ui, struct ubi_scan_info *si,
int start_eb, int novtbl)
{
- int eb, err, write_size;
- struct ubi_ec_hdr *hdr;
+ int eb, err;
struct ubi_vtbl_record *vtbl;
int eb1 = -1, eb2 = -1;
long long ec1 = -1, ec2 = -1;
- write_size = UBI_EC_HDR_SIZE + mtd->subpage_size - 1;
- write_size /= mtd->subpage_size;
- write_size *= mtd->subpage_size;
- hdr = malloc(write_size);
- if (!hdr)
- return sys_errmsg("cannot allocate %d bytes of memory", write_size);
- memset(hdr, 0xFF, write_size);
-
for (eb = start_eb; eb < mtd->eb_cnt; eb++) {
long long ec;
@@ -579,33 +613,6 @@ static int format(libmtd_t libmtd, const struct mtd_dev_info *mtd,
if (si->ec[eb] == EB_BAD)
continue;
- if (args.override_ec)
- ec = args.ec;
- else if (si->ec[eb] <= EC_MAX)
- ec = si->ec[eb] + 1;
- else
- ec = si->mean_ec;
- ubigen_init_ec_hdr(ui, hdr, ec);
-
- if (args.verbose) {
- normsg_cont("eraseblock %d: erase", eb);
- fflush(stdout);
- }
-
- err = mtd_erase(libmtd, mtd, args.node_fd, eb);
- if (err) {
- if (!args.quiet)
- printf("\n");
-
- sys_errmsg("failed to erase eraseblock %d", eb);
- if (errno != EIO)
- goto out_free;
-
- if (mark_bad(mtd, si, eb))
- goto out_free;
- continue;
- }
-
if ((eb1 == -1 || eb2 == -1) && !novtbl) {
if (eb1 == -1) {
eb1 = eb;
@@ -619,33 +626,9 @@ static int format(libmtd_t libmtd, const struct mtd_dev_info *mtd,
continue;
}
- if (args.verbose) {
- printf(", write EC %lld\n", ec);
- fflush(stdout);
- }
-
- err = mtd_write(libmtd, mtd, args.node_fd, eb, 0, hdr,
- write_size, NULL, 0, 0);
- if (err) {
- if (!args.quiet && !args.verbose)
- printf("\n");
- sys_errmsg("cannot write EC header (%d bytes buffer) to eraseblock %d",
- write_size, eb);
-
- if (errno != EIO) {
- if (args.subpage_size != mtd->min_io_size)
- normsg("may be sub-page size is incorrect?");
- goto out_free;
- }
-
- err = mtd_torture(libmtd, mtd, args.node_fd, eb);
- if (err) {
- if (mark_bad(mtd, si, eb))
- goto out_free;
- }
- continue;
-
- }
+ err = write_eraseblock(libmtd, mtd, ui, si, eb, NULL, 0);
+ if (err < 0)
+ return -1;
}
if (!args.quiet && !args.verbose)
@@ -654,28 +637,26 @@ static int format(libmtd_t libmtd, const struct mtd_dev_info *mtd,
if (!novtbl) {
if (eb1 == -1 || eb2 == -1) {
errmsg("no eraseblocks for volume table");
- goto out_free;
+ goto out;
}
verbose(args.verbose, "write volume table to eraseblocks %d and %d", eb1, eb2);
vtbl = ubigen_create_empty_vtbl(ui);
if (!vtbl)
- goto out_free;
+ goto out;
err = ubigen_write_layout_vol(ui, eb1, eb2, ec1, ec2, vtbl,
args.node_fd);
free(vtbl);
if (err) {
errmsg("cannot write layout volume");
- goto out_free;
+ goto out;
}
}
- free(hdr);
return 0;
-out_free:
- free(hdr);
+out:
return -1;
}
--
2.1.1
More information about the linux-mtd
mailing list