Merge branch 'master' of ssh://www.aleph1.co.uk/home/aleph1/git/yaffs2
[yaffs2.git] / yaffs_guts.c
index c01f00c8b6b37239d9562a6bbf8461d486ce8308..75eeb84cf3d5d23459d9897fa2b1fbc9e5b9c88c 100644 (file)
@@ -2223,6 +2223,7 @@ 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--;
 
@@ -2434,7 +2435,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)
@@ -2499,8 +2509,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;
@@ -2534,10 +2546,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 &&
@@ -2565,6 +2575,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 ||
@@ -4189,6 +4202,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) {
@@ -4242,6 +4258,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.