X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_guts.c;h=feade2aff1044b208adf2647a924f374d79b52b4;hp=523bfb722b8afc31bd36f4e1ededd9805234460d;hb=e22bd0c9f6ff5759ae63d2f28b5dc4e000e9def7;hpb=329ebf2e9014af0fa876cd860a4525e2a98a0d50 diff --git a/yaffs_guts.c b/yaffs_guts.c index 523bfb7..feade2a 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -2943,6 +2943,10 @@ static void yaffs_BlockBecameDirty(yaffs_Device *dev, int blockNo) bi->blockState = YAFFS_BLOCK_STATE_DIRTY; + /* If this is the block being garbage collected then stop gc'ing this block */ + if(blockNo == dev->gcBlock) + dev->gcBlock = -1; + if (!bi->needsRetiring) { yaffs_InvalidateCheckpoint(dev); erasedOk = yaffs_EraseBlockInNAND(dev, blockNo); @@ -3215,12 +3219,6 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block, bi->hasShrinkHeader = 0; /* clear the flag so that the block can erase */ - /* Take off the number of soft deleted entries because - * they're going to get really deleted during GC. - */ - if(dev->gcChunk == 0) /* first time through for this block */ - dev->nFreeChunks -= bi->softDeletions; - dev->isDoingGC = 1; if (isCheckpointBlock || @@ -3300,6 +3298,13 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block, * No need to copy this, just forget about it and * fix up the object. */ + + /* Free chunks already includes softdeleted chunks. + * How ever this chunk is going to soon be really deleted + * which will increment free chunks. + * We have to decrement free chunks so this works out properly. + */ + dev->nFreeChunks--; object->nDataChunks--; @@ -3420,8 +3425,14 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block, - /* If the gc completed then clear the current gcBlock so that we find another. */ - if (bi->blockState != YAFFS_BLOCK_STATE_COLLECTING) { + if (bi->blockState == YAFFS_BLOCK_STATE_COLLECTING) { + /* + * The gc did not complete. Set block state back to FULL + * because checkpointing does not restore gc. + */ + bi->blockState = YAFFS_BLOCK_STATE_FULL; + } else { + /* The gc completed. */ chunksAfter = yaffs_GetErasedChunks(dev); if (chunksBefore >= chunksAfter) { T(YAFFS_TRACE_GC,