yaffs Remove obsolete list debugging code
[yaffs2.git] / yaffs_guts.c
index b8a11b5d7cbe4dc189a837f72d1273a5c007f371..f910f386dfdb5a33d86a19b4069ee951d887e804 100644 (file)
@@ -66,15 +66,12 @@ static yaffs_Object *yaffs_CreateNewObject(yaffs_Device *dev, int number,
                                        yaffs_ObjectType type);
 
 
-static int yaffs_ApplyXMod(yaffs_Device *dev, char *buffer, yaffs_XAttrMod *xmod);
+static int yaffs_ApplyXMod(yaffs_Object *obj, char *buffer, yaffs_XAttrMod *xmod);
 
 static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj);
 static int yaffs_CheckStructures(void);
 static int yaffs_DoGenericObjectDeletion(yaffs_Object *in);
 
-static yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device *dev, int blockNo);
-
-
 static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,
                                int chunkInNAND);
 
@@ -2106,7 +2103,6 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block,
        int newChunk;
        int markNAND;
        int retVal = YAFFS_OK;
-       int cleanups = 0;
        int i;
        int isCheckpointBlock;
        int matchingChunk;
@@ -2224,14 +2220,15 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block,
                                         * We have to decrement free chunks so this works out properly.
                                         */
                                        dev->nFreeChunks--;
+                                       bi->softDeletions--;
 
                                        object->nDataChunks--;
 
                                        if (object->nDataChunks <= 0) {
                                                /* remeber to clean up the object */
-                                               dev->gcCleanupList[cleanups] =
+                                               dev->gcCleanupList[dev->nCleanups] =
                                                    tags.objectId;
-                                               cleanups++;
+                                               dev->nCleanups++;
                                        }
                                        markNAND = 0;
                                } else if (0) {
@@ -2317,8 +2314,23 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block,
                yaffs_ReleaseTempBuffer(dev, buffer, __LINE__);
 
 
+
+       }
+
+       yaffs_VerifyCollectedBlock(dev, bi, block);
+
+
+
+       if (bi->blockState == YAFFS_BLOCK_STATE_COLLECTING) {
+               /*
+                * The gc did not complete. Set block state back to FULL
+                * because checkpointing does not restore gc.
+                */
+               bi->blockState = YAFFS_BLOCK_STATE_FULL;
+       } else {
+               /* The gc completed. */
                /* Do any required cleanups */
-               for (i = 0; i < cleanups; i++) {
+               for (i = 0; i < dev->nCleanups; i++) {
                        /* Time to delete the file too */
                        object =
                            yaffs_FindObjectByNumber(dev,
@@ -2338,20 +2350,7 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block,
 
                }
 
-       }
-
-       yaffs_VerifyCollectedBlock(dev, bi, block);
-
 
-
-       if (bi->blockState == YAFFS_BLOCK_STATE_COLLECTING) {
-               /*
-                * The gc did not complete. Set block state back to FULL
-                * because checkpointing does not restore gc.
-                */
-               bi->blockState = YAFFS_BLOCK_STATE_FULL;
-       } else {
-               /* The gc completed. */
                chunksAfter = yaffs_GetErasedChunks(dev);
                if (chunksBefore >= chunksAfter) {
                        T(YAFFS_TRACE_GC,
@@ -2361,6 +2360,7 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block,
                }
                dev->gcBlock = 0;
                dev->gcChunk = 0;
+               dev->nCleanups = 0;
        }
 
        dev->gcDisable = 0;
@@ -2432,7 +2432,16 @@ static unsigned yaffs_FindBlockForGarbageCollection(yaffs_Device *dev,
                        threshold = dev->param.nChunksPerBlock;
                        iterations = nBlocks;
                } else {
-                       int maxThreshold = dev->param.nChunksPerBlock/2;
+                       int maxThreshold;
+
+                       if(background)
+                               maxThreshold = dev->param.nChunksPerBlock/2;
+                       else
+                               maxThreshold = dev->param.nChunksPerBlock/8;
+
+                       if(maxThreshold <  YAFFS_GC_PASSIVE_THRESHOLD)
+                               maxThreshold = YAFFS_GC_PASSIVE_THRESHOLD;
+
                        threshold = background ?
                                (dev->gcNotDone + 2) * 2 : 0;
                        if(threshold <YAFFS_GC_PASSIVE_THRESHOLD)
@@ -2497,8 +2506,10 @@ static unsigned yaffs_FindBlockForGarbageCollection(yaffs_Device *dev,
                  dev->param.nChunksPerBlock - dev->gcPagesInUse,
                  prioritised));
 
+               dev->nGCBlocks++;
                if(background)
                        dev->backgroundGCs++;
+
                dev->gcDirtiest = 0;
                dev->gcPagesInUse = 0;
                dev->gcNotDone = 0;
@@ -2532,10 +2543,8 @@ static int yaffs_CheckGarbageCollection(yaffs_Device *dev, int background)
        int aggressive = 0;
        int gcOk = YAFFS_OK;
        int maxTries = 0;
-
        int minErased;
        int erasedChunks;
-
        int checkpointBlockAdjust;
 
        if(dev->param.gcControl &&
@@ -2563,6 +2572,9 @@ static int yaffs_CheckGarbageCollection(yaffs_Device *dev, int background)
                if (dev->nErasedBlocks < minErased)
                        aggressive = 1;
                else {
+                       if(!background && erasedChunks > (dev->nFreeChunks / 4))
+                               break;
+
                        if(dev->gcSkip > 20)
                                dev->gcSkip = 20;
                        if(erasedChunks < dev->nFreeChunks/2 ||
@@ -2582,10 +2594,12 @@ static int yaffs_CheckGarbageCollection(yaffs_Device *dev, int background)
                if (dev->gcBlock < 1 && !aggressive) {
                        dev->gcBlock = yaffs2_FindRefreshBlock(dev);
                        dev->gcChunk = 0;
+                       dev->nCleanups=0;
                }
                if (dev->gcBlock < 1) {
                        dev->gcBlock = yaffs_FindBlockForGarbageCollection(dev, aggressive, background);
                        dev->gcChunk = 0;
+                       dev->nCleanups=0;
                }
 
                if (dev->gcBlock > 0) {
@@ -2994,7 +3008,7 @@ int yaffs_UpdateObjectHeader(yaffs_Object *in, const YCHAR *name, int force,
        int newChunkId;
        yaffs_ExtendedTags newTags;
        yaffs_ExtendedTags oldTags;
-       YCHAR *alias = NULL;
+       const YCHAR *alias = NULL;
 
        __u8 *buffer = NULL;
        YCHAR oldName[YAFFS_MAX_NAME_LENGTH + 1];
@@ -3095,7 +3109,7 @@ int yaffs_UpdateObjectHeader(yaffs_Object *in, const YCHAR *name, int force,
 
                /* process any xattrib modifications */
                if(xmod)
-                       yaffs_ApplyXMod(dev, (char *)buffer, xmod);
+                       yaffs_ApplyXMod(in, (char *)buffer, xmod);
 
 
                /* Tags */
@@ -4185,6 +4199,9 @@ static void yaffs_StripDeletedObjects(yaffs_Device *dev)
        struct ylist_head *n;
        yaffs_Object *l;
 
+       if (dev->readOnly)
+               return;
+
        /* Soft delete all the unlinked files */
        ylist_for_each_safe(i, n,
                &dev->unlinkedDir->variant.directoryVariant.children) {
@@ -4238,6 +4255,8 @@ static void yaffs_FixHangingObjects(yaffs_Device *dev)
        int depthLimit;
        int hanging;
 
+       if (dev->readOnly)
+               return;
 
        /* Iterate through the objects in each hash entry,
         * looking at each object.
@@ -4367,7 +4386,7 @@ static void yaffs_CheckObjectDetailsLoaded(yaffs_Object *in)
                in->yst_rdev = oh->yst_rdev;
 
 #endif
-               yaffs_SetObjectName(in, oh->name);
+               yaffs_SetObjectNameFromOH(in, oh);
 
                if (in->variantType == YAFFS_OBJECT_TYPE_SYMLINK) {
                        in->variant.symLinkVariant.alias =
@@ -4917,10 +4936,11 @@ static int yaffs_DoXMod(yaffs_Object *obj, int set, const YCHAR *name, const voi
                return -ENOSPC;
 }
 
-static int yaffs_ApplyXMod(yaffs_Device *dev, char *buffer, yaffs_XAttrMod *xmod)
+static int yaffs_ApplyXMod(yaffs_Object *obj, char *buffer, yaffs_XAttrMod *xmod)
 {
        int retval = 0;
        int x_offs = sizeof(yaffs_ObjectHeader);
+       yaffs_Device *dev = obj->myDev;
        int x_size = dev->nDataBytesPerChunk - sizeof(yaffs_ObjectHeader);
 
        char * x_buffer = buffer + x_offs;
@@ -4930,6 +4950,9 @@ static int yaffs_ApplyXMod(yaffs_Device *dev, char *buffer, yaffs_XAttrMod *xmod
        else
                retval = nval_del(x_buffer, x_size, xmod->name);
 
+       obj->hasXattr = nval_hasvalues(x_buffer, x_size);
+       obj->xattrKnown = 1;
+
        xmod->result = retval;
 
        return retval;
@@ -4944,30 +4967,45 @@ static int yaffs_DoXFetch(yaffs_Object *obj, const YCHAR *name, void *value, int
        int x_offs = sizeof(yaffs_ObjectHeader);
        int x_size = dev->nDataBytesPerChunk - sizeof(yaffs_ObjectHeader);
 
-       __u8 * x_buffer;
+       char * x_buffer;
 
        int retval = 0;
 
        if(obj->hdrChunk < 1)
                return -ENODATA;
 
-       buffer = yaffs_GetTempBuffer(dev, __LINE__);
+       /* If we know that the object has no xattribs then don't do all the
+        * reading and parsing.
+        */
+       if(obj->xattrKnown && !obj->hasXattr){
+               if(name)
+                       return -ENODATA;
+               else
+                       return 0;
+       }
+
+       buffer = (char *) yaffs_GetTempBuffer(dev, __LINE__);
        if(!buffer)
                return -ENOMEM;
 
-       result = yaffs_ReadChunkWithTagsFromNAND(dev,obj->hdrChunk, buffer, &tags);
+       result = yaffs_ReadChunkWithTagsFromNAND(dev,obj->hdrChunk, (__u8 *)buffer, &tags);
 
        if(result != YAFFS_OK)
                retval = -ENOENT;
        else{
                x_buffer =  buffer + x_offs;
 
+               if (!obj->xattrKnown){
+                       obj->hasXattr = nval_hasvalues(x_buffer, x_size);
+                       obj->xattrKnown = 1;
+               }
+
                if(name)
                        retval = nval_get(x_buffer, x_size, name, value, size);
                else
                        retval = nval_list(x_buffer, x_size, value,size);
        }
-       yaffs_ReleaseTempBuffer(dev,buffer,__LINE__);
+       yaffs_ReleaseTempBuffer(dev,(__u8 *)buffer,__LINE__);
        return retval;
 }
 
@@ -5497,9 +5535,8 @@ static int yaffs_CheckStructures(void)
 /*      yaffs_CheckStruct(yaffs_Tags,8,"yaffs_Tags"); */
 /*      yaffs_CheckStruct(yaffs_TagsUnion,8,"yaffs_TagsUnion"); */
 /*      yaffs_CheckStruct(yaffs_Spare,16,"yaffs_Spare"); */
-#ifndef CONFIG_YAFFS_TNODE_LIST_DEBUG
 /*     yaffs_CheckStruct(yaffs_Tnode, 2 * YAFFS_NTNODES_LEVEL0, "yaffs_Tnode"); */
-#endif
+
 #ifndef CONFIG_YAFFS_WINCE
        yaffs_CheckStruct(yaffs_ObjectHeader, 512, "yaffs_ObjectHeader");
 #endif