X-Git-Url: https://yaffs.net/gitweb/?a=blobdiff_plain;f=yaffs_guts.c;h=7b41a764941972cefd61949ccf499bb478b91d2a;hb=e434bac0480bf62ea4d66519ff40dad3d2e3e410;hp=306b9b4bb08b4c688c5df0ff455c8836fd0bd06c;hpb=378bbdf4d64b8b26db55a495ab6ae520ff62e471;p=yaffs2.git diff --git a/yaffs_guts.c b/yaffs_guts.c index 306b9b4..7b41a76 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -13,7 +13,7 @@ */ const char *yaffs_guts_c_version = - "$Id: yaffs_guts.c,v 1.39 2006-10-03 10:13:03 charles Exp $"; + "$Id: yaffs_guts.c,v 1.40 2006-10-13 08:52:49 charles Exp $"; #include "yportenv.h" @@ -511,19 +511,35 @@ static void yaffs_HandleUpdateChunk(yaffs_Device * dev, int chunkInNAND, { } +void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi) +{ + if(!bi->gcPrioritise){ + bi->gcPrioritise = 1; + dev->hasPendingPrioritisedGCs = 1; + bi->chunkErrorStrikes ++; + + if(bi->chunkErrorStrikes > 3){ + bi->needsRetiring = 1; /* Too many stikes, so retire this */ + T(YAFFS_TRACE_ALWAYS, (TSTR("yaffs: Block struck out" TENDSTR))); + + } + + } +} + static void yaffs_HandleWriteChunkError(yaffs_Device * dev, int chunkInNAND, int erasedOk) { int blockInNAND = chunkInNAND / dev->nChunksPerBlock; yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, blockInNAND); + + yaffs_HandleChunkError(dev,bi); - bi->gcPrioritise = 1; - dev->hasPendingPrioritisedGCs = 1; - if(erasedOk) { + if(erasedOk ) { /* Was an actual write failure, so mark the block for retirement */ - bi->needsRetiring = 1; + } /* Delete the chunk */ @@ -2015,22 +2031,26 @@ static int yaffs_FindBlockForGarbageCollection(yaffs_Device * dev, int prioritised=0; yaffs_BlockInfo *bi; static int nonAggressiveSkip = 0; + int pendingPrioritisedExist = 0; /* First let's see if we need to grab a prioritised block */ if(dev->hasPendingPrioritisedGCs){ for(i = dev->internalStartBlock; i < dev->internalEndBlock && !prioritised; i++){ bi = yaffs_GetBlockInfo(dev, i); + if(bi->gcPrioritise) + pendingPrioritisedExist = 1; if(bi->blockState == YAFFS_BLOCK_STATE_FULL && bi->gcPrioritise && yaffs_BlockNotDisqualifiedFromGC(dev, bi)){ pagesInUse = (bi->pagesInUse - bi->softDeletions); - dirtiest = b; + dirtiest = i; prioritised = 1; aggressive = 1; /* Fool the non-aggressive skip logiv below */ } } - if(dirtiest < 0) /* None found, so we can clear this */ + + if(!pendingPrioritisedExist) /* None found, so we can clear this */ dev->hasPendingPrioritisedGCs = 0; } @@ -3408,7 +3428,7 @@ static int yaffs_WriteCheckpointValidityMarker(yaffs_Device *dev,int head) yaffs_CheckpointValidity cp; cp.structType = sizeof(cp); cp.magic = YAFFS_MAGIC; - cp.version = 1; + cp.version = YAFFS_CHECKPOINT_VERSION; cp.head = (head) ? 1 : 0; return (yaffs_CheckpointWrite(dev,&cp,sizeof(cp)) == sizeof(cp))? @@ -3425,7 +3445,7 @@ static int yaffs_ReadCheckpointValidityMarker(yaffs_Device *dev, int head) if(ok) ok = (cp.structType == sizeof(cp)) && (cp.magic == YAFFS_MAGIC) && - (cp.version == 1) && + (cp.version == YAFFS_CHECKPOINT_VERSION) && (cp.head == ((head) ? 1 : 0)); return ok ? 1 : 0; }