Mercurial > yaffs-ecoscentric
changeset 156:97177e5df1f8
Fix checkpointing bug
| author | charles |
|---|---|
| date | Tue, 07 Nov 2006 23:26:52 +0000 |
| parents | 8c15cd8621a4 |
| children | 41dac3f9ad92 |
| files | yaffs_checkptrw.c yaffs_guts.c |
| diffstat | 2 files changed, 37 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/yaffs_checkptrw.c +++ b/yaffs_checkptrw.c @@ -46,7 +46,7 @@ static int yaffs_CheckpointErase(yaffs_D 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_CheckpointFindNextEras 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(y 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 * } 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 {
--- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -527,6 +527,20 @@ void yaffs_HandleChunkError(yaffs_Device } } +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( 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_BlockNotDisqualifiedFro */ 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( 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(y 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(y 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 T(YAFFS_TRACE_CHECKPOINT,(TSTR("restore exit: isCheckpointed %d"TENDSTR),dev->isCheckpointed)); + yaffs_ReportOddballBlocks(dev); + return retval; } @@ -5141,6 +5163,12 @@ static void yaffs_CheckObjectDetailsLoad 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__);
