Change checkpoint to calculate number of blocks required instead of using a hardcoded...
authorcharles <charles>
Mon, 3 Dec 2007 03:21:48 +0000 (03:21 +0000)
committercharles <charles>
Mon, 3 Dec 2007 03:21:48 +0000 (03:21 +0000)
Kconfig
direct/yaffscfg.c
direct/yaffscfg2k.c
yaffs_fs.c
yaffs_guts.c
yaffs_guts.h

diff --git a/Kconfig b/Kconfig
index 272df72..b2b3bc5 100644 (file)
--- 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"
index b1d311e..dd95a74 100644 (file)
@@ -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
index 6d5f542..2c95409 100644 (file)
@@ -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;
 }
 
index e572301..583fe99 100644 (file)
@@ -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 <linux/version.h>
@@ -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);
index c29c1f9..cad48e6 100644 (file)
@@ -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;
                
index 87b539b..6251f9a 100644 (file)
@@ -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 */