Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 63fd7f30 authored by Daniel Rosenthal's avatar Daniel Rosenthal Committed by David Woodhouse
Browse files

[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: default avatarDaniel Rosenthal <danielrosenthal@acm.org>
Acked-by: default avatarGreg Ungerer <gerg@snapgear.com>
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent f324277c
Loading
Loading
Loading
Loading
+4 −1
Original line number Original line Diff line number Diff line
@@ -388,6 +388,10 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
		if (thisEUN == targetEUN)
		if (thisEUN == targetEUN)
			break;
			break;


		/* Unlink the last block from the chain. */
		inftl->PUtable[prevEUN] = BLOCK_NIL;

		/* Now try to erase it. */
		if (INFTL_formatblock(inftl, thisEUN) < 0) {
		if (INFTL_formatblock(inftl, thisEUN) < 0) {
			/*
			/*
			 * Could not erase : mark block as reserved.
			 * Could not erase : mark block as reserved.
@@ -396,7 +400,6 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
		} else {
		} else {
			/* Correctly erased : mark it as free */
			/* Correctly erased : mark it as free */
			inftl->PUtable[thisEUN] = BLOCK_FREE;
			inftl->PUtable[thisEUN] = BLOCK_FREE;
			inftl->PUtable[prevEUN] = BLOCK_NIL;
			inftl->numfreeEUNs++;
			inftl->numfreeEUNs++;
		}
		}
	}
	}