From: charles Date: Thu, 15 Oct 2009 00:45:46 +0000 (+0000) Subject: Runtime disbale of lazy loading. Fix problem where resize was breading rename shadowing X-Git-Tag: pre-name-change~184 X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=commitdiff_plain;h=9b9950b65bae80f37e783de48d424ff4691a201b;hp=2743dc68063b6c83dce3a3b07e78d941fd6feeb2 Runtime disbale of lazy loading. Fix problem where resize was breading rename shadowing --- diff --git a/direct/yaffs_fileem2k.c b/direct/yaffs_fileem2k.c index cfe992e..398cc08 100644 --- a/direct/yaffs_fileem2k.c +++ b/direct/yaffs_fileem2k.c @@ -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; diff --git a/yaffs_fs.c b/yaffs_fs.c index a51dc20..93236e4 100644 --- a/yaffs_fs.c +++ b/yaffs_fs.c @@ -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 @@ -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 diff --git a/yaffs_guts.c b/yaffs_guts.c index 2b9bf7b..74b73dd 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -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 || diff --git a/yaffs_guts.h b/yaffs_guts.h index 853fea6..3385bd4 100644 --- a/yaffs_guts.h +++ b/yaffs_guts.h @@ -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.