Fix checkpointing bug
authorcharles <charles>
Tue, 7 Nov 2006 23:26:52 +0000 (23:26 +0000)
committercharles <charles>
Tue, 7 Nov 2006 23:26:52 +0000 (23:26 +0000)
yaffs_checkptrw.c
yaffs_guts.c

index 8d1bb66..afc7e47 100644 (file)
@@ -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 {
index 7b41a76..2736ced 100644 (file)
@@ -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__);