[MTD] [INFTL] Fix infinite loop in INFTL_foldchain

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Wed Oct 8 06:59:02 EDT 2008


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=63fd7f30f328f99956d3c774d17219c3c8d54131
Commit:     63fd7f30f328f99956d3c774d17219c3c8d54131
Parent:     f324277cf70ad284dd99acf5ac5101e32bc8c55b
Author:     Daniel Rosenthal <danielrosenthal at acm.org>
AuthorDate: Sun Oct 5 17:43:10 2008 -0400
Committer:  David Woodhouse <David.Woodhouse at intel.com>
CommitDate: Wed Oct 8 11:26:38 2008 +0100

    [MTD] [INFTL] Fix infinite loop in INFTL_foldchain
    
    When iterating over a chain in reverse (oldest block first), this
    patch correctly marks the PUtable[] entry of the second to last erase
    block of a chain as BLOCK_NIL, regardless of whether or not it can
    format the last block successfully. Before, the second to last block
    was only marked as pointing to BLOCK_NIL if INFTL_formatblock()
    succeeded on the last block of the chain, which could potentially
    result in an infinite loop if the block was worn out and refused to
    format.
    
    Signed-off-by: Daniel Rosenthal <danielrosenthal at acm.org>
    Acked-by: Greg Ungerer <gerg at snapgear.com>
    Signed-off-by: David Woodhouse <David.Woodhouse at intel.com>
---
 drivers/mtd/inftlcore.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c
index c4f9d33..50ce138 100644
--- a/drivers/mtd/inftlcore.c
+++ b/drivers/mtd/inftlcore.c
@@ -388,6 +388,10 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
 		if (thisEUN == targetEUN)
 			break;
 
+		/* Unlink the last block from the chain. */
+		inftl->PUtable[prevEUN] = BLOCK_NIL;
+
+		/* Now try to erase it. */
 		if (INFTL_formatblock(inftl, thisEUN) < 0) {
 			/*
 			 * Could not erase : mark block as reserved.
@@ -396,7 +400,6 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
 		} else {
 			/* Correctly erased : mark it as free */
 			inftl->PUtable[thisEUN] = BLOCK_FREE;
-			inftl->PUtable[prevEUN] = BLOCK_NIL;
 			inftl->numfreeEUNs++;
 		}
 	}



More information about the linux-mtd-cvs mailing list