Changes to allow usage of block zero
authorcharles <charles>
Sat, 25 Jun 2005 03:22:23 +0000 (03:22 +0000)
committercharles <charles>
Sat, 25 Jun 2005 03:22:23 +0000 (03:22 +0000)
direct/yaffscfg.c
yaffs_fs.c
yaffs_guts.c
yaffs_guts.h

index 83f2277..dfa1b13 100644 (file)
@@ -74,7 +74,7 @@ int yaffs_StartUp(void)
        ramDev.nBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
        ramDev.nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
        ramDev.nReservedBlocks = 2; // Set this smaller for RAM
-       ramDev.startBlock = 1; // Can't use block 0
+       ramDev.startBlock = 0; // Can now use block zero
        ramDev.endBlock = 127; // Last block in 2MB.    
        ramDev.useNANDECC = 1;
        ramDev.nShortOpCaches = 0;      // Disable caching on this device.
@@ -88,7 +88,7 @@ int yaffs_StartUp(void)
        bootDev.nBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
        bootDev.nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
        bootDev.nReservedBlocks = 5;
-       bootDev.startBlock = 1; // Can't use block 0
+       bootDev.startBlock = 0; // Can now use block zero
        bootDev.endBlock = 127; // Last block in 2MB.   
        bootDev.useNANDECC = 0; // use YAFFS's ECC
        bootDev.nShortOpCaches = 10; // Use caches
index 86a2559..715a71b 100644 (file)
@@ -29,7 +29,7 @@
  */
 
 
-const char *yaffs_fs_c_version = "$Id: yaffs_fs.c,v 1.39 2005-04-24 08:54:36 charles Exp $";
+const char *yaffs_fs_c_version = "$Id: yaffs_fs.c,v 1.40 2005-06-25 03:22:23 charles Exp $";
 extern const char *yaffs_guts_c_version;
 
 
@@ -1326,7 +1326,7 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl
                dev->genericDevice = NULL; // Not used for RAM emulation.
 
                nBlocks = YAFFS_RAM_EMULATION_SIZE / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
-               dev->startBlock = 1;  // Don't use block 0
+               dev->startBlock = 0;
                dev->endBlock = nBlocks - 1;
                dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
                dev->nBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
@@ -1426,7 +1426,7 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl
                // Set up the memory size parameters....
                
                nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
-               dev->startBlock = 1;  // Don't use block 0
+               dev->startBlock = 0;
                dev->endBlock = nBlocks - 1;
                dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
                dev->nBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
index e4a61c0..8f09a10 100644 (file)
@@ -14,7 +14,7 @@
  */
  //yaffs_guts.c
 
-const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.41 2005-04-24 08:54:36 charles Exp $";
+const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.42 2005-06-25 03:22:23 charles Exp $";
 
 #include "yportenv.h"
 
@@ -120,12 +120,12 @@ static void yaffs_InvalidateChunkCache(yaffs_Object *object, int chunkId);
 
 static __inline __u8 *yaffs_BlockBits(yaffs_Device *dev, int blk)
 {
-       if(blk < dev->startBlock || blk > dev->endBlock)
+       if(blk < dev->internalStartBlock || blk > dev->internalEndBlock)
        {
                T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs: BlockBits block %d is not valid" TENDSTR),blk));
                YBUG();
        }
-       return dev->chunkBits + (dev->chunkBitmapStride * (blk - dev->startBlock));
+       return dev->chunkBits + (dev->chunkBitmapStride * (blk - dev->internalStartBlock));
 }
 
 static __inline__ void yaffs_ClearChunkBits(yaffs_Device *dev,int blk)
@@ -170,12 +170,12 @@ static __inline__ int yaffs_StillSomeChunkBits(yaffs_Device *dev,int blk)
 // Function to manipulate block info
 static  __inline__ yaffs_BlockInfo* yaffs_GetBlockInfo(yaffs_Device *dev, int blk)
 {
-       if(blk < dev->startBlock || blk > dev->endBlock)
+       if(blk < dev->internalStartBlock || blk > dev->internalEndBlock)
        {
                T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs: getBlockInfo block %d is not valid" TENDSTR),blk));
                YBUG();
        }
-       return &dev->blockInfo[blk - dev->startBlock];
+       return &dev->blockInfo[blk - dev->internalStartBlock];
 }
 
 
@@ -198,14 +198,14 @@ yaffs_Object *yaffs_LostNFound(yaffs_Device *dev)
 
 static int yaffs_WriteChunkToNAND(struct yaffs_DeviceStruct *dev,int chunkInNAND, const __u8 *data, yaffs_Spare *spare)
 {
-       if(chunkInNAND < dev->startBlock * dev->nChunksPerBlock)
+       if(chunkInNAND < dev->internalStartBlock * dev->nChunksPerBlock)
        {
                T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs chunk %d is not valid" TENDSTR),chunkInNAND));
                return YAFFS_FAIL;
        }
 
        dev->nPageWrites++;
-       return dev->writeChunkToNAND(dev,chunkInNAND,data,spare);
+       return dev->writeChunkToNAND(dev,chunkInNAND - dev->chunkOffset,data,spare);
 }
 
 
@@ -234,7 +234,7 @@ int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,
 
        if(!dev->useNANDECC)
        {
-               retVal  = dev->readChunkFromNAND(dev,chunkInNAND,data,spare);
+               retVal  = dev->readChunkFromNAND(dev,chunkInNAND - dev->chunkOffset,data,spare);
                if(data && doErrorCorrection)
                {
                        // Do ECC correction
@@ -249,23 +249,23 @@ int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,
 
                        if(eccResult1>0)
                        {
-                               T(YAFFS_TRACE_ERROR, (TSTR("**>>ecc error fix performed on chunk %d:0" TENDSTR),chunkInNAND));
+                               T(YAFFS_TRACE_ERROR, (TSTR("**>>ecc error fix performed on chunk %d:0" TENDSTR),chunkInNAND - dev->chunkOffset));
                                dev->eccFixed++;
                        }
                        else if(eccResult1<0)
                        {
-                               T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:0" TENDSTR),chunkInNAND));
+                               T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:0" TENDSTR),chunkInNAND - dev->chunkOffset));
                                dev->eccUnfixed++;
                        }
 
                        if(eccResult2>0)
                        {
-                               T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error fix performed on chunk %d:1" TENDSTR),chunkInNAND));
+                               T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error fix performed on chunk %d:1" TENDSTR),chunkInNAND - dev->chunkOffset));
                                dev->eccFixed++;
                        }
                        else if(eccResult2<0)
                        {
-                               T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:1" TENDSTR),chunkInNAND));
+                               T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:1" TENDSTR),chunkInNAND - dev->chunkOffset));
                                dev->eccUnfixed++;
                        }
 
@@ -280,26 +280,26 @@ int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,
        {
         // Must allocate enough memory for spare+2*sizeof(int) for ecc results from device.
        struct yaffs_NANDSpare nspare;
-               retVal  = dev->readChunkFromNAND(dev,chunkInNAND,data,(yaffs_Spare*)&nspare);
+               retVal  = dev->readChunkFromNAND(dev,chunkInNAND - dev->chunkOffset,data,(yaffs_Spare*)&nspare);
                memcpy (spare, &nspare, sizeof(yaffs_Spare));
                if(data && doErrorCorrection)
                {
                        if(nspare.eccres1>0)
                        {
-                               T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error fix performed on chunk %d:0" TENDSTR),chunkInNAND));
+                               T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error fix performed on chunk %d:0" TENDSTR),chunkInNAND - dev->chunkOffset));
                        }
                        else if(nspare.eccres1<0)
                        {
-                               T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:0" TENDSTR),chunkInNAND));
+                               T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:0" TENDSTR),chunkInNAND - dev->chunkOffset));
                        }
 
                        if(nspare.eccres2>0)
                        {
-                               T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error fix performed on chunk %d:1" TENDSTR),chunkInNAND));
+                               T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error fix performed on chunk %d:1" TENDSTR),chunkInNAND - dev->chunkOffset));
                        }
                        else if(nspare.eccres2<0)
                        {
-                               T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:1" TENDSTR),chunkInNAND));
+                               T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:1" TENDSTR),chunkInNAND - dev->chunkOffset));
                        }
 
                        if(nspare.eccres1 || nspare.eccres2)
@@ -323,7 +323,7 @@ static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,int chunkInNAND
     // Might as well always allocate the larger size for dev->useNANDECC == true;
        static __u8 spare[sizeof(struct yaffs_NANDSpare)];      
 
-       dev->readChunkFromNAND(dev,chunkInNAND,data,(yaffs_Spare *)spare);
+       dev->readChunkFromNAND(dev,chunkInNAND - dev->chunkOffset,data,(yaffs_Spare *)spare);
        
        if(!init)
        {
@@ -344,7 +344,7 @@ static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,int chunkInNAND
 int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,int blockInNAND)
 {
        dev->nBlockErasures++;
-       return dev->eraseBlockInNAND(dev,blockInNAND);
+       return dev->eraseBlockInNAND(dev,blockInNAND - dev->blockOffset);
 }
 
 int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev)
@@ -2054,11 +2054,11 @@ static int yaffs_FindDirtiestBlock(yaffs_Device *dev,int aggressive)
        pagesInUse = (aggressive)? dev->nChunksPerBlock : YAFFS_PASSIVE_GC_CHUNKS + 1;
        if(aggressive)
        {
-               iterations = dev->endBlock - dev->startBlock + 1;
+               iterations = dev->internalEndBlock - dev->internalStartBlock + 1;
        }
        else
        {
-               iterations = dev->endBlock - dev->startBlock + 1;
+               iterations = dev->internalEndBlock - dev->internalStartBlock + 1;
                iterations = iterations / 16;
                if(iterations > 200)
                {
@@ -2069,12 +2069,12 @@ static int yaffs_FindDirtiestBlock(yaffs_Device *dev,int aggressive)
        for(i = 0; i <= iterations && pagesInUse > 0 ; i++)
        {
                b++;
-               if ( b < dev->startBlock || b > dev->endBlock)
+               if ( b < dev->internalStartBlock || b > dev->internalEndBlock)
                {
-                       b =  dev->startBlock;
+                       b =  dev->internalStartBlock;
                }
 
-               if(b < dev->startBlock || b > dev->endBlock)
+               if(b < dev->internalStartBlock || b > dev->internalEndBlock)
                {
                        T(YAFFS_TRACE_ERROR,(TSTR("**>> Block %d is not valid" TENDSTR),b));
                        YBUG();
@@ -2151,12 +2151,12 @@ static int yaffs_FindBlockForAllocation(yaffs_Device *dev)
        
        // Find an empty block.
        
-       for(i = dev->startBlock; i <= dev->endBlock; i++)
+       for(i = dev->internalStartBlock; i <= dev->internalEndBlock; i++)
        {
                dev->allocationBlockFinder++;
-               if(dev->allocationBlockFinder <dev->startBlock || dev->allocationBlockFinder> dev->endBlock) 
+               if(dev->allocationBlockFinder <dev->internalStartBlock || dev->allocationBlockFinder> dev->internalEndBlock) 
                {
-                       dev->allocationBlockFinder = dev->startBlock;
+                       dev->allocationBlockFinder = dev->internalStartBlock;
                }
                
                bi = yaffs_GetBlockInfo(dev,dev->allocationBlockFinder);
@@ -3674,7 +3674,7 @@ int yaffs_ResizeFile(yaffs_Object *in, int newSize)
                        // using yaffs_DeleteChunk
 
                        chunkId = yaffs_FindAndDeleteChunkInFile(in,i,NULL);
-                       if(chunkId < (dev->startBlock * 32) || chunkId >= ((dev->endBlock+1) * 32))
+                       if(chunkId < (dev->internalStartBlock * 32) || chunkId >= ((dev->internalEndBlock+1) * 32))
                        {
                                //T(("Found daft chunkId %d for %d\n",chunkId,i));
                        }
@@ -4068,7 +4068,7 @@ static int yaffs_Scan(yaffs_Device *dev)
        
        // Scan all the blocks...
        
-       for(blk = dev->startBlock; blk <= dev->endBlock; blk++)
+       for(blk = dev->internalStartBlock; blk <= dev->internalEndBlock; blk++)
        {
                deleted = 0;
                bi = yaffs_GetBlockInfo(dev,blk);
@@ -4700,13 +4700,13 @@ int yaffs_GutsInitialise(yaffs_Device *dev)
        if(     dev->nBytesPerChunk != YAFFS_BYTES_PER_CHUNK || 
                dev->nChunksPerBlock < 2 ||
                dev->nReservedBlocks < 2 ||
-               dev->startBlock <= 0 ||
+               dev->startBlock < 0 ||
                dev->endBlock <= 0 ||
                dev->endBlock <= (dev->startBlock + dev->nReservedBlocks)
          )
        {
                //these parameters must be set before stating yaffs
-               // Other parameters startBlock,
+               // Other parameters internalStartBlock,
                return YAFFS_FAIL;
        }
 
@@ -4725,8 +4725,8 @@ int yaffs_GutsInitialise(yaffs_Device *dev)
        }
 
        dev->isMounted = 1;
-       
-       if(dev->startBlock <= 0 ||
+
+       if(dev->startBlock < 0 ||
           (dev->endBlock - dev->startBlock) < 10)
        {
                T(YAFFS_TRACE_ALWAYS,(TSTR("startBlock %d or endBlock %d invalid\n" TENDSTR),
@@ -4734,15 +4734,32 @@ int yaffs_GutsInitialise(yaffs_Device *dev)
                return YAFFS_FAIL;
        }
        
-       nBlocks = dev->endBlock - dev->startBlock + 1;
+       
+       // Do we need to add an offset to use block 0?
+       
+       dev->internalStartBlock = dev->startBlock;
+       dev->internalEndBlock = dev->endBlock;
+       dev->blockOffset = 0;
+       dev->chunkOffset = 0;
+       
+       if(dev->startBlock == 0)
+       {
+               dev->internalStartBlock++;
+               dev->internalEndBlock++;
+               dev->blockOffset++;
+               dev->chunkOffset = dev->nChunksPerBlock;                
+       }
+       
+       
+       nBlocks = dev->internalEndBlock - dev->internalStartBlock + 1;
        
 
                
        // OK now calculate a few things for the device
        // Calculate chunkGroupBits. 
-       // We need to find the next power of 2 > than endBlock
+       // We need to find the next power of 2 > than internalEndBlock
        
-       x = dev->nChunksPerBlock * (dev->endBlock+1);
+       x = dev->nChunksPerBlock * (dev->internalEndBlock+1);
        
        for(bits = extraBits = 0; x > 1; bits++)
        {
@@ -4914,7 +4931,7 @@ int  yaffs_GetNumberOfFreeChunks(yaffs_Device *dev)
        struct list_head *i;    
        yaffs_Object *l;
        
-       for(nFree = 0, b = dev->startBlock; b <= dev->endBlock; b++)
+       for(nFree = 0, b = dev->internalStartBlock; b <= dev->internalEndBlock; b++)
        {
                blk = yaffs_GetBlockInfo(dev,b);
                
index 03f8d0d..3728722 100644 (file)
@@ -14,7 +14,7 @@
  *
  * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
  *
- * $Id: yaffs_guts.h,v 1.19 2005-03-29 22:43:38 charles Exp $
+ * $Id: yaffs_guts.h,v 1.20 2005-06-25 03:22:24 charles Exp $
  */
 
 #ifndef __YAFFS_GUTS_H__
@@ -398,7 +398,7 @@ struct yaffs_DeviceStruct
 {
        // Entry parameters set up way early. Yaffs sets up the rest.
        int   nBytesPerChunk;    // Should be a power of 2 >= 512
-       int       nChunksPerBlock;       // does not need to be a power of 2
+       int   nChunksPerBlock;   // does not need to be a power of 2
        int   startBlock;                // Start block we're allowed to use
        int   endBlock;                  // End block we're allowed to use
        int   nReservedBlocks;   // We want this tuneable so that we can reduce
@@ -420,6 +420,11 @@ struct yaffs_DeviceStruct
        int (*initialiseNAND)(struct yaffs_DeviceStruct *dev);
 
        // Runtime parameters. Set up by YAFFS.
+       int   internalStartBlock;                // Internal version of startBlock
+       int   internalEndBlock;                  // End block we're allowed to use
+       int   blockOffset;
+       int   chunkOffset;
+       
        
        __u16 chunkGroupBits; // 0 for devices <= 32MB. else log2(nchunks) - 16
        __u16 chunkGroupSize; // == 2^^chunkGroupBits