aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/wbuf.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@cruncher.tec.linutronix.de>2006-05-29 08:56:39 -0400
committerThomas Gleixner <tglx@cruncher.tec.linutronix.de>2006-05-29 09:06:51 -0400
commit9a1fcdfd4bee27c418424cac47abf7c049541297 (patch)
tree5baa5f1e1d1a296a319bf6a5a4b636668c107e00 /fs/jffs2/wbuf.c
parent8593fbc68b0df1168995de76d1af38eb62fd6b62 (diff)
[MTD] NAND Signal that a bitflip was corrected by ECC
Return -EUCLEAN on read when a bitflip was detected and corrected, so the clients can react and eventually copy the affected block to a spare one. Make all in kernel users aware of the change. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'fs/jffs2/wbuf.c')
-rw-r--r--fs/jffs2/wbuf.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 1195d06d4373..a7f153f79ecb 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -296,10 +296,11 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
296 /* Do the read... */ 296 /* Do the read... */
297 ret = c->mtd->read(c->mtd, start, c->wbuf_ofs - start, &retlen, buf); 297 ret = c->mtd->read(c->mtd, start, c->wbuf_ofs - start, &retlen, buf);
298 298
299 if (ret == -EBADMSG && retlen == c->wbuf_ofs - start) { 299 /* ECC recovered ? */
300 /* ECC recovered */ 300 if ((ret == -EUCLEAN || ret == -EBADMSG) &&
301 (retlen == c->wbuf_ofs - start))
301 ret = 0; 302 ret = 0;
302 } 303
303 if (ret || retlen != c->wbuf_ofs - start) { 304 if (ret || retlen != c->wbuf_ofs - start) {
304 printk(KERN_CRIT "Old data are already lost in wbuf recovery. Data loss ensues.\n"); 305 printk(KERN_CRIT "Old data are already lost in wbuf recovery. Data loss ensues.\n");
305 306
@@ -908,20 +909,21 @@ int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *re
908 down_read(&c->wbuf_sem); 909 down_read(&c->wbuf_sem);
909 ret = c->mtd->read(c->mtd, ofs, len, retlen, buf); 910 ret = c->mtd->read(c->mtd, ofs, len, retlen, buf);
910 911
911 if ( (ret == -EBADMSG) && (*retlen == len) ) { 912 if ( (ret == -EBADMSG || ret == -EUCLEAN) && (*retlen == len) ) {
912 printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n", 913 if (ret == -EBADMSG)
913 len, ofs); 914 printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx)"
915 " returned ECC error\n", len, ofs);
914 /* 916 /*
915 * We have the raw data without ECC correction in the buffer, maybe 917 * We have the raw data without ECC correction in the buffer,
916 * we are lucky and all data or parts are correct. We check the node. 918 * maybe we are lucky and all data or parts are correct. We
917 * If data are corrupted node check will sort it out. 919 * check the node. If data are corrupted node check will sort
918 * We keep this block, it will fail on write or erase and the we 920 * it out. We keep this block, it will fail on write or erase
919 * mark it bad. Or should we do that now? But we should give him a chance. 921 * and the we mark it bad. Or should we do that now? But we
920 * Maybe we had a system crash or power loss before the ecc write or 922 * should give him a chance. Maybe we had a system crash or
921 * a erase was completed. 923 * power loss before the ecc write or a erase was completed.
922 * So we return success. :) 924 * So we return success. :)
923 */ 925 */
924 ret = 0; 926 ret = 0;
925 } 927 }
926 928
927 /* if no writebuffer available or write buffer empty, return */ 929 /* if no writebuffer available or write buffer empty, return */
@@ -943,7 +945,7 @@ int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *re
943 orbf = (c->wbuf_ofs - ofs); /* offset in read buffer */ 945 orbf = (c->wbuf_ofs - ofs); /* offset in read buffer */
944 if (orbf > len) /* is write beyond write buffer ? */ 946 if (orbf > len) /* is write beyond write buffer ? */
945 goto exit; 947 goto exit;
946 lwbf = len - orbf; /* number of bytes to copy */ 948 lwbf = len - orbf; /* number of bytes to copy */
947 if (lwbf > c->wbuf_len) 949 if (lwbf > c->wbuf_len)
948 lwbf = c->wbuf_len; 950 lwbf = c->wbuf_len;
949 } 951 }