Runtime disbale of lazy loading. Fix problem where resize was breading rename shadowing
authorcharles <charles>
Thu, 15 Oct 2009 00:45:46 +0000 (00:45 +0000)
committercharles <charles>
Thu, 15 Oct 2009 00:45:46 +0000 (00:45 +0000)
direct/yaffs_fileem2k.c
yaffs_fs.c
yaffs_guts.c
yaffs_guts.h

index cfe992e..398cc08 100644 (file)
@@ -16,7 +16,7 @@
  * This is only intended as test code to test persistence etc.
  */
 
-const char *yaffs_flashif2_c_version = "$Id: yaffs_fileem2k.c,v 1.19 2009-10-14 00:01:57 charles Exp $";
+const char *yaffs_flashif2_c_version = "$Id: yaffs_fileem2k.c,v 1.20 2009-10-15 00:45:46 charles Exp $";
 
 
 #include "yportenv.h"
@@ -72,7 +72,7 @@ static int nops_so_far;
 int ops_multiplier;
 
 
-static void yflash2_MaybePowerFail(void)
+static void yflash2_MaybePowerFail(unsigned int chunkInNAND, int failPoint)
 {
 
    nops_so_far++;
@@ -82,6 +82,8 @@ static void yflash2_MaybePowerFail(void)
    if(simulate_power_failure &&
       remaining_ops < 1){
        printf("Simulated power failure after %d operations\n",nops_so_far);
+       printf("  Fail simulated on chunkInNAND %d, at fail point %d\n",
+                               chunkInNAND, failPoint);
        exit(0);
   }
 }
@@ -240,7 +242,7 @@ int yflash2_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u
 
                        if(written != dev->nDataBytesPerChunk) return YAFFS_FAIL;
                }
-               yflash2_MaybePowerFail();
+               // yflash2_MaybePowerFail(chunkInNAND,1);
        
                if(tags)
                {
@@ -291,7 +293,7 @@ int yflash2_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u
                        }
                }
                
-               //yflash2_MaybePowerFail();
+               //yflash2_MaybePowerFail(chunkInNAND,2);
                
                /* Next do the whole write */
                if(data)
@@ -361,7 +363,7 @@ int yflash2_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u
                        }
                }
                
-               yflash2_MaybePowerFail();
+               yflash2_MaybePowerFail(chunkInNAND,3);
        
        }
        return YAFFS_OK;        
index a51dc20..93236e4 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 const char *yaffs_fs_c_version =
-    "$Id: yaffs_fs.c,v 1.84 2009-10-14 00:01:56 charles Exp $";
+    "$Id: yaffs_fs.c,v 1.85 2009-10-15 00:45:46 charles Exp $";
 extern const char *yaffs_guts_c_version;
 
 #include <linux/version.h>
@@ -1814,6 +1814,8 @@ typedef struct {
        int no_cache;
        int tags_ecc_on;
        int tags_ecc_overridden;
+       int lazy_load_enabled;
+       int lazy_load_overridden;
 } yaffs_options;
 
 #define MAX_OPT_LEN 20
@@ -1848,6 +1850,12 @@ static int yaffs_parse_options(yaffs_options *options, const char *options_str)
                } else if (!strcmp(cur_opt, "tags-ecc-on")){
                        options->tags_ecc_on = 1;
                        options->tags_ecc_overridden = 1;
+               } else if (!strcmp(cur_opt, "lazy-load-off")){
+                       options->lazy_load_enabled = 0;
+                       options->lazy_load_overridden=1;
+               } else if (!strcmp(cur_opt, "lazy-load-on")){
+                       options->lazy_load_enabled = 1;
+                       options->lazy_load_overridden = 1;
                } else if (!strcmp(cur_opt, "no-cache"))
                        options->no_cache = 1;
                else if (!strcmp(cur_opt, "no-checkpoint-read"))
@@ -2064,6 +2072,12 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
        dev->nShortOpCaches = (options.no_cache) ? 0 : 10;
        dev->inbandTags = options.inband_tags;
 
+#ifdef CONFIG_YAFFS_DISABLE_LAZY_LOAD
+       dev->disableLazyLoad = 1;
+#endif
+       if(options.lazy_load_overridden)
+               dev->disableLazyLoad = !options.lazy_load_enabled;
+
 #ifdef CONFIG_YAFFS_DISABLE_TAGS_ECC
        dev->noTagsECC = 1;
 #endif
index 2b9bf7b..74b73dd 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 const char *yaffs_guts_c_version =
-    "$Id: yaffs_guts.c,v 1.90 2009-09-23 23:24:55 charles Exp $";
+    "$Id: yaffs_guts.c,v 1.91 2009-10-15 00:45:46 charles Exp $";
 
 #include "yportenv.h"
 
@@ -2466,6 +2466,8 @@ int yaffs_RenameObject(yaffs_Object *oldDir, const YCHAR *oldName,
        yaffs_Object *obj = NULL;
        yaffs_Object *existingTarget = NULL;
        int force = 0;
+       int result;
+       yaffs_Device *dev;
 
 
        if (!oldDir || oldDir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY)
@@ -2473,6 +2475,8 @@ int yaffs_RenameObject(yaffs_Object *oldDir, const YCHAR *oldName,
        if (!newDir || newDir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY)
                YBUG();
 
+       dev = oldDir->myDev;
+
 #ifdef CONFIG_YAFFS_CASE_INSENSITIVE
        /* Special case for case insemsitive systems (eg. WinCE).
         * While look-up is case insensitive, the name isn't.
@@ -2482,7 +2486,7 @@ int yaffs_RenameObject(yaffs_Object *oldDir, const YCHAR *oldName,
                force = 1;
 #endif
 
-       else if (yaffs_strlen(newName) > YAFFS_MAX_NAME_LENGTH)
+       if(yaffs_strlen(newName) > YAFFS_MAX_NAME_LENGTH)
                /* ENAMETOOLONG */
                return YAFFS_FAIL;
 
@@ -2500,17 +2504,26 @@ int yaffs_RenameObject(yaffs_Object *oldDir, const YCHAR *oldName,
                        return YAFFS_FAIL;      /* EEXIST or ENOTEMPTY */
                } else if (existingTarget && existingTarget != obj) {
                        /* Nuke the target first, using shadowing,
-                        * but only if it isn't the same object
+                        * but only if it isn't the same object.
+                        *
+                        * Note we must disable gc otherwise it can mess up the shadowing.
+                        *
                         */
+                       dev->isDoingGC=1;
                        yaffs_ChangeObjectName(obj, newDir, newName, force,
                                                existingTarget->objectId);
+                       existingTarget->isShadowed = 1;
                        yaffs_UnlinkObject(existingTarget);
+                       dev->isDoingGC=0;
                }
+
+               result = yaffs_ChangeObjectName(obj, newDir, newName, 1, 0);
+
                yaffs_UpdateParent(oldDir);
                if(newDir != oldDir)
                        yaffs_UpdateParent(newDir);
-
-               return yaffs_ChangeObjectName(obj, newDir, newName, 1, 0);
+               
+               return result;
        }
        return YAFFS_FAIL;
 }
@@ -5031,11 +5044,13 @@ int yaffs_ResizeFile(yaffs_Object *in, loff_t newSize)
        }
 
 
-       /* Write a new object header.
+       /* Write a new object header to reflect the resize.
         * show we've shrunk the file, if need be
-        * Do this only if the file is not in the deleted directories.
+        * Do this only if the file is not in the deleted directories
+        * and is not shadowed.
         */
        if (in->parent &&
+           !in->isShadowed &&
            in->parent->objectId != YAFFS_OBJECTID_UNLINKED &&
            in->parent->objectId != YAFFS_OBJECTID_DELETED)
                yaffs_UpdateObjectHeader(in, NULL, 0,
@@ -5350,7 +5365,8 @@ static void yaffs_HandleShadowedObject(yaffs_Device *dev, int objId,
                /* Handle YAFFS2 case (backward scanning)
                 * If the shadowed object exists then ignore.
                 */
-               if (yaffs_FindObjectByNumber(dev, objId))
+               obj = yaffs_FindObjectByNumber(dev, objId);
+               if(obj)
                        return;
        }
 
@@ -5362,6 +5378,7 @@ static void yaffs_HandleShadowedObject(yaffs_Device *dev, int objId,
                                             YAFFS_OBJECT_TYPE_FILE);
        if (!obj)
                return;
+       obj->isShadowed = 1;
        yaffs_AddObjectToDirectory(dev->unlinkedDir, obj);
        obj->variant.fileVariant.shrinkSize = 0;
        obj->valid = 1;         /* So that we don't read any other info for this file */
@@ -6279,9 +6296,7 @@ static int yaffs_ScanBackwards(yaffs_Device *dev)
                                }
 
                                if (!in ||
-#ifdef CONFIG_YAFFS_DISABLE_LAZY_LOAD
-                                   !in->valid ||
-#endif
+                                   (!in->valid && dev->disableLazyLoad) ||
                                    tags.extraShadows ||
                                    (!in->valid &&
                                    (tags.objectId == YAFFS_OBJECTID_ROOT ||
index 853fea6..3385bd4 100644 (file)
@@ -424,6 +424,7 @@ struct yaffs_ObjectStruct {
                                 * until the inode is released.
                                 */
        __u8 beingCreated:1;    /* This object is still being created so skip some checks. */
+       __u8 isShadowed:1;      /* This object is shadowed on the way to being renamed. */
 
        __u8 serial;            /* serial number of chunk in NAND. Cached here */
        __u16 sum;              /* sum of the name to speed searching */
@@ -559,6 +560,8 @@ struct yaffs_DeviceStruct {
 
        int useNANDECC;         /* Flag to decide whether or not to use NANDECC on data (yaffs1) */
        int noTagsECC;          /* Flag to decide whether or not to do ECC on packed tags (yaffs2) */ 
+       
+       int disableLazyLoad;    /* Disable lazy loading on this device */
 
        void *genericDevice;    /* Pointer to device context
                                 * On an mtd this holds the mtd pointer.