From patchwork Thu Apr 21 17:17:07 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Matthieu CASTET X-Patchwork-Id: 92430 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [18.85.46.34]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id CEC9FB6F47 for ; Fri, 22 Apr 2011 03:19:08 +1000 (EST) Received: from canuck.infradead.org ([2001:4978:20e::1]) by bombadil.infradead.org with esmtps (Exim 4.72 #1 (Red Hat Linux)) id 1QCxVi-0004Im-9p; Thu, 21 Apr 2011 17:17:46 +0000 Received: from localhost ([127.0.0.1] helo=canuck.infradead.org) by canuck.infradead.org with esmtp (Exim 4.72 #1 (Red Hat Linux)) id 1QCxVg-0003Jz-HG; Thu, 21 Apr 2011 17:17:44 +0000 Received: from co202.xi-lite.net ([149.6.83.202]) by canuck.infradead.org with esmtp (Exim 4.72 #1 (Red Hat Linux)) id 1QCxVe-0003Jg-1p for linux-mtd@lists.infradead.org; Thu, 21 Apr 2011 17:17:42 +0000 Received: from ONYX.xi-lite.lan (unknown [193.34.35.244]) by co202.xi-lite.net (Postfix) with ESMTPS id A8BC8260180 for ; Thu, 21 Apr 2011 20:52:46 +0200 (CEST) Received: from [172.20.223.18] (84.14.91.202) by mail.xi-lite.com (193.34.32.105) with Microsoft SMTP Server (TLS) id 8.1.336.0; Thu, 21 Apr 2011 18:17:03 +0100 Message-ID: <4DB06693.5000100@parrot.com> Date: Thu, 21 Apr 2011 19:17:07 +0200 From: Matthieu CASTET User-Agent: Thunderbird 2.0.0.24 (X11/20100228) MIME-Version: 1.0 To: Matthieu CASTET Subject: Re: bbt and bitflip References: <4DB033E4.6030105@parrot.com> In-Reply-To: <4DB033E4.6030105@parrot.com> X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20110421_131742_247940_F4FE1118 X-CRM114-Status: GOOD ( 17.23 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.3.1 on canuck.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- Cc: "linux-mtd@lists.infradead.org" X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Matthieu CASTET a écrit : > Hi, > > the current bad block table implementation doesn't seem robust against bit flip. > > at boot we call : > - search_read_bbts which scan for bbt using oob pattern. > - check_create > -- read_abs_bbt > --- read_bbt which ignore ecc bit flip/error > > So if bit flip happen in BBT, we never scrub it. > And if bit flip accumulate and we can't correct it anymore, the code will parse > the corrupted data and our bad block info will be wrong (valid block can be > marked as bad and we lose bad, bad block can be see as valid). > > > Also the pattern and version in oob isn't protected by ecc. They can be corrupted. > > Are bbt safe to use ? > > Are there any plan to make the bbt more robust ? > Here a quick and dirty patch to make them more robust. Any comment are welcomed. Matthieu diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 5fedf4a..7b85b54 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -171,7 +171,7 @@ static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td) static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, int bits, int offs, int reserved_block_code) { - int res, i, j, act = 0; + int res, i, j, act = 0, ret = 0; struct nand_chip *this = mtd->priv; size_t retlen, len, totlen; loff_t from; @@ -188,6 +188,12 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, printk(KERN_INFO "nand_bbt: Error reading bad block table\n"); return res; } + if (res != -EUCLEAN) { + printk(KERN_INFO "nand_bbt: Error reading bad block table2\n"); + return res; + } + /* inform caller that there is bit flips */ + ret |= res; printk(KERN_WARNING "nand_bbt: ECC error while reading bad block table\n"); } @@ -220,7 +226,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, totlen -= len; from += len; } - return 0; + return ret; } /** @@ -900,7 +906,20 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc writecheck: /* read back first ? */ if (rd) - read_abs_bbt(mtd, buf, rd, chipsel); + res = read_abs_bbt(mtd, buf, rd, chipsel); + if (!rd2) { + if (res == -EBADMSG) { + /* bad recreate it */ + rd = NULL; + writeops = 0x03; + goto create; + } + else if (!rd2 && res == -EUCLEAN) { + /* rewrite it */ + writeops = 0x03; + } + } + /* If they weren't versioned, read both. */ if (rd2) read_abs_bbt(mtd, buf, rd2, chipsel);