Use vmalloc for large memory allocations
[yaffs2.git] / yaffs_guts.c
index d72cd49d3150d23c58eaff423d835ff000e68cd6..4783f85e92fbed109d200c401714735d83d26f80 100644 (file)
@@ -13,7 +13,7 @@
  */
 
 const char *yaffs_guts_c_version =
-    "$Id: yaffs_guts.c,v 1.18 2005-08-16 02:28:04 charles Exp $";
+    "$Id: yaffs_guts.c,v 1.21 2005-10-09 07:55:00 charles Exp $";
 
 #include "yportenv.h"
 
@@ -57,6 +57,8 @@ static void yaffs_HandleUpdateChunk(yaffs_Device * dev, int chunkInNAND,
                                    const yaffs_ExtendedTags * tags);
 
 /* Other local prototypes */
+static int yaffs_UnlinkObject( yaffs_Object *obj);
+
 static int yaffs_WriteNewChunkWithTagsToNAND(yaffs_Device * dev,
                                             const __u8 * buffer,
                                             yaffs_ExtendedTags * tags,
@@ -1729,10 +1731,10 @@ int yaffs_RenameObject(yaffs_Object * oldDir, const YCHAR * oldName,
                         */
                        yaffs_ChangeObjectName(obj, newDir, newName, force,
                                               existingTarget->objectId);
-                       yaffs_Unlink(newDir, newName);
+                       yaffs_UnlinkObject(existingTarget);
                }
 
-               return yaffs_ChangeObjectName(obj, newDir, newName, force, 0);
+               return yaffs_ChangeObjectName(obj, newDir, newName, 1, 0);
        }
        return YAFFS_FAIL;
 }
@@ -1745,10 +1747,23 @@ static int yaffs_InitialiseBlocks(yaffs_Device * dev, int nBlocks)
 
        /* Todo we're assuming the malloc will pass. */
        dev->blockInfo = YMALLOC(nBlocks * sizeof(yaffs_BlockInfo));
+       if(!dev->blockInfo){
+               dev->blockInfo = YMALLOC_ALT(nBlocks * sizeof(yaffs_BlockInfo));
+               dev->blockInfoAlt = 1;
+       }
+       else
+               dev->blockInfoAlt = 0;
        
        /* Set up dynamic blockinfo stuff. */
        dev->chunkBitmapStride = (dev->nChunksPerBlock + 7) / 8;
        dev->chunkBits = YMALLOC(dev->chunkBitmapStride * nBlocks);
+       if(!dev->chunkBits){
+               dev->chunkBits = YMALLOC_ALT(dev->chunkBitmapStride * nBlocks);
+               dev->chunkBitsAlt = 1;
+       }
+       else
+               dev->chunkBitsAlt = 0;
+       
        if (dev->blockInfo && dev->chunkBits) {
                memset(dev->blockInfo, 0, nBlocks * sizeof(yaffs_BlockInfo));
                memset(dev->chunkBits, 0, dev->chunkBitmapStride * nBlocks);
@@ -1761,9 +1776,19 @@ static int yaffs_InitialiseBlocks(yaffs_Device * dev, int nBlocks)
 
 static void yaffs_DeinitialiseBlocks(yaffs_Device * dev)
 {
-       YFREE(dev->blockInfo);
+       if(dev->blockInfoAlt)
+               YFREE_ALT(dev->blockInfo);
+       else
+               YFREE(dev->blockInfo);
+       dev->blockInfoAlt = 0;
+
        dev->blockInfo = NULL;
-       YFREE(dev->chunkBits);
+       
+       if(dev->chunkBitsAlt)
+               YFREE_ALT(dev->chunkBits);
+       else
+               YFREE(dev->chunkBits);
+       dev->chunkBitsAlt = 0;
        dev->chunkBits = NULL;
 }
 
@@ -3771,11 +3796,9 @@ static int yaffs_UnlinkWorker(yaffs_Object * obj)
        }
 }
 
-int yaffs_Unlink(yaffs_Object * dir, const YCHAR * name)
-{
-       yaffs_Object *obj;
 
-       obj = yaffs_FindObjectByName(dir, name);
+static int yaffs_UnlinkObject( yaffs_Object *obj)
+{
 
        if (obj && obj->unlinkAllowed) {
                return yaffs_UnlinkWorker(obj);
@@ -3784,6 +3807,13 @@ int yaffs_Unlink(yaffs_Object * dir, const YCHAR * name)
        return YAFFS_FAIL;
 
 }
+int yaffs_Unlink(yaffs_Object * dir, const YCHAR * name)
+{
+       yaffs_Object *obj;
+
+       obj = yaffs_FindObjectByName(dir, name);
+       return yaffs_UnlinkObject(obj);
+}
 
 /*----------------------- Initialisation Scanning ---------------------- */
 
@@ -4910,6 +4940,18 @@ static int yaffs_ScanBackwards(yaffs_Device * dev)
 
 /*------------------------------  Directory Functions ----------------------------- */
 
+static void yaffs_RemoveObjectFromDirectory(yaffs_Object * obj)
+{
+       yaffs_Device *dev = obj->myDev;
+       
+       if(dev && dev->removeObjectCallback)
+               dev->removeObjectCallback(obj);
+          
+       list_del_init(&obj->siblings);
+       obj->parent = NULL;
+}
+
+
 static void yaffs_AddObjectToDirectory(yaffs_Object * directory,
                                       yaffs_Object * obj)
 {
@@ -4935,7 +4977,7 @@ static void yaffs_AddObjectToDirectory(yaffs_Object * directory,
 
        } else if (!list_empty(&obj->siblings)) {
                /* If it is holed up somewhere else, un hook it */
-               list_del_init(&obj->siblings);
+               yaffs_RemoveObjectFromDirectory(obj);
        }
        /* Now add it */
        list_add(&obj->siblings, &directory->variant.directoryVariant.children);
@@ -4949,12 +4991,6 @@ static void yaffs_AddObjectToDirectory(yaffs_Object * directory,
        }
 }
 
-static void yaffs_RemoveObjectFromDirectory(yaffs_Object * obj)
-{
-       list_del_init(&obj->siblings);
-       obj->parent = NULL;
-}
-
 yaffs_Object *yaffs_FindObjectByName(yaffs_Object * directory,
                                     const YCHAR * name)
 {