If unsure, say N.
-config YAFFS_CHECKPOINT_RESERVED_BLOCKS
- int "Reserved blocks for checkpointing"
- depends on YAFFS_YAFFS2
- default 10
- help
- Give the number of Blocks to reserve for checkpointing.
- Checkpointing saves the state at unmount so that mounting is
- much faster as a scan of all the flash to regenerate this state
- is not needed. These Blocks are reserved per partition, so if
- you have very small partitions the default (10) may be a mess
- for you. You can set this value to 0, but that does not mean
- checkpointing is disabled at all. There only won't be any
- specially reserved blocks for checkpointing, so if there is
- enough free space on the filesystem, it will be used for
- checkpointing.
-
- If unsure, leave at default (10), but don't wonder if there are
- always 2MB used on your large page device partition (10 x 2k
- pagesize). When using small partitions or when being very small
- on space, you probably want to set this to zero.
config YAFFS_DISABLE_WIDE_TNODES
bool "Turn off wide tnodes"
*/
const char *yaffs_fs_c_version =
- "$Id: yaffs_fs.c,v 1.63 2007-09-19 20:35:40 imcd Exp $";
+ "$Id: yaffs_fs.c,v 1.64 2007-12-03 03:21:48 charles Exp $";
extern const char *yaffs_guts_c_version;
#include <linux/version.h>
#endif
nBlocks = mtd->size / mtd->erasesize;
- dev->nCheckpointReservedBlocks = CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS;
dev->startBlock = 0;
dev->endBlock = nBlocks - 1;
} else {
buf += sprintf(buf, "chunkGroupSize..... %d\n", dev->chunkGroupSize);
buf += sprintf(buf, "nErasedBlocks...... %d\n", dev->nErasedBlocks);
buf += sprintf(buf, "nReservedBlocks.... %d\n", dev->nReservedBlocks);
- buf += sprintf(buf, "nCheckptResBlocks.. %d\n", dev->nCheckpointReservedBlocks);
buf += sprintf(buf, "blocksInCheckpoint. %d\n", dev->blocksInCheckpoint);
buf += sprintf(buf, "nTnodesCreated..... %d\n", dev->nTnodesCreated);
buf += sprintf(buf, "nFreeTnodes........ %d\n", dev->nFreeTnodes);
*/
const char *yaffs_guts_c_version =
- "$Id: yaffs_guts.c,v 1.52 2007-10-16 00:45:05 charles Exp $";
+ "$Id: yaffs_guts.c,v 1.53 2007-12-03 03:21:48 charles Exp $";
#include "yportenv.h"
* Must be a multiple of 32-bits */
tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
+ if(tnodeSize < sizeof(yaffs_Tnode))
+ tnodeSize = sizeof(yaffs_Tnode);
+
+
/* make these things */
newTnodes = YMALLOC(nTnodes * tnodeSize);
dev->nFreeTnodes--;
}
+ dev->nCheckpointBlocksRequired = 0; /* force recalculation*/
+
return tn;
}
static yaffs_Tnode *yaffs_GetTnode(yaffs_Device * dev)
{
yaffs_Tnode *tn = yaffs_GetTnodeRaw(dev);
+ int tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
+
+ if(tnodeSize < sizeof(yaffs_Tnode))
+ tnodeSize = sizeof(yaffs_Tnode);
if(tn)
- memset(tn, 0, (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8);
+ memset(tn, 0, tnodeSize);
return tn;
}
dev->freeTnodes = tn;
dev->nFreeTnodes++;
}
+ dev->nCheckpointBlocksRequired = 0; /* force recalculation*/
+
}
static void yaffs_DeinitialiseTnodes(yaffs_Device * dev)
yaffs_AddObjectToDirectory(dev->lostNFoundDir, tn);
}
}
+
+ dev->nCheckpointBlocksRequired = 0; /* force recalculation*/
return tn;
}
tn->siblings.next = (struct list_head *)(dev->freeObjects);
dev->freeObjects = tn;
dev->nFreeObjects++;
+
+ dev->nCheckpointBlocksRequired = 0; /* force recalculation*/
+
}
#ifdef __KERNEL__
}
+
+static int yaffs_CalcCheckpointBlocksRequired(yaffs_Device *dev)
+{
+ if(!dev->nCheckpointBlocksRequired){
+ /* Not a valid value so recalculate */
+ int nBytes = 0;
+ int nBlocks;
+ int devBlocks = (dev->endBlock - dev->startBlock + 1);
+ int tnodeSize;
+
+ tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
+
+ if(tnodeSize < sizeof(yaffs_Tnode))
+ tnodeSize = sizeof(yaffs_Tnode);
+
+ nBytes += sizeof(yaffs_CheckpointValidity);
+ nBytes += sizeof(yaffs_CheckpointDevice);
+ nBytes += devBlocks * sizeof(yaffs_BlockInfo);
+ nBytes += devBlocks * dev->chunkBitmapStride;
+ nBytes += (sizeof(yaffs_CheckpointObject) + sizeof(__u32)) * (dev->nObjectsCreated - dev->nFreeObjects);
+ nBytes += (tnodeSize + sizeof(__u32)) * (dev->nTnodesCreated - dev->nFreeTnodes);
+ nBytes += sizeof(yaffs_CheckpointValidity);
+ nBytes += sizeof(__u32); /* checksum*/
+
+ /* Round up and add 2 blocks to allow for some bad blocks, so add 3 */
+
+ nBlocks = (nBytes/(dev->nDataBytesPerChunk * dev->nChunksPerBlock)) + 3;
+
+ dev->nCheckpointBlocksRequired = nBlocks;
+ }
+
+ return dev->nCheckpointBlocksRequired;
+}
+
// 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 reservedBlocks = dev->nReservedBlocks;
int checkpointBlocks;
- checkpointBlocks = dev->nCheckpointReservedBlocks - dev->blocksInCheckpoint;
+ checkpointBlocks = yaffs_CalcCheckpointBlocksRequired(dev) - dev->blocksInCheckpoint;
if(checkpointBlocks < 0)
checkpointBlocks = 0;
do {
maxTries++;
- checkpointBlockAdjust = (dev->nCheckpointReservedBlocks - dev->blocksInCheckpoint);
+ checkpointBlockAdjust = yaffs_CalcCheckpointBlocksRequired(dev) - dev->blocksInCheckpoint;
if(checkpointBlockAdjust < 0)
checkpointBlockAdjust = 0;
int i;
yaffs_Device *dev = in->myDev;
int ok = 1;
- int nTnodeBytes = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
+ int tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
+
+ if(tnodeSize < sizeof(yaffs_Tnode))
+ tnodeSize = sizeof(yaffs_Tnode);
+
if (tn) {
if (level > 0) {
/* printf("write tnode at %d\n",baseOffset); */
ok = (yaffs_CheckpointWrite(dev,&baseOffset,sizeof(baseOffset)) == sizeof(baseOffset));
if(ok)
- ok = (yaffs_CheckpointWrite(dev,tn,nTnodeBytes) == nTnodeBytes);
+ ok = (yaffs_CheckpointWrite(dev,tn,tnodeSize) == tnodeSize);
}
}
yaffs_FileStructure *fileStructPtr = &obj->variant.fileVariant;
yaffs_Tnode *tn;
int nread = 0;
-
+ int tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
+
+ if(tnodeSize < sizeof(yaffs_Tnode))
+ tnodeSize = sizeof(yaffs_Tnode);
+
ok = (yaffs_CheckpointRead(dev,&baseChunk,sizeof(baseChunk)) == sizeof(baseChunk));
while(ok && (~baseChunk)){
/* printf("read tnode at %d\n",baseChunk); */
tn = yaffs_GetTnodeRaw(dev);
if(tn)
- ok = (yaffs_CheckpointRead(dev,tn,(dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8) ==
- (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8);
+ ok = (yaffs_CheckpointRead(dev,tn,tnodeSize) == tnodeSize);
else
ok = 0;
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;
+ blocksForCheckpoint = yaffs_CalcCheckpointBlocksRequired(dev) - dev->blocksInCheckpoint;
if(blocksForCheckpoint < 0)
blocksForCheckpoint = 0;