/*
- * YAFFS: Yet another FFS. A NAND-flash specific file system.
+ * YAFFS: Yet another FFS. A NAND-flash specific file system.
*
* Copyright (C) 2002 Aleph One Ltd.
* for Toby Churchill Ltd and Brightstar Engineering
*/
const char *yaffs_guts_c_version =
- "$Id: yaffs_guts.c,v 1.32 2006-05-08 10:13:34 charles Exp $";
+ "$Id: yaffs_guts.c,v 1.33 2006-05-17 09:20:26 charles Exp $";
#include "yportenv.h"
bi = yaffs_GetBlockInfo(dev, b);
+#if 0
+ if (bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT) {
+ dirtiest = b;
+ pagesInUse = 0;
+ }
+ else
+#endif
+
if (bi->blockState == YAFFS_BLOCK_STATE_FULL &&
- (bi->pagesInUse - bi->softDeletions) < pagesInUse &&
- yaffs_BlockNotDisqualifiedFromGC(dev, bi)) {
+ (bi->pagesInUse - bi->softDeletions) < pagesInUse &&
+ yaffs_BlockNotDisqualifiedFromGC(dev, bi)) {
dirtiest = b;
pagesInUse = (bi->pagesInUse - bi->softDeletions);
}
}
-
+// Check if there's space to allocate...
+// Thinks.... do we need top make this ths same as yaffs_GetFreeChunks()?
static int yaffs_CheckSpaceForAllocation(yaffs_Device * dev)
{
- int reservedChunks = (dev->nReservedBlocks * dev->nChunksPerBlock);
+ int reservedChunks;
+ int reservedBlocks = dev->nReservedBlocks;
+ int checkpointBlocks;
+
+ checkpointBlocks = dev->nCheckpointReservedBlocks - dev->blocksInCheckpoint;
+ if(checkpointBlocks < 0)
+ checkpointBlocks = 0;
+
+ reservedChunks = ((reservedBlocks + checkpointBlocks) * dev->nChunksPerBlock);
+
return (dev->nFreeChunks > reservedChunks);
}
int retVal = YAFFS_OK;
int cleanups = 0;
int i;
+ int isCheckpointBlock;
int chunksBefore = yaffs_GetErasedChunks(dev);
int chunksAfter;
yaffs_Object *object;
+ isCheckpointBlock = (bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT);
+
bi->blockState = YAFFS_BLOCK_STATE_COLLECTING;
T(YAFFS_TRACE_TRACING,
dev->isDoingGC = 1;
- if (!yaffs_StillSomeChunkBits(dev, block)) {
+ if (isCheckpointBlock ||
+ !yaffs_StillSomeChunkBits(dev, block)) {
T(YAFFS_TRACE_TRACING,
(TSTR
("Collecting block %d that has no chunks in use" TENDSTR),
static int yaffs_WriteCheckpointTnodes(yaffs_Object *obj)
{
__u32 endMarker = ~0;
- int ok;
+ int ok = 1;
if(obj->variantType == YAFFS_OBJECT_TYPE_FILE){
ok = yaffs_CheckpointTnodeWorker(obj,
yaffs_CheckpointClose(dev);
- if(ok)
+// if(dev->checkpointBytes)
dev->isCheckpointed = 1;
- else
- dev->isCheckpointed = 0;
+// else
+ //dev->isCheckpointed = 0;
return dev->isCheckpointed;
}
if(ok)
ok = yaffs_ReadCheckpointValidityMarker(dev,0);
-
- if(ok)
- dev->isCheckpointed = 1;
- else
- dev->isCheckpointed = 0;
+
yaffs_CheckpointClose(dev);
+// if(ok)
+ dev->isCheckpointed = 1;
+// else
+// dev->isCheckpointed = 0;
+
return ok ? 1 : 0;
}
if(dev->isCheckpointed){
dev->isCheckpointed = 0;
yaffs_CheckpointInvalidateStream(dev);
+ if(dev->superBlock && dev->markSuperBlockDirty)
+ dev->markSuperBlockDirty(dev->superBlock);
}
}
yaffs_ChunkCache *cache;
/* If we can't find the data in the cache, then load the cache */
cache = yaffs_FindChunkCache(in, chunk);
+
if (!cache
&& yaffs_CheckSpaceForAllocation(in->
myDev)) {
cache->
data);
}
+ else if(cache &&
+ !cache->dirty &&
+ !yaffs_CheckSpaceForAllocation(in->myDev)){
+ /* Drop the cache if it was a read cache item and
+ * no space check has been made for it.
+ */
+ cache = NULL;
+ }
if (cache) {
yaffs_UseChunkCache(dev, cache, 1);
bi->blockState = state;
bi->sequenceNumber = sequenceNumber;
+ if(bi->sequenceNumber == YAFFS_SEQUENCE_CHECKPOINT_DATA)
+ bi->blockState = state = YAFFS_BLOCK_STATE_CHECKPOINT;
+
T(YAFFS_TRACE_SCAN_DEBUG,
(TSTR("Block scanning block %d state %d seq %d" TENDSTR), blk,
state, sequenceNumber));
- if (state == YAFFS_BLOCK_STATE_DEAD) {
+
+ if(state == YAFFS_BLOCK_STATE_CHECKPOINT){
+ /* todo .. fix free space ? */
+
+ } else if (state == YAFFS_BLOCK_STATE_DEAD) {
T(YAFFS_TRACE_BAD_BLOCKS,
(TSTR("block %d is bad" TENDSTR), blk));
} else if (state == YAFFS_BLOCK_STATE_EMPTY) {
int nFree;
int nDirtyCacheChunks;
+ int blocksForCheckpoint;
#if 1
nFree = dev->nFreeChunks;
nFree -= nDirtyCacheChunks;
nFree -= ((dev->nReservedBlocks + 1) * dev->nChunksPerBlock);
+
+ /* Now we figure out how much to reserve for the checkpoint and report that... */
+ blocksForCheckpoint = dev->nCheckpointReservedBlocks - dev->blocksInCheckpoint;
+ if(blocksForCheckpoint < 0)
+ blocksForCheckpoint = 0;
+
+ nFree -= (blocksForCheckpoint * dev->nChunksPerBlock);
if (nFree < 0)
nFree = 0;