X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_guts.c;h=f88851eea5c89e971120c6267b6a7e012f1bebe9;hp=a5e8f670a03fd48b30bb40ac37587aedf5d3efd5;hb=379119cdc62e194b143c7086c0bac6618bc4390a;hpb=1049ca7d7f24a91577b738e26825fb9be2f169f3 diff --git a/yaffs_guts.c b/yaffs_guts.c index a5e8f67..f88851e 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -13,7 +13,7 @@ */ const char *yaffs_guts_c_version = - "$Id: yaffs_guts.c,v 1.42 2006-11-08 00:33:29 charles Exp $"; + "$Id: yaffs_guts.c,v 1.45 2006-11-14 03:07:17 charles Exp $"; #include "yportenv.h" @@ -484,13 +484,15 @@ static int yaffs_WriteNewChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev, static void yaffs_RetireBlock(yaffs_Device * dev, int blockInNAND) { + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, blockInNAND); yaffs_InvalidateCheckpoint(dev); yaffs_MarkBlockBad(dev, blockInNAND); - yaffs_GetBlockInfo(dev, blockInNAND)->blockState = - YAFFS_BLOCK_STATE_DEAD; + bi->blockState = YAFFS_BLOCK_STATE_DEAD; + bi->gcPrioritise = 0; + bi->needsRetiring = 0; dev->nRetiredBlocks++; } @@ -2054,15 +2056,15 @@ static int yaffs_FindBlockForGarbageCollection(yaffs_Device * dev, for(i = dev->internalStartBlock; i < dev->internalEndBlock && !prioritised; i++){ bi = yaffs_GetBlockInfo(dev, i); - if(bi->gcPrioritise) + if(bi->gcPrioritise) { pendingPrioritisedExist = 1; - if(bi->blockState == YAFFS_BLOCK_STATE_FULL && - bi->gcPrioritise && - yaffs_BlockNotDisqualifiedFromGC(dev, bi)){ - pagesInUse = (bi->pagesInUse - bi->softDeletions); - dirtiest = i; - prioritised = 1; - aggressive = 1; /* Fool the non-aggressive skip logiv below */ + if(bi->blockState == YAFFS_BLOCK_STATE_FULL && + yaffs_BlockNotDisqualifiedFromGC(dev, bi)){ + pagesInUse = (bi->pagesInUse - bi->softDeletions); + dirtiest = i; + prioritised = 1; + aggressive = 1; /* Fool the non-aggressive skip logiv below */ + } } } @@ -2154,6 +2156,11 @@ static void yaffs_BlockBecameDirty(yaffs_Device * dev, int blockNo) /* If the block is still healthy erase it and mark as clean. * If the block has had a data failure, then retire it. */ + + T(YAFFS_TRACE_GC | YAFFS_TRACE_ERASE, + (TSTR("yaffs_BlockBecameDirty block %d state %d %s"TENDSTR), + blockNo, bi->blockState, (bi->needsRetiring) ? "needs retiring" : "")); + bi->blockState = YAFFS_BLOCK_STATE_DIRTY; if (!bi->needsRetiring) { @@ -5413,39 +5420,41 @@ static int yaffs_ScanBackwards(yaffs_Device * dev) state = YAFFS_BLOCK_STATE_EMPTY; dev->nErasedBlocks++; } else { - /* this is the block being allocated from */ - if (state == - YAFFS_BLOCK_STATE_NEEDS_SCANNING) { - T(YAFFS_TRACE_SCAN, - (TSTR - (" Allocating from %d %d" - TENDSTR), blk, c)); + if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING || + state == YAFFS_BLOCK_STATE_ALLOCATING) { + if(dev->sequenceNumber == bi->sequenceNumber) { + /* this is the block being allocated from */ + + T(YAFFS_TRACE_SCAN, + (TSTR + (" Allocating from %d %d" + TENDSTR), blk, c)); + + state = YAFFS_BLOCK_STATE_ALLOCATING; + dev->allocationBlock = blk; + dev->allocationPage = c; + dev->allocationBlockFinder = blk; + } + else { + /* This is a partially written block that is not + * the current allocation block. This block must have + * had a write failure, so set up for retirement. + */ + + bi->needsRetiring = 1; + bi->gcPrioritise = 1; + + T(YAFFS_TRACE_ALWAYS, + (TSTR("Partially written block %d being set for retirement" TENDSTR), + blk)); + } + } - state = YAFFS_BLOCK_STATE_ALLOCATING; - dev->allocationBlock = blk; - dev->allocationPage = c; - dev->allocationBlockFinder = blk; - /* Set it to here to encourage the allocator to - * go forth from here. - */ - /* Yaffs2 sanity check: - * This should be the one with the highest sequence number - */ - if (dev->isYaffs2 - && (dev->sequenceNumber != - bi->sequenceNumber)) { - T(YAFFS_TRACE_ALWAYS, - (TSTR - ("yaffs: Allocation block %d was not highest sequence " - "id: block seq = %d, dev seq = %d" - TENDSTR), blk, - bi->sequenceNumber, - dev->sequenceNumber)); - } } dev->nFreeChunks++; + } else if (tags.chunkId > 0) { /* chunkId > 0 so it is a data chunk... */ unsigned int endpos;