From 107910497be0a0d0e4a8ab357c403fc2a234323b Mon Sep 17 00:00:00 2001 From: Charles Manning Date: Tue, 10 Aug 2010 09:09:41 +1200 Subject: [PATCH] yaffs Fix yaffs1 soft delete issue In some corner cases soft deletion could cause NAND to leak and show up in lost and found. This only impacts yaffs1 mode. Signed-off-by: Charles Manning --- yaffs_guts.c | 38 +++++++++++++++++++++----------------- yaffs_guts.h | 1 + 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/yaffs_guts.c b/yaffs_guts.c index cfb0b42..c01f00c 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -2106,7 +2106,6 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block, int newChunk; int markNAND; int retVal = YAFFS_OK; - int cleanups = 0; int i; int isCheckpointBlock; int matchingChunk; @@ -2229,9 +2228,9 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block, if (object->nDataChunks <= 0) { /* remeber to clean up the object */ - dev->gcCleanupList[cleanups] = + dev->gcCleanupList[dev->nCleanups] = tags.objectId; - cleanups++; + dev->nCleanups++; } markNAND = 0; } else if (0) { @@ -2317,8 +2316,23 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block, yaffs_ReleaseTempBuffer(dev, buffer, __LINE__); + + } + + yaffs_VerifyCollectedBlock(dev, bi, block); + + + + 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. */ /* Do any required cleanups */ - for (i = 0; i < cleanups; i++) { + for (i = 0; i < dev->nCleanups; i++) { /* Time to delete the file too */ object = yaffs_FindObjectByNumber(dev, @@ -2338,20 +2352,7 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block, } - } - - yaffs_VerifyCollectedBlock(dev, bi, block); - - - 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, @@ -2361,6 +2362,7 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block, } dev->gcBlock = 0; dev->gcChunk = 0; + dev->nCleanups = 0; } dev->gcDisable = 0; @@ -2582,10 +2584,12 @@ static int yaffs_CheckGarbageCollection(yaffs_Device *dev, int background) if (dev->gcBlock < 1 && !aggressive) { dev->gcBlock = yaffs2_FindRefreshBlock(dev); dev->gcChunk = 0; + dev->nCleanups=0; } if (dev->gcBlock < 1) { dev->gcBlock = yaffs_FindBlockForGarbageCollection(dev, aggressive, background); dev->gcChunk = 0; + dev->nCleanups=0; } if (dev->gcBlock > 0) { diff --git a/yaffs_guts.h b/yaffs_guts.h index ce9c385..6d4ae46 100644 --- a/yaffs_guts.h +++ b/yaffs_guts.h @@ -696,6 +696,7 @@ struct yaffs_DeviceStruct { /* Garbage collection control */ __u32 *gcCleanupList; /* objects to delete at the end of a GC. */ + __u32 nCleanups; unsigned hasPendingPrioritisedGCs; /* We think this device might have pending prioritised gcs */ unsigned gcDisable; -- 2.30.2