From f1bdfc2922899bb7f85385d0876bd82ebedd8f62 Mon Sep 17 00:00:00 2001 From: charles Date: Tue, 7 Nov 2006 23:26:52 +0000 Subject: [PATCH] Fix checkpointing bug --- yaffs_checkptrw.c | 10 +++++----- yaffs_guts.c | 40 ++++++++++++++++++++++++++++++++++------ 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/yaffs_checkptrw.c b/yaffs_checkptrw.c index 8d1bb66..afc7e47 100644 --- a/yaffs_checkptrw.c +++ b/yaffs_checkptrw.c @@ -13,7 +13,7 @@ */ const char *yaffs_checkptrw_c_version = - "$Id: yaffs_checkptrw.c,v 1.5 2006-10-03 10:13:03 charles Exp $"; + "$Id: yaffs_checkptrw.c,v 1.6 2006-11-07 23:26:52 charles Exp $"; #include "yaffs_checkptrw.h" @@ -46,7 +46,7 @@ static int yaffs_CheckpointErase(yaffs_Device *dev) dev->startBlock,dev->endBlock)); for(i = dev->startBlock; i <= dev->endBlock; i++) { - yaffs_BlockInfo *bi = &dev->blockInfo[i]; + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,i); if(bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT){ T(YAFFS_TRACE_CHECKPOINT,(TSTR("erasing checkpt block %d"TENDSTR),i)); if(dev->eraseBlockInNAND(dev,i)){ @@ -77,7 +77,7 @@ static void yaffs_CheckpointFindNextErasedBlock(yaffs_Device *dev) blocksAvailable > 0){ for(i = dev->checkpointNextBlock; i <= dev->endBlock; i++){ - yaffs_BlockInfo *bi = &dev->blockInfo[i]; + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,i); if(bi->blockState == YAFFS_BLOCK_STATE_EMPTY){ dev->checkpointNextBlock = i + 1; dev->checkpointCurrentBlock = i; @@ -195,7 +195,7 @@ static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev) if(dev->checkpointCurrentChunk == 0){ /* First chunk we write for the block? Set block state to checkpoint */ - yaffs_BlockInfo *bi = &dev->blockInfo[dev->checkpointCurrentBlock]; + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,dev->checkpointCurrentBlock); bi->blockState = YAFFS_BLOCK_STATE_CHECKPOINT; dev->blocksInCheckpoint++; } @@ -321,7 +321,7 @@ int yaffs_CheckpointClose(yaffs_Device *dev) } else { int i; for(i = 0; i < dev->blocksInCheckpoint && dev->checkpointBlockList[i] >= 0; i++){ - yaffs_BlockInfo *bi = &dev->blockInfo[dev->checkpointBlockList[i]]; + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,dev->checkpointBlockList[i]); if(bi->blockState == YAFFS_BLOCK_STATE_EMPTY) bi->blockState = YAFFS_BLOCK_STATE_CHECKPOINT; else { diff --git a/yaffs_guts.c b/yaffs_guts.c index 7b41a76..2736ced 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.40 2006-10-13 08:52:49 charles Exp $"; + "$Id: yaffs_guts.c,v 1.41 2006-11-07 23:26:52 charles Exp $"; #include "yportenv.h" @@ -527,6 +527,20 @@ void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi) } } +static void yaffs_ReportOddballBlocks(yaffs_Device *dev) +{ + int i; + for(i = dev->startBlock; i <= dev->endBlock; i++){ + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,i); + if(bi->needsRetiring || bi->gcPrioritise) + T(YAFFS_TRACE_BAD_BLOCKS,(TSTR("yaffs block %d%s%s" TENDSTR), + i, + bi->needsRetiring ? " needs retiring" : "", + bi->gcPrioritise ? " gc prioritised" : "")); + + } +} + static void yaffs_HandleWriteChunkError(yaffs_Device * dev, int chunkInNAND, int erasedOk) { @@ -539,6 +553,9 @@ static void yaffs_HandleWriteChunkError(yaffs_Device * dev, int chunkInNAND, int if(erasedOk ) { /* Was an actual write failure, so mark the block for retirement */ bi->needsRetiring = 1; + T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS, + (TSTR("**>> Block %d needs retiring" TENDSTR), blockInNAND)); + } @@ -2010,8 +2027,6 @@ static int yaffs_BlockNotDisqualifiedFromGC(yaffs_Device * dev, */ return (bi->sequenceNumber <= dev->oldestDirtySequence); - return 1; - } /* FindDiretiestBlock is used to select the dirtiest block (or close enough) @@ -3712,7 +3727,11 @@ static int yaffs_WriteCheckpointObjects(yaffs_Device *dev) if (!obj->deferedFree) { yaffs_ObjectToCheckpointObject(&cp,obj); cp.structType = sizeof(cp); - /* printf("Write out object %d type %d\n",obj->objectId,obj->variantType); */ + + T(YAFFS_TRACE_CHECKPOINT,( + TSTR("Checkpoint write object %d parent %d type %d chunk %d obj addr %x" TENDSTR), + cp.objectId,cp.parentId,cp.variantType,cp.chunkId,(unsigned) obj)); + ok = (yaffs_CheckpointWrite(dev,&cp,sizeof(cp)) == sizeof(cp)); if(ok && obj->variantType == YAFFS_OBJECT_TYPE_FILE){ @@ -3751,9 +3770,9 @@ static int yaffs_ReadCheckpointObjects(yaffs_Device *dev) if(ok && cp.objectId == ~0) done = 1; else if(ok){ - T(YAFFS_TRACE_CHECKPOINT,(TSTR("Read object %d parent %d type %d" TENDSTR), - cp.objectId,cp.parentId,cp.variantType)); obj = yaffs_FindOrCreateObjectByNumber(dev,cp.objectId, cp.variantType); + T(YAFFS_TRACE_CHECKPOINT,(TSTR("Checkpoint read object %d parent %d type %d chunk %d obj addr %x" TENDSTR), + cp.objectId,cp.parentId,cp.variantType,cp.chunkId,(unsigned) obj)); if(obj) { yaffs_CheckpointObjectToObject(obj,&cp); if(obj->variantType == YAFFS_OBJECT_TYPE_FILE) { @@ -3845,6 +3864,7 @@ static void yaffs_InvalidateCheckpoint(yaffs_Device *dev) int yaffs_CheckpointSave(yaffs_Device *dev) { + yaffs_ReportOddballBlocks(dev); T(YAFFS_TRACE_CHECKPOINT,(TSTR("save entry: isCheckpointed %d"TENDSTR),dev->isCheckpointed)); if(!dev->isCheckpointed) @@ -3864,6 +3884,8 @@ int yaffs_CheckpointRestore(yaffs_Device *dev) T(YAFFS_TRACE_CHECKPOINT,(TSTR("restore exit: isCheckpointed %d"TENDSTR),dev->isCheckpointed)); + yaffs_ReportOddballBlocks(dev); + return retval; } @@ -5141,6 +5163,12 @@ static void yaffs_CheckObjectDetailsLoaded(yaffs_Object *in) yaffs_ExtendedTags tags; int result; +#if 0 + T(YAFFS_TRACE_SCAN,(TSTR("details for object %d %s loaded" TENDSTR), + in->objectId, + in->lazyLoaded ? "not yet" : "already")); +#endif + if(in->lazyLoaded){ in->lazyLoaded = 0; chunkData = yaffs_GetTempBuffer(dev, __LINE__); -- 2.30.2