| Upstream-Status: Pending |
| From patchwork Mon Aug 8 08:16:43 2011 |
| Content-Type: text/plain; charset="utf-8" |
| MIME-Version: 1.0 |
| Content-Transfer-Encoding: 7bit |
| Subject: mtd-utils: fix corrupt cleanmarker with flash_erase -j command |
| Date: Sun, 07 Aug 2011 22:16:43 -0000 |
| From: b35362@freescale.com |
| X-Patchwork-Id: 108873 |
| Message-Id: <1312791403-13473-1-git-send-email-b35362@freescale.com> |
| To: <dwmw2@infradead.org> |
| Cc: Liu Shuo <b35362@freescale.com>, Artem.Bityutskiy@nokia.com, |
| Li Yang <leoli@freescale.com>, linux-mtd@lists.infradead.org |
| |
| From: Liu Shuo <b35362@freescale.com> |
| |
| Flash_erase -j should fill discrete freeoob areas with required bytes |
| of JFFS2 cleanmarker in jffs2_check_nand_cleanmarker(). Not just fill |
| the first freeoob area. |
| |
| The below is the result without this workaround: |
| |
| JFFS2: Erase block at 0x00000000 is not formatted. It will be erased |
| JFFS2: Erase block at 0x00004000 is not formatted. It will be erased |
| JFFS2: Erase block at 0x00008000 is not formatted. It will be erased |
| JFFS2: Erase block at 0x0000c000 is not formatted. It will be erased |
| JFFS2: Erase block at 0x00010000 is not formatted. It will be erased |
| JFFS2: Erase block at 0x00014000 is not formatted. It will be erased |
| JFFS2: Erase block at 0x00018000 is not formatted. It will be erased |
| JFFS2: Erase block at 0x0001c000 is not formatted. It will be erased |
| JFFS2: Erase block at 0x00020000 is not formatted. It will be erased |
| JFFS2: Erase block at 0x00024000 is not formatted. It will be erased |
| JFFS2: Erase block at 0x00028000 is not formatted. It will be erased |
| ... |
| |
| Signed-off-by: Liu Shuo <b35362@freescale.com> |
| Signed-off-by: Li Yang <leoli@freescale.com> |
| |
| Updated for the new version |
| |
| Signed-off-by: Robert Yang <liezhi.yang@windriver.com> |
| |
| --- |
| v2 : get length of availble freeoob bytes from oobinfo information, |
| not use the ioctl ECCGETLAYOUT which is being deprecated. |
| |
| flash_erase.c | 46 +++++++++++++++++++++++++++++++++++++++------- |
| 1 files changed, 39 insertions(+), 7 deletions(-) |
| |
| diff --git a/flash_erase.c b/flash_erase.c |
| index 933373a..4b9d84b 100644 |
| --- a/flash_erase.c |
| +++ b/flash_erase.c |
| @@ -99,6 +99,7 @@ int main(int argc, char *argv[]) |
| bool isNAND; |
| int error = 0; |
| off_t offset = 0; |
| + void *oob_data = NULL; |
| |
| /* |
| * Process user arguments |
| @@ -201,15 +202,43 @@ int main(int argc, char *argv[]) |
| if (ioctl(fd, MEMGETOOBSEL, &oobinfo) != 0) |
| return sys_errmsg("%s: unable to get NAND oobinfo", mtd_device); |
| |
| + cleanmarker.totlen = cpu_to_je32(8); |
| /* Check for autoplacement */ |
| if (oobinfo.useecc == MTD_NANDECC_AUTOPLACE) { |
| - /* Get the position of the free bytes */ |
| - if (!oobinfo.oobfree[0][1]) |
| + struct nand_ecclayout_user ecclayout; |
| + int i, oobavail; |
| + |
| + for (i = 0, oobavail = 0; oobinfo.oobfree[i][1]; i++) |
| + oobavail += oobinfo.oobfree[i][1]; |
| + |
| + if (!oobavail) |
| return errmsg(" Eeep. Autoplacement selected and no empty space in oob"); |
| + |
| + /* Get the position of the free bytes */ |
| clmpos = oobinfo.oobfree[0][0]; |
| - clmlen = oobinfo.oobfree[0][1]; |
| - if (clmlen > 8) |
| - clmlen = 8; |
| + clmlen = MIN(oobavail, 8); |
| + |
| + if (oobinfo.oobfree[0][1] < 8 && oobavail >= 8) { |
| + int left, n, last = 0; |
| + void *cm; |
| + |
| + oob_data = malloc(mtd.oob_size); |
| + if (!oob_data) |
| + return -ENOMEM; |
| + |
| + memset(oob_data, 0xff, mtd.oob_size); |
| + cm = &cleanmarker; |
| + for (i = 0, left = clmlen; left ; i++) { |
| + n = MIN(left, oobinfo.oobfree[i][1]); |
| + memcpy(oob_data + oobinfo.oobfree[i][0], |
| + cm, n); |
| + left -= n; |
| + cm += n; |
| + last = oobinfo.oobfree[i][0] + n; |
| + } |
| + |
| + clmlen = last - clmpos; |
| + } |
| } else { |
| /* Legacy mode */ |
| switch (mtd.oob_size) { |
| @@ -227,7 +256,6 @@ int main(int argc, char *argv[]) |
| break; |
| } |
| } |
| - cleanmarker.totlen = cpu_to_je32(8); |
| } |
| cleanmarker.hdr_crc = cpu_to_je32(mtd_crc32(0, &cleanmarker, sizeof(cleanmarker) - 4)); |
| } |
| @@ -276,7 +304,8 @@ int main(int argc, char *argv[]) |
| |
| /* write cleanmarker */ |
| if (isNAND) { |
| - if (mtd_write_oob(mtd_desc, &mtd, fd, (uint64_t)offset + clmpos, clmlen, &cleanmarker) != 0) { |
| + void *data = oob_data ? oob_data + clmpos : &cleanmarker; |
| + if (mtd_write_oob(mtd_desc, &mtd, fd, (uint64_t)offset + clmpos, clmlen, data) != 0) { |
| sys_errmsg("%s: MTD writeoob failure", mtd_device); |
| continue; |
| } |
| @@ -291,5 +320,8 @@ int main(int argc, char *argv[]) |
| show_progress(&mtd, offset, eb, eb_start, eb_cnt); |
| bareverbose(!quiet, "\n"); |
| |
| + if (oob_data) |
| + free(oob_data); |
| + |
| return 0; |
| } |