From e721e0888655c325e5d5477ae121ff325f2847c0 Mon Sep 17 00:00:00 2001 From: charles Date: Mon, 3 Dec 2007 03:21:48 +0000 Subject: [PATCH] Change checkpoint to calculate number of blocks required instead of using a hardcoded value --- Kconfig | 20 ------------ direct/yaffscfg.c | 6 ++-- direct/yaffscfg2k.c | 3 +- yaffs_fs.c | 4 +-- yaffs_guts.c | 78 +++++++++++++++++++++++++++++++++++++++------ yaffs_guts.h | 4 ++- 6 files changed, 76 insertions(+), 39 deletions(-) diff --git a/Kconfig b/Kconfig index 272df72..b2b3bc5 100644 --- a/Kconfig +++ b/Kconfig @@ -110,26 +110,6 @@ config YAFFS_DISABLE_LAZY_LOAD 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" diff --git a/direct/yaffscfg.c b/direct/yaffscfg.c index b1d311e..dd95a74 100644 --- a/direct/yaffscfg.c +++ b/direct/yaffscfg.c @@ -93,7 +93,7 @@ int yaffs_StartUp(void) // Set up devices // /ram - ramDev.nBytesPerChunk = 512; + ramDev.nDataBytesPerChunk = 512; ramDev.nChunksPerBlock = 32; ramDev.nReservedBlocks = 2; // Set this smaller for RAM ramDev.startBlock = 1; // Can't use block 0 @@ -107,7 +107,7 @@ int yaffs_StartUp(void) ramDev.initialiseNAND = yramdisk_InitialiseNAND; // /boot - bootDev.nBytesPerChunk = 612; + bootDev.nDataBytesPerChunk = 512; bootDev.nChunksPerBlock = 32; bootDev.nReservedBlocks = 5; bootDev.startBlock = 1; // Can't use block 0 @@ -121,7 +121,7 @@ int yaffs_StartUp(void) bootDev.initialiseNAND = yflash_InitialiseNAND; // /flash - flashDev.nBytesPerChunk = 512; + flashDev.nDataBytesPerChunk = 512; flashDev.nChunksPerBlock = 32; flashDev.nReservedBlocks = 5; flashDev.startBlock = 128; // First block after 2MB diff --git a/direct/yaffscfg2k.c b/direct/yaffscfg2k.c index 6d5f542..2c95409 100644 --- a/direct/yaffscfg2k.c +++ b/direct/yaffscfg2k.c @@ -176,7 +176,6 @@ int yaffs_StartUp(void) flashDev.nDataBytesPerChunk = 2048; flashDev.nChunksPerBlock = 64; flashDev.nReservedBlocks = 5; - flashDev.nCheckpointReservedBlocks = 5; //flashDev.checkpointStartBlock = 1; //flashDev.checkpointEndBlock = 20; flashDev.startBlock = 0; @@ -224,6 +223,6 @@ int yaffs_StartUp(void) void SetCheckpointReservedBlocks(int n) { - flashDev.nCheckpointReservedBlocks = n; +// flashDev.nCheckpointReservedBlocks = n; } diff --git a/yaffs_fs.c b/yaffs_fs.c index e572301..583fe99 100644 --- a/yaffs_fs.c +++ b/yaffs_fs.c @@ -32,7 +32,7 @@ */ 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 @@ -1807,7 +1807,6 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion, #endif nBlocks = mtd->size / mtd->erasesize; - dev->nCheckpointReservedBlocks = CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS; dev->startBlock = 0; dev->endBlock = nBlocks - 1; } else { @@ -1995,7 +1994,6 @@ static char *yaffs_dump_dev(char *buf, yaffs_Device * dev) 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); diff --git a/yaffs_guts.c b/yaffs_guts.c index c29c1f9..cad48e6 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.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" @@ -1146,6 +1146,10 @@ static int yaffs_CreateTnodes(yaffs_Device * dev, int nTnodes) * 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); @@ -1236,15 +1240,21 @@ static yaffs_Tnode *yaffs_GetTnodeRaw(yaffs_Device * dev) 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; } @@ -1265,6 +1275,8 @@ static void yaffs_FreeTnode(yaffs_Device * dev, yaffs_Tnode * tn) dev->freeTnodes = tn; dev->nFreeTnodes++; } + dev->nCheckpointBlocksRequired = 0; /* force recalculation*/ + } static void yaffs_DeinitialiseTnodes(yaffs_Device * dev) @@ -1909,6 +1921,8 @@ static yaffs_Object *yaffs_AllocateEmptyObject(yaffs_Device * dev) yaffs_AddObjectToDirectory(dev->lostNFoundDir, tn); } } + + dev->nCheckpointBlocksRequired = 0; /* force recalculation*/ return tn; } @@ -1970,6 +1984,9 @@ static void yaffs_FreeObject(yaffs_Object * tn) tn->siblings.next = (struct list_head *)(dev->freeObjects); dev->freeObjects = tn; dev->nFreeObjects++; + + dev->nCheckpointBlocksRequired = 0; /* force recalculation*/ + } #ifdef __KERNEL__ @@ -2804,6 +2821,40 @@ static int yaffs_FindBlockForAllocation(yaffs_Device * dev) } + +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) @@ -2812,7 +2863,7 @@ 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; @@ -3145,7 +3196,7 @@ static int yaffs_CheckGarbageCollection(yaffs_Device * dev) do { maxTries++; - checkpointBlockAdjust = (dev->nCheckpointReservedBlocks - dev->blocksInCheckpoint); + checkpointBlockAdjust = yaffs_CalcCheckpointBlocksRequired(dev) - dev->blocksInCheckpoint; if(checkpointBlockAdjust < 0) checkpointBlockAdjust = 0; @@ -4223,7 +4274,11 @@ static int yaffs_CheckpointTnodeWorker(yaffs_Object * in, yaffs_Tnode * tn, 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) { @@ -4241,7 +4296,7 @@ static int yaffs_CheckpointTnodeWorker(yaffs_Object * in, yaffs_Tnode * tn, /* 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); } } @@ -4275,7 +4330,11 @@ static int yaffs_ReadCheckpointTnodes(yaffs_Object *obj) 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)){ @@ -4286,8 +4345,7 @@ static int yaffs_ReadCheckpointTnodes(yaffs_Object *obj) /* 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; @@ -7415,7 +7473,7 @@ int yaffs_GetNumberOfFreeChunks(yaffs_Device * dev) 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; diff --git a/yaffs_guts.h b/yaffs_guts.h index 87b539b..6251f9a 100644 --- a/yaffs_guts.h +++ b/yaffs_guts.h @@ -544,7 +544,7 @@ struct yaffs_DeviceStruct { /* Stuff used by the shared space checkpointing mechanism */ /* If this value is zero, then this mechanism is disabled */ - int nCheckpointReservedBlocks; /* Blocks to reserve for checkpoint data */ +// int nCheckpointReservedBlocks; /* Blocks to reserve for checkpoint data */ @@ -663,6 +663,8 @@ struct yaffs_DeviceStruct { __u32 checkpointSum; __u32 checkpointXor; + int nCheckpointBlocksRequired; /* Number of blocks needed to store current checkpoint set */ + /* Block Info */ yaffs_BlockInfo *blockInfo; __u8 *chunkBits; /* bitmap of chunks in use */ -- 2.30.2