*** empty log message ***
[yaffs/.git] / yaffs_guts.c
index 5cbd371a938ecafc39814e049f7ca0381eac1e78..5218aeab3391faef20b9d85dbbf0800f29e0332f 100644 (file)
@@ -14,7 +14,7 @@
  */
  //yaffs_guts.c
 
-const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.27 2003-08-16 08:17:32 charles Exp $";
+const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.30 2003-09-16 06:48:38 charles Exp $";
 
 #include "yportenv.h"
 
@@ -782,11 +782,16 @@ static void yaffs_FreeTnode(yaffs_Device*dev, yaffs_Tnode *tn)
 static void yaffs_DeinitialiseTnodes(yaffs_Device*dev)
 {
        // Free the list of allocated tnodes
-       
+       yaffs_TnodeList *tmp;
+               
        while(dev->allocatedTnodeList)
        {
+               tmp =  dev->allocatedTnodeList->next;
+
                YFREE(dev->allocatedTnodeList->tnodes);
-               dev->allocatedTnodeList =  dev->allocatedTnodeList->next;
+               YFREE(dev->allocatedTnodeList);
+               dev->allocatedTnodeList = tmp;
+               
        }
        
        dev->freeTnodes = NULL;
@@ -1151,6 +1156,8 @@ static int yaffs_SoftDeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level
                        {
                            if(tn->level0[i])
                        {
+                                       // Note this does not find the real chunk, only the chunk group.
+                                       // We make an assumption that a chunk group is niot larger than a block.
                                        theChunk =  (tn->level0[i] << in->myDev->chunkGroupBits);
                                        T(YAFFS_TRACE_SCAN,(TSTR("soft delete tch %d cgb %d chunk %d" TENDSTR),
                                                tn->level0[i],in->myDev->chunkGroupBits,theChunk));
@@ -1452,10 +1459,15 @@ static void yaffs_DeinitialiseObjects(yaffs_Device *dev)
 {
        // Free the list of allocated Objects
        
+       yaffs_ObjectList *tmp;
+       
        while( dev->allocatedObjectList)
        {
+               tmp =  dev->allocatedObjectList->next;
                YFREE(dev->allocatedObjectList->objects);
-               dev->allocatedObjectList =  dev->allocatedObjectList->next;
+               YFREE(dev->allocatedObjectList);
+               
+               dev->allocatedObjectList =  tmp;
        }
        
        dev->freeObjects = NULL;
@@ -2853,7 +2865,14 @@ static void yaffs_DeleteChunk(yaffs_Device *dev,int chunkId,int markNAND)
        if(markNAND)
        {
                yaffs_SpareInitialise(&spare);
-       
+
+#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
+
+                //read data before write, to ensure correct ecc 
+                //if we're using MTD verification under Linux
+                yaffs_ReadChunkFromNAND(dev,chunkId,NULL,&spare,0);
+#endif
+
                spare.pageStatus = 0; // To mark it as deleted.
 
        
@@ -4656,8 +4675,7 @@ int yaffs_GutsInitialise(yaffs_Device *dev)
        int extraBits;
        int nBlocks;
 
-       if(     dev->nBytesPerChunk != YAFFS_BYTES_PER_CHUNK ||
-       
+       if(     dev->nBytesPerChunk != YAFFS_BYTES_PER_CHUNK || 
                dev->nChunksPerBlock < 2 ||
                dev->nReservedBlocks < 2 ||
                dev->startBlock <= 0 ||
@@ -4724,7 +4742,18 @@ int yaffs_GutsInitialise(yaffs_Device *dev)
        {
                dev->chunkGroupBits = bits - 16;
        }
+       
        dev->chunkGroupSize = 1 << dev->chunkGroupBits;
+
+       if(dev->nChunksPerBlock < dev->chunkGroupSize)
+       {
+               // We have a problem because the soft delete won't work if
+               // the chunk group size > chunks per block.
+               // This can be remedied by using larger "virtual blocks".
+               
+               return YAFFS_FAIL;
+       }
+