*** empty log message ***
authorcharles <charles>
Fri, 17 Jan 2003 04:19:08 +0000 (04:19 +0000)
committercharles <charles>
Fri, 17 Jan 2003 04:19:08 +0000 (04:19 +0000)
yaffs_fs.c
yaffs_guts.c
yaffs_guts.h
yaffs_mtdif.c
yportenv.h

index 1f4f5b866fda28e3de6619506d721be107ee5795..de7ee00f00b2d869c9f80a00187ca4acdb73c150 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 
-const char *yaffs_fs_c_version = "$Id: yaffs_fs.c,v 1.22 2003-01-14 23:15:29 charles Exp $";
+const char *yaffs_fs_c_version = "$Id: yaffs_fs.c,v 1.23 2003-01-17 04:19:08 charles Exp $";
 extern const char *yaffs_guts_c_version;
 
 
@@ -1155,6 +1155,8 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl
                nBlocks = YAFFS_RAM_EMULATION_SIZE / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
                dev->startBlock = 1;  // Don't use block 0
                dev->endBlock = nBlocks - 1;
+               dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
+               dev->nBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
 
                dev->writeChunkToNAND = nandemul_WriteChunkToNAND;
                dev->readChunkFromNAND = nandemul_ReadChunkFromNAND;
@@ -1239,6 +1241,9 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl
                nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
                dev->startBlock = 1;  // Don't use block 0
                dev->endBlock = nBlocks - 1;
+               dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
+               dev->nBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
+               
 
                // ... and the functions.
                dev->writeChunkToNAND = nandmtd_WriteChunkToNAND;
@@ -1331,6 +1336,7 @@ static char * yaffs_dump_dev(char *buf,yaffs_Device *dev,char *name)
        buf +=sprintf(buf,"nBlockErasures..... %d\n",dev->nBlockErasures);
        buf +=sprintf(buf,"nGCCopies.......... %d\n",dev->nGCCopies);
        buf +=sprintf(buf,"garbageCollections. %d\n",dev->garbageCollections);
+       buf +=sprintf(buf,"passiveGCs......... %d\n",dev->passiveGarbageCollections);
        buf +=sprintf(buf,"nRetriedWrites..... %d\n",dev->nRetriedWrites);
        buf +=sprintf(buf,"nRetireBlocks...... %d\n",dev->nRetiredBlocks);
        buf +=sprintf(buf,"eccFixed........... %d\n",dev->eccFixed);
index bb714e01bcc79b6bc5df98f490545b8556a7fbcb..47059771ef3727dd21f413947425f20a1a85ec63 100644 (file)
@@ -14,7 +14,7 @@
  */
  //yaffs_guts.c
 
-const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.16 2003-01-14 23:15:29 charles Exp $";
+const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.17 2003-01-17 04:19:08 charles Exp $";
 
 #include "yportenv.h"
 
@@ -22,9 +22,9 @@ const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.16 2003-01-14 23:15:29 c
 #include "yaffs_guts.h"
 
 
-#define YAFFS_GARBAGE_COLLECT_LOW_WATER 2
 
 
+#define YAFFS_PASSIVE_GC_CHUNKS 2
 
 // External functions for ECC on data
 void nand_calculate_ecc (const u_char *dat, u_char *ecc_code);
@@ -195,7 +195,7 @@ 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 * YAFFS_CHUNKS_PER_BLOCK)
+       if(chunkInNAND < dev->startBlock * dev->nChunksPerBlock)
        {
                T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs chunk %d is not valid" TENDSTR),chunkInNAND));
                return YAFFS_FAIL;
@@ -438,8 +438,9 @@ static void yaffs_RetireBlock(yaffs_Device *dev,int blockInNAND)
 
        spare.blockStatus = 0;
        
-       yaffs_WriteChunkToNAND(dev, blockInNAND * YAFFS_CHUNKS_PER_BLOCK, NULL , &spare);
-       yaffs_WriteChunkToNAND(dev, blockInNAND * YAFFS_CHUNKS_PER_BLOCK + 1, NULL , &spare);
+       // TODO change this retirement marking for other NAND types
+       yaffs_WriteChunkToNAND(dev, blockInNAND * dev->nChunksPerBlock, NULL , &spare);
+       yaffs_WriteChunkToNAND(dev, blockInNAND * dev->nChunksPerBlock + 1, NULL , &spare);
        
        yaffs_GetBlockInfo(dev,blockInNAND)->blockState = YAFFS_BLOCK_STATE_DEAD;
        dev->nRetiredBlocks++;
@@ -463,7 +464,7 @@ static int yaffs_RewriteBufferedBlock(yaffs_Device *dev)
 
 static void yaffs_HandleReadDataError(yaffs_Device *dev,int chunkInNAND)
 {
-       int blockInNAND = chunkInNAND/YAFFS_CHUNKS_PER_BLOCK;
+       int blockInNAND = chunkInNAND/dev->nChunksPerBlock;
 
        // Mark the block for retirement
        yaffs_GetBlockInfo(dev,blockInNAND)->needsRetiring = 1;
@@ -490,7 +491,7 @@ static void yaffs_HandleUpdateChunk(yaffs_Device *dev,int chunkInNAND, const yaf
 
 static void yaffs_HandleWriteChunkError(yaffs_Device *dev,int chunkInNAND)
 {
-       int blockInNAND = chunkInNAND/YAFFS_CHUNKS_PER_BLOCK;
+       int blockInNAND = chunkInNAND/dev->nChunksPerBlock;
 
        // Mark the block for retirement
        yaffs_GetBlockInfo(dev,blockInNAND)->needsRetiring = 1;
@@ -1150,7 +1151,7 @@ static int yaffs_SoftDeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level
                        {
                                        
                                        theChunk =  (tn->level0[i] << in->myDev->chunkGroupBits);
-                                       theBlock =      yaffs_GetBlockInfo(in->myDev,  theChunk/ YAFFS_CHUNKS_PER_BLOCK);
+                                       theBlock =      yaffs_GetBlockInfo(in->myDev,  theChunk/in->myDev->nChunksPerBlock);
                                        if(theBlock)
                                        {
                                                theBlock->softDeletions++;
@@ -1541,7 +1542,7 @@ static int yaffs_CreateNewObjectNumber(yaffs_Device *dev)
                        list_for_each(i,&dev->objectBucket[bucket].list)
                        {
                                // If there is already one in the list
-                               if(list_entry(i, yaffs_Object,hashLink)->objectId == n)
+                               if(i && list_entry(i, yaffs_Object,hashLink)->objectId == n)
                                {
                                        found = 0;
                                }
@@ -1579,10 +1580,13 @@ yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device *dev,__u32 number)
        list_for_each(i,&dev->objectBucket[bucket].list)
        {
                // Look if it is in the list
-               in = list_entry(i, yaffs_Object,hashLink);
-               if(in->objectId == number)
+               if(i)
                {
-                       return in;
+                       in = list_entry(i, yaffs_Object,hashLink);
+                       if(in->objectId == number)
+                       {
+                               return in;
+                       }
                }
        }
        
@@ -1987,17 +1991,35 @@ static void yaffs_DeinitialiseBlocks(yaffs_Device *dev)
 // FindDiretiestBlock is used to select the dirtiest block (or close enough)
 // for garbage collection.
 
-static int yaffs_FindDirtiestBlock(yaffs_Device *dev)
+static int yaffs_FindDirtiestBlock(yaffs_Device *dev,int aggressive)
 {
 
        int b = dev->currentDirtyChecker;
        
        int i;
+       int iterations;
        int dirtiest = -1;
-       int pagesInUse = dev->nChunksPerBlock
+       int pagesInUse; 
        yaffs_BlockInfo *bi;
+
+       // If we're doing aggressive GC then we are happy to take a less-dirty block, and
+       // search further.
+       
+       pagesInUse = (aggressive)? dev->nChunksPerBlock : YAFFS_PASSIVE_GC_CHUNKS + 1;
+       if(aggressive)
+       {
+               iterations = dev->endBlock - dev->startBlock + 1;
+       }
+       else
+       {
+               iterations = iterations / 16;
+               if(iterations > 200)
+               {
+                       iterations = 200;
+               }
+       }
        
-       for(i = dev->startBlock; i <= dev->endBlock && pagesInUse > 2 ; i++)
+       for(i = 0; i <= iterations && pagesInUse > 0 ; i++)
        {
                b++;
                if ( b < dev->startBlock || b > dev->endBlock)
@@ -2128,7 +2150,7 @@ static int yaffs_AllocateChunk(yaffs_Device *dev,int useReserve)
        {
                bi = yaffs_GetBlockInfo(dev,dev->allocationBlock);
                
-               retVal = (dev->allocationBlock * YAFFS_CHUNKS_PER_BLOCK) + 
+               retVal = (dev->allocationBlock * dev->nChunksPerBlock) + 
                                  dev->allocationPage;
                bi->pagesInUse++;
                yaffs_SetChunkBit(dev,dev->allocationBlock,dev->allocationPage);
@@ -2138,7 +2160,7 @@ static int yaffs_AllocateChunk(yaffs_Device *dev,int useReserve)
                dev->nFreeChunks--;
                
                // If the block is full set the state to full
-               if(dev->allocationPage >= YAFFS_CHUNKS_PER_BLOCK)
+               if(dev->allocationPage >= dev->nChunksPerBlock)
                {
                        bi->blockState = YAFFS_BLOCK_STATE_FULL;
                        dev->allocationBlock = -1;
@@ -2157,13 +2179,13 @@ static int yaffs_AllocateChunk(yaffs_Device *dev,int useReserve)
 // number of erased blocks.
 // The cache is allowed to use reserved blocks.
 
-int yaffs_CheckSpaceForChunkCache(yaffs_Device *dev)
+static int yaffs_CheckSpaceForChunkCache(yaffs_Device *dev)
 {
        return (dev->nErasedBlocks >= YAFFS_RESERVED_BLOCKS);
 }
 
 
-int  yaffs_GarbageCollectBlock(yaffs_Device *dev,int block)
+static int  yaffs_GarbageCollectBlock(yaffs_Device *dev,int block)
 {
        int oldChunk;
        int newChunk;
@@ -2173,7 +2195,7 @@ int  yaffs_GarbageCollectBlock(yaffs_Device *dev,int block)
        
        yaffs_Spare spare;
        yaffs_Tags  tags;
-               __u8  buffer[YAFFS_BYTES_PER_CHUNK];
+       __u8  buffer[YAFFS_BYTES_PER_CHUNK];
        
 //     yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,block);
        
@@ -2181,7 +2203,7 @@ int  yaffs_GarbageCollectBlock(yaffs_Device *dev,int block)
 
        //T(("Collecting block %d n %d bits %x\n",block, bi->pagesInUse, bi->pageBits));        
        
-       for(chunkInBlock = 0,oldChunk = block * YAFFS_CHUNKS_PER_BLOCK
+       for(chunkInBlock = 0,oldChunk = block * dev->nChunksPerBlock
            chunkInBlock < dev->nChunksPerBlock && yaffs_StillSomeChunkBits(dev,block);
            chunkInBlock++, oldChunk++ )
        {
@@ -2281,10 +2303,13 @@ static yaffs_Object *yaffs_FindDeletedUnlinkedFile(yaffs_Device *dev)
        //Scan the unlinked files looking for one to delete
        list_for_each(i,&dev->unlinkedDir->variant.directoryVariant.children)
        {
-               l = list_entry(i, yaffs_Object,siblings);
-               if(l->deleted)
+               if(i)
                {
-                       return l;                       
+                       l = list_entry(i, yaffs_Object,siblings);
+                       if(l->deleted)
+                       {
+                               return l;                       
+                       }
                }
        }       
        return NULL;
@@ -2328,33 +2353,27 @@ static void yaffs_DoUnlinkedFileDeletion(yaffs_Device *dev)
 }
 
 
-
+#if 0
+#define YAFFS_GARBAGE_COLLECT_LOW_WATER 2
 static int yaffs_CheckGarbageCollection(yaffs_Device *dev)
 {
        int block;
+       int aggressive=0;
        
        //yaffs_DoUnlinkedFileDeletion(dev);
        
        if(dev->nErasedBlocks <= (YAFFS_RESERVED_BLOCKS + YAFFS_GARBAGE_COLLECT_LOW_WATER))
        {
-               dev->garbageCollectionRequired = 1;
-       }       
+               aggressive = 1;
+       }               
        
-       if(dev->garbageCollectionRequired)
+       if(aggressive)
        {
-               dev->garbageCollections++;
-               dev->garbageCollectionRequired = 0;
-               if(dev->blockSelectedForGC >= 0)
-               {
-                       block = dev->blockSelectedForGC;
-               }
-               else
-               {
-                       block = yaffs_FindDirtiestBlock(dev);
-               }
+               block = yaffs_FindDirtiestBlock(dev,aggressive);
                
                if(block >= 0)
                {
+                       dev->garbageCollections++;
                        return yaffs_GarbageCollectBlock(dev,block);
                }       
                else
@@ -2365,6 +2384,46 @@ static int yaffs_CheckGarbageCollection(yaffs_Device *dev)
 
        return YAFFS_OK;
 }
+#endif
+
+// New garbage collector
+// If we're very low on erased blocks then we do aggressive garbage collection
+// otherwise we do "passive" garbage collection.
+// Aggressive gc looks further (whole array) and will accept dirtier blocks.
+// Passive gc only inspects smaller areas and will only accept cleaner blocks.
+//
+// The idea is to help clear out space in a more spread-out manner.
+// Dunno if it really does anything useful.
+//
+static int yaffs_CheckGarbageCollection(yaffs_Device *dev)
+{
+       int block;
+       int aggressive=0;
+       
+       //yaffs_DoUnlinkedFileDeletion(dev);
+       
+       if(dev->nErasedBlocks <= (YAFFS_RESERVED_BLOCKS + 1))
+       {
+               aggressive = 1;
+       }               
+       
+       block = yaffs_FindDirtiestBlock(dev,aggressive);
+       
+       if(block >= 0)
+       {
+               dev->garbageCollections++;
+               if(!aggressive)
+               {
+                       dev->passiveGarbageCollections++;
+               }
+
+               T(YAFFS_TRACE_GC,(TSTR("yaffs: GC erasedBlocks %d aggressive %d" TENDSTR),dev->nErasedBlocks,aggressive));
+
+               return yaffs_GarbageCollectBlock(dev,block);
+       }       
+
+       return aggressive ? YAFFS_FAIL : YAFFS_OK;
+}
 
 
 //////////////////////////// TAGS ///////////////////////////////////////
@@ -2623,7 +2682,7 @@ static int yaffs_CheckFileSanity(yaffs_Object *in)
        
        objId = in->objectId;
        fSize  = in->variant.fileVariant.fileSize;
-       nChunks = (fSize + YAFFS_BYTES_PER_CHUNK -1)/YAFFS_BYTES_PER_CHUNK;
+       nChunks = (fSize + in->myDev->nBytesPerChunk -1)/in->myDev->nBytesPerChunk;
        
        for(chunk = 1; chunk <= nChunks; chunk++)
        {
@@ -2774,8 +2833,8 @@ static void yaffs_DeleteChunk(yaffs_Device *dev,int chunkId,int markNAND)
        if(chunkId <= 0) return;        
        
        dev->nDeletions++;
-       block = chunkId / YAFFS_CHUNKS_PER_BLOCK;
-       page = chunkId % YAFFS_CHUNKS_PER_BLOCK;
+       block = chunkId / dev->nChunksPerBlock;
+       page = chunkId % dev->nChunksPerBlock;
        
        if(markNAND)
        {
@@ -3605,7 +3664,7 @@ int yaffs_FlushFile(yaffs_Object *in, int updateTime)
 #endif
                }
 
-               retVal = yaffs_UpdateObjectHeader(in,NULL,0);
+               retVal = (yaffs_UpdateObjectHeader(in,NULL,0) >= 0)? YAFFS_OK : YAFFS_FAIL;
        }
        else
        {
@@ -3862,7 +3921,7 @@ static int yaffs_IsBlockBad(yaffs_Device *dev, int blk)
 {
        yaffs_Spare spare;
        
-       yaffs_ReadChunkFromNAND(dev,blk * YAFFS_CHUNKS_PER_BLOCK,NULL,&spare,1);
+       yaffs_ReadChunkFromNAND(dev,blk * dev->nChunksPerBlock,NULL,&spare,1);
 #if 1
        if(yaffs_CountBits(spare.blockStatus) < 7)
        {
@@ -3874,7 +3933,7 @@ static int yaffs_IsBlockBad(yaffs_Device *dev, int blk)
                return 1;
        }
 #endif
-       yaffs_ReadChunkFromNAND(dev,blk * YAFFS_CHUNKS_PER_BLOCK + 1,NULL,&spare,1);
+       yaffs_ReadChunkFromNAND(dev,blk * dev->nChunksPerBlock + 1,NULL,&spare,1);
 
 #if 1
        if(yaffs_CountBits(spare.blockStatus) < 7)
@@ -3933,11 +3992,11 @@ static int yaffs_Scan(yaffs_Device *dev)
                
                // Read each chunk in the block.
                
-               for(c = 0; c < YAFFS_CHUNKS_PER_BLOCK && 
+               for(c = 0; c < dev->nChunksPerBlock && 
                                   state == YAFFS_BLOCK_STATE_SCANNING; c++)
                {
                        // Read the spare area and decide what to do
-                       chunk = blk * YAFFS_CHUNKS_PER_BLOCK + c;
+                       chunk = blk * dev->nChunksPerBlock + c;
                        
                        yaffs_ReadChunkFromNAND(dev,chunk,NULL,&spare,1);
 
@@ -3973,7 +4032,7 @@ static int yaffs_Scan(yaffs_Device *dev)
                                        dev->allocationPage = c;
                                }
 
-                               dev->nFreeChunks += (YAFFS_CHUNKS_PER_BLOCK - c);
+                               dev->nFreeChunks += (dev->nChunksPerBlock - c);
                        }
                        else if(tags.chunkId > 0)
                        {
@@ -4191,14 +4250,19 @@ static int yaffs_Scan(yaffs_Device *dev)
        
        {
                struct list_head *i;    
+               struct list_head *n;
+                       
                yaffs_Object *l;
                // Soft delete all the unlinked files
-               list_for_each(i,&dev->unlinkedDir->variant.directoryVariant.children)
+               list_for_each_safe(i,n,&dev->unlinkedDir->variant.directoryVariant.children)
                {
-                       l = list_entry(i, yaffs_Object,siblings);
-                       if(l->deleted)
+                       if(i)
                        {
-                               yaffs_SoftDeleteFile(l);                
+                               l = list_entry(i, yaffs_Object,siblings);
+                               if(l->deleted)
+                               {
+                                       yaffs_SoftDeleteFile(l);                
+                               }
                        }
                }       
        }
@@ -4256,26 +4320,28 @@ yaffs_Object *yaffs_FindObjectByName(yaffs_Object *directory,const char *name)
        
        list_for_each(i,&directory->variant.directoryVariant.children)
        {
-               l = list_entry(i, yaffs_Object,siblings);
-               
-               // Special case for lost-n-found
-               if(l->objectId == YAFFS_OBJECTID_LOSTNFOUND)
+               if(i)
                {
-                       if(yaffs_strcmp(name,YAFFS_LOSTNFOUND_NAME) == 0)
+                       l = list_entry(i, yaffs_Object,siblings);
+               
+                       // Special case for lost-n-found
+                       if(l->objectId == YAFFS_OBJECTID_LOSTNFOUND)
                        {
-                               return l;
+                               if(yaffs_strcmp(name,YAFFS_LOSTNFOUND_NAME) == 0)
+                               {
+                                       return l;
+                               }
                        }
-               }
-               else if(yaffs_SumCompare(l->sum, sum))
-               {
-                       // Do a real check
-                       yaffs_GetObjectName(l,buffer,YAFFS_MAX_NAME_LENGTH);
-                       if(yaffs_strcmp(name,buffer) == 0)
+                       else if(yaffs_SumCompare(l->sum, sum))
                        {
-                               return l;
-                       }
-                       
+                               // Do a real check
+                               yaffs_GetObjectName(l,buffer,YAFFS_MAX_NAME_LENGTH);
+                               if(yaffs_strcmp(name,buffer) == 0)
+                               {
+                                       return l;
+                               }
                        
+                       }                       
                }
        }
        
@@ -4291,10 +4357,13 @@ int yaffs_ApplyToDirectoryChildren(yaffs_Object *theDir,int (*fn)(yaffs_Object *
        
        list_for_each(i,&theDir->variant.directoryVariant.children)
        {
-               l = list_entry(i, yaffs_Object,siblings);
-               if(!fn(l))
+               if(i)
                {
-                       return YAFFS_FAIL;
+                       l = list_entry(i, yaffs_Object,siblings);
+                       if(l && !fn(l))
+                       {
+                               return YAFFS_FAIL;
+                       }
                }
        }
        
@@ -4562,7 +4631,7 @@ int yaffs_GutsInitialise(yaffs_Device *dev)
        // Calculate chunkGroupBits. 
        // We need to find the next power of 2 > than endBlock
        
-       x = YAFFS_CHUNKS_PER_BLOCK * (dev->endBlock+1);
+       x = dev->nChunksPerBlock * (dev->endBlock+1);
        
        for(bits = extraBits = 0; x > 1; bits++)
        {
@@ -4592,12 +4661,11 @@ int yaffs_GutsInitialise(yaffs_Device *dev)
        
        
        // More device initialisation
-       dev->garbageCollectionRequired  = 0;
        dev->garbageCollections = 0;
+       dev->passiveGarbageCollections = 0;
        dev->currentDirtyChecker = 0;
        dev->bufferedBlock = -1;
        dev->doingBufferedBlockRewrite = 0;
-       dev->blockSelectedForGC = -1;
        dev->nDeletedFiles = 0;
        dev->nBackgroundDeletions=0;
        dev->nUnlinkedFiles = 0;
@@ -4682,7 +4750,7 @@ void yaffs_Deinitialise(yaffs_Device *dev)
 
 int  yaffs_GetNumberOfFreeChunks(yaffs_Device *dev)
 {
-       int nFree = dev->nFreeChunks - (YAFFS_CHUNKS_PER_BLOCK * YAFFS_RESERVED_BLOCKS);
+       int nFree = dev->nFreeChunks - (dev->nChunksPerBlock * YAFFS_RESERVED_BLOCKS);
        
        struct list_head *i;    
        yaffs_Object *l;
@@ -4740,11 +4808,14 @@ int  yaffs_GetNumberOfFreeChunks(yaffs_Device *dev)
        // To the free chunks add the chunks that are in the deleted unlinked files.
        list_for_each(i,&dev->unlinkedDir->variant.directoryVariant.children)
        {
-               l = list_entry(i, yaffs_Object,siblings);
-               if(l->deleted)
+               if(i)
                {
-                       pending++;
-                       pending += l->nDataChunks;
+                       l = list_entry(i, yaffs_Object,siblings);
+                       if(l->deleted)
+                       {
+                               pending++;
+                               pending += l->nDataChunks;
+                       }
                }
        }
        
index 0fe8f74557b7ca942ad0d1c9b5591102606cc0e8..46e8f982fe704c63c388a4e344f36cf367711237 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.14 2003-01-14 23:15:32 charles Exp $
+ * $Id: yaffs_guts.h,v 1.15 2003-01-17 04:19:08 charles Exp $
  */
 
 #ifndef __YAFFS_GUTS_H__
@@ -466,7 +466,6 @@ struct yaffs_DeviceStruct
                
        int   currentDirtyChecker;      // Used to find current dirtiest block
        
-       int   garbageCollectionRequired;
        
        // Operations since mount
        int nPageWrites;
@@ -474,6 +473,7 @@ struct yaffs_DeviceStruct
        int nBlockErasures;
        int nGCCopies;
        int garbageCollections;
+       int passiveGarbageCollections;
        int nRetriedWrites;
        int nRetiredBlocks;
        int eccFixed;
@@ -491,8 +491,6 @@ struct yaffs_DeviceStruct
 //     yaffs_Spare bufferedSpare[YAFFS_CHUNKS_PER_BLOCK];
        int bufferedBlock;      // Which block is buffered here?
        int doingBufferedBlockRewrite;
-       
-       int blockSelectedForGC;
 
        yaffs_ChunkCache *srCache;
        int srLastUse;
index 14876c84206a3b3468544ebf7f543e0dfffc8982..7ada87a8c37216373b01654d85d9a6e3482f6039 100644 (file)
@@ -13,7 +13,7 @@
  *
  */
 
-const char *yaffs_mtdif_c_version = "$Id: yaffs_mtdif.c,v 1.6 2003-01-14 23:15:32 charles Exp $";
+const char *yaffs_mtdif_c_version = "$Id: yaffs_mtdif.c,v 1.7 2003-01-17 04:19:08 charles Exp $";
 
 #ifdef CONFIG_YAFFS_MTD_ENABLED
  
@@ -35,7 +35,7 @@ int nandmtd_WriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data,
        size_t dummy;
     int retval = 0;
        
-       loff_t addr = ((loff_t)chunkInNAND) * YAFFS_BYTES_PER_CHUNK;
+       loff_t addr = ((loff_t)chunkInNAND) * dev->nBytesPerChunk;
        
        __u8 *spareAsBytes = (__u8 *)spare;
 
@@ -43,15 +43,15 @@ int nandmtd_WriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data,
        if(data && spare)
        {
                if(dev->useNANDECC)
-                       mtd->write_ecc(mtd,addr,YAFFS_BYTES_PER_CHUNK,&dummy,data,spareAsBytes,NAND_YAFFS_OOB);
+                       mtd->write_ecc(mtd,addr,dev->nBytesPerChunk,&dummy,data,spareAsBytes,NAND_YAFFS_OOB);
                else
-                       mtd->write_ecc(mtd,addr,YAFFS_BYTES_PER_CHUNK,&dummy,data,spareAsBytes,NAND_NONE_OOB);
+                       mtd->write_ecc(mtd,addr,dev->nBytesPerChunk,&dummy,data,spareAsBytes,NAND_NONE_OOB);
        }
        else
        {
 #endif
        if(data)
-               retval = mtd->write(mtd,addr,YAFFS_BYTES_PER_CHUNK,&dummy,data);
+               retval = mtd->write(mtd,addr,dev->nBytesPerChunk,&dummy,data);
        if(spare)
                retval = mtd->write_oob(mtd,addr,YAFFS_BYTES_PER_SPARE,&dummy,spareAsBytes);
 #ifndef        CONFIG_YAFFS_USE_OLD_MTD
@@ -70,7 +70,7 @@ int nandmtd_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaf
        size_t dummy;
     int retval = 0;
        
-       loff_t addr = ((loff_t)chunkInNAND) * YAFFS_BYTES_PER_CHUNK;
+       loff_t addr = ((loff_t)chunkInNAND) * dev->nBytesPerChunk;
        
        __u8 *spareAsBytes = (__u8 *)spare;
        
@@ -80,19 +80,19 @@ int nandmtd_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaf
                if(dev->useNANDECC)
                {
                        u8 tmpSpare[ YAFFS_BYTES_PER_SPARE + (2*sizeof(int)) ];
-                       retval = mtd->read_ecc(mtd,addr,YAFFS_BYTES_PER_CHUNK,&dummy,data,tmpSpare,NAND_YAFFS_OOB);
+                       retval = mtd->read_ecc(mtd,addr,dev->nBytesPerChunk,&dummy,data,tmpSpare,NAND_YAFFS_OOB);
                        memcpy(spareAsBytes, tmpSpare, YAFFS_BYTES_PER_SPARE);
                }
                else
                {
-                       retval = mtd->read_ecc(mtd,addr,YAFFS_BYTES_PER_CHUNK,&dummy,data,spareAsBytes,NAND_NONE_OOB);
+                       retval = mtd->read_ecc(mtd,addr,dev->nBytesPerChunk,&dummy,data,spareAsBytes,NAND_NONE_OOB);
                }
        }
        else
        {
 #endif
        if(data)
-               retval = mtd->read(mtd,addr,YAFFS_BYTES_PER_CHUNK,&dummy,data);
+               retval = mtd->read(mtd,addr,dev->nBytesPerChunk,&dummy,data);
        if(spare)
                retval = mtd->read_oob(mtd,addr,YAFFS_BYTES_PER_SPARE,&dummy,spareAsBytes);
 #ifndef        CONFIG_YAFFS_USE_OLD_MTD
@@ -116,13 +116,13 @@ static void nandmtd_EraseCallback(struct erase_info *ei)
 int nandmtd_EraseBlockInNAND(yaffs_Device *dev, int blockNumber)
 {
        struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
-       __u32 addr = ((loff_t) blockNumber) * YAFFS_BYTES_PER_BLOCK;
+       __u32 addr = ((loff_t) blockNumber) * dev->nBytesPerChunk * dev->nChunksPerBlock;
        struct erase_info ei;
     int retval = 0;
        
        ei.mtd = mtd;
        ei.addr = addr;
-       ei.len = YAFFS_BYTES_PER_BLOCK;
+       ei.len = dev->nBytesPerChunk * dev->nChunksPerBlock;
        ei.time = 1000;
        ei.retries = 2;
        ei.callback = nandmtd_EraseCallback;
index b330375888f19595e60604183f8a35ab5b20f3be..9b3e637e29547c155a5c8bc29a9be0981e35f56c 100644 (file)
@@ -15,7 +15,7 @@
  *
  * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
  *
- * $Id: yportenv.h,v 1.8 2003-01-14 23:15:41 charles Exp $
+ * $Id: yportenv.h,v 1.9 2003-01-17 04:19:08 charles Exp $
  *
  */
  
@@ -184,6 +184,7 @@ extern unsigned yaffs_traceMask;
 #define YAFFS_TRACE_SCAN               0x0008
 #define YAFFS_TRACE_BAD_BLOCKS 0x0010
 #define YAFFS_TRACE_ERASE              0x0020
+#define YAFFS_TRACE_GC                 0x0040
 #define YAFFS_TRACE_TRACING            0x0100
 #define YAFFS_TRACE_ALWAYS             0x0200
 #define YAFFS_TRACE_BUG                        0x8000