X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_guts.c;h=34e94a0a93942b2b931026beef9fa8e31624bc53;hp=a6775a9498cae9e6870a83df509c2fd32fb61b9b;hb=5b88de3db784f69899f8f02d0114d03c4cdba354;hpb=3b6c99b4d21c4ff4bbc9aed65a71868ab6a0dc46 diff --git a/yaffs_guts.c b/yaffs_guts.c index a6775a9..34e94a0 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -12,7 +12,7 @@ */ const char *yaffs_guts_c_version = - "$Id: yaffs_guts.c,v 1.63 2008-11-21 02:17:32 charles Exp $"; + "$Id: yaffs_guts.c,v 1.67 2008-11-27 02:46:45 charles Exp $"; #include "yportenv.h" @@ -2993,17 +2993,17 @@ static int yaffs_GetErasedChunks(yaffs_Device * dev) } -static int yaffs_GarbageCollectBlock(yaffs_Device * dev, int block) +static int yaffs_GarbageCollectBlock(yaffs_Device * dev, int block, int wholeBlock) { int oldChunk; int newChunk; - int chunkInBlock; int markNAND; int retVal = YAFFS_OK; int cleanups = 0; int i; int isCheckpointBlock; int matchingChunk; + int maxCopies; int chunksBefore = yaffs_GetErasedChunks(dev); int chunksAfter; @@ -3019,8 +3019,11 @@ static int yaffs_GarbageCollectBlock(yaffs_Device * dev, int block) bi->blockState = YAFFS_BLOCK_STATE_COLLECTING; T(YAFFS_TRACE_TRACING, - (TSTR("Collecting block %d, in use %d, shrink %d, " TENDSTR), block, - bi->pagesInUse, bi->hasShrinkHeader)); + (TSTR("Collecting block %d, in use %d, shrink %d, wholeBlock %d" TENDSTR), + block, + bi->pagesInUse, + bi->hasShrinkHeader, + wholeBlock)); /*yaffs_VerifyFreeChunks(dev); */ @@ -3046,14 +3049,20 @@ static int yaffs_GarbageCollectBlock(yaffs_Device * dev, int block) yaffs_VerifyBlock(dev,bi,block); - for (chunkInBlock = 0, oldChunk = block * dev->nChunksPerBlock; + maxCopies = (wholeBlock) ? dev->nChunksPerBlock : 10; + oldChunk = block * dev->nChunksPerBlock + dev->gcChunk; + + for ( /* init already done */; retVal == YAFFS_OK && - chunkInBlock < dev->nChunksPerBlock - && yaffs_StillSomeChunkBits(dev, block); - chunkInBlock++, oldChunk++) { - if (yaffs_CheckChunkBit(dev, block, chunkInBlock)) { + dev->gcChunk < dev->nChunksPerBlock && + (bi->blockState == YAFFS_BLOCK_STATE_COLLECTING)&& + maxCopies > 0; + dev->gcChunk++, oldChunk++) { + if (yaffs_CheckChunkBit(dev, block, dev->gcChunk)) { /* This page is in use and might need to be copied off */ + + maxCopies--; markNAND = 1; @@ -3068,8 +3077,8 @@ static int yaffs_GarbageCollectBlock(yaffs_Device * dev, int block) T(YAFFS_TRACE_GC_DETAIL, (TSTR - ("Collecting page %d, %d %d %d " TENDSTR), - chunkInBlock, tags.objectId, tags.chunkId, + ("Collecting chunk in block %d, %d %d %d " TENDSTR), + dev->gcChunk, tags.objectId, tags.chunkId, tags.byteCount)); if(object && !yaffs_SkipVerification(dev)){ @@ -3148,7 +3157,6 @@ static int yaffs_GarbageCollectBlock(yaffs_Device * dev, int block) yaffs_ObjectHeader *oh; oh = (yaffs_ObjectHeader *)buffer; oh->isShrink = 0; - oh->shadowsObject = oh->inbandShadowsObject = -1; tags.extraShadows = 0; tags.extraIsShrinkHeader = 0; @@ -3185,6 +3193,7 @@ static int yaffs_GarbageCollectBlock(yaffs_Device * dev, int block) } yaffs_ReleaseTempBuffer(dev, buffer, __LINE__); + /* Do any required cleanups */ @@ -3219,6 +3228,12 @@ static int yaffs_GarbageCollectBlock(yaffs_Device * dev, int block) TENDSTR), chunksBefore, chunksAfter)); } + /* If the gc completed then clear the current gcBlock so that we find another. */ + if(bi->blockState != YAFFS_BLOCK_STATE_COLLECTING){ + dev->gcBlock = -1; + dev->gcChunk = 0; + } + dev->isDoingGC = 0; return retVal; @@ -3266,7 +3281,12 @@ static int yaffs_CheckGarbageCollection(yaffs_Device * dev) aggressive = 0; } - block = yaffs_FindBlockForGarbageCollection(dev, aggressive); + if(dev->gcBlock <= 0){ + dev->gcBlock = yaffs_FindBlockForGarbageCollection(dev, aggressive); + dev->gcChunk = 0; + } + + block = dev->gcBlock; if (block > 0) { dev->garbageCollections++; @@ -3279,7 +3299,7 @@ static int yaffs_CheckGarbageCollection(yaffs_Device * dev) ("yaffs: GC erasedBlocks %d aggressive %d" TENDSTR), dev->nErasedBlocks, aggressive)); - gcOk = yaffs_GarbageCollectBlock(dev, block); + gcOk = yaffs_GarbageCollectBlock(dev,block,aggressive); } if (dev->nErasedBlocks < (dev->nReservedBlocks) && block > 0) { @@ -3288,8 +3308,9 @@ static int yaffs_CheckGarbageCollection(yaffs_Device * dev) ("yaffs: GC !!!no reclaim!!! erasedBlocks %d after try %d block %d" TENDSTR), dev->nErasedBlocks, maxTries, block)); } - } while ((dev->nErasedBlocks < dev->nReservedBlocks) && (block > 0) - && (maxTries < 2)); + } while ((dev->nErasedBlocks < dev->nReservedBlocks) && + (block > 0) && + (maxTries < 2)); return aggressive ? gcOk : YAFFS_OK; } @@ -4868,7 +4889,7 @@ int yaffs_WriteDataToFile(yaffs_Object * in, const __u8 * buffer, loff_t offset, nToWriteBack = (nBytesRead > - (start + n)) ? nBytesRead : (start + n); + ((int)start + n)) ? nBytesRead : (start + n); } else { nToCopy = dev->nDataBytesPerChunk - start; @@ -6943,9 +6964,18 @@ int yaffs_GetObjectName(yaffs_Object * obj, YCHAR * name, int buffSize) yaffs_strncpy(name, YAFFS_LOSTNFOUND_NAME, buffSize - 1); } else if (obj->hdrChunk <= 0) { YCHAR locName[20]; + YCHAR numString[20]; + YCHAR *x = &numString[19]; + unsigned v = obj->objectId; + numString[19] = 0; + while(v>0){ + x--; + *x = '0' + (v % 10); + v /= 10; + } /* make up a name */ - yaffs_sprintf(locName, _Y("%s%d"), YAFFS_LOSTNFOUND_PREFIX, - obj->objectId); + yaffs_strcpy(locName, YAFFS_LOSTNFOUND_PREFIX); + yaffs_strcat(locName,x); yaffs_strncpy(name, locName, buffSize - 1); } @@ -7213,6 +7243,8 @@ int yaffs_GutsInitialise(yaffs_Device * dev) dev->blockOffset = 0; dev->chunkOffset = 0; dev->nFreeChunks = 0; + + dev->gcBlock = -1; if (dev->startBlock == 0) { dev->internalStartBlock = dev->startBlock + 1;