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__);