# HG changeset patch # User Ross Younger # Date 1257269715 0 # Node ID 1c56b1df53d868031da831330c83e42c40ae9445 # Parent 8e1210f7946a3438ecb59e7cfe8be0b8f7d613b0# Parent 85d1653547810a95745c6742703f64b323684439 Merge from upstream diff --git a/.hgtags b/.hgtags new file mode 100644 --- /dev/null +++ b/.hgtags @@ -0,0 +1,9 @@ +14d97b52d375b0ebb1c6c0258cd14d9b263cd098 pre_Ians_changes +15cda41fdfb6eb0ae4e92b42ec3f6950c31ee281 pre-inbandtags-checkin +1d8892b579f5d2487134ff0e6672f0d9d343c01b before_2_6_18_support +5141f90de139d19c1fcce14345be430c5881f66f Pre-retirement-changes +6d11517ae07f4f1570d8a00c3b59c270620f81c8 pre-checkpatch-20090306 +7bdee2571f8f511573cf3bde1629fef106a0b6d1 pre_checkpoint_robustness +8fb66e0909adc6957d235feec438abcd59607f1e pre_Lindent_20050811 +a06876fb1295b3722687facf6230ab9e0e4a8e91 post_Lindent_20050816 +b9ba4e46d2e5c0a16eb6b65f6291414be4ddc0d4 pre-large-nand-changes diff --git a/packages/fs/yaffs/current/src/yaffs_checkptrw.c b/packages/fs/yaffs/current/src/yaffs_checkptrw.c --- a/packages/fs/yaffs/current/src/yaffs_checkptrw.c +++ b/packages/fs/yaffs/current/src/yaffs_checkptrw.c @@ -130,6 +130,9 @@ static void yaffs_CheckpointFindNextChec int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting) { + + dev->checkpointOpenForWrite = forWriting; + /* Got the functions we need? */ if (!dev->writeChunkWithTagsToNAND || !dev->readChunkWithTagsFromNAND || @@ -147,9 +150,6 @@ int yaffs_CheckpointOpen(yaffs_Device *d dev->checkpointPageSequence = 0; - - dev->checkpointOpenForWrite = forWriting; - dev->checkpointByteCount = 0; dev->checkpointSum = 0; dev->checkpointXor = 0; @@ -358,11 +358,14 @@ int yaffs_CheckpointClose(yaffs_Device * if (dev->checkpointOpenForWrite) { if (dev->checkpointByteOffset != 0) yaffs_CheckpointFlushBuffer(dev); - } else { + } else if(dev->checkpointBlockList){ int i; for (i = 0; i < dev->blocksInCheckpoint && dev->checkpointBlockList[i] >= 0; i++) { - yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, dev->checkpointBlockList[i]); - if (bi->blockState == YAFFS_BLOCK_STATE_EMPTY) + int blk = dev->checkpointBlockList[i]; + yaffs_BlockInfo *bi = NULL; + if( dev->internalStartBlock <= blk && blk <= dev->internalEndBlock) + bi = yaffs_GetBlockInfo(dev, blk); + if (bi && bi->blockState == YAFFS_BLOCK_STATE_EMPTY) bi->blockState = YAFFS_BLOCK_STATE_CHECKPOINT; else { /* Todo this looks odd... */ @@ -390,13 +393,10 @@ int yaffs_CheckpointClose(yaffs_Device * int yaffs_CheckpointInvalidateStream(yaffs_Device *dev) { - /* Erase the first checksum block */ + /* Erase the checkpoint data */ T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint invalidate"TENDSTR))); - if (!yaffs_CheckpointSpaceOk(dev)) - return 0; - return yaffs_CheckpointErase(dev); } diff --git a/packages/fs/yaffs/current/src/yaffs_guts.c b/packages/fs/yaffs/current/src/yaffs_guts.c --- a/packages/fs/yaffs/current/src/yaffs_guts.c +++ b/packages/fs/yaffs/current/src/yaffs_guts.c @@ -2470,6 +2470,8 @@ int yaffs_RenameObject(yaffs_Object *old yaffs_Object *obj = NULL; yaffs_Object *existingTarget = NULL; int force = 0; + int result; + yaffs_Device *dev; if (!oldDir || oldDir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) @@ -2477,6 +2479,8 @@ int yaffs_RenameObject(yaffs_Object *old 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. @@ -2486,7 +2490,7 @@ int yaffs_RenameObject(yaffs_Object *old force = 1; #endif - else if (yaffs_strlen(newName) > YAFFS_MAX_NAME_LENGTH) + if(yaffs_strlen(newName) > YAFFS_MAX_NAME_LENGTH) /* ENAMETOOLONG */ return YAFFS_FAIL; @@ -2504,17 +2508,26 @@ int yaffs_RenameObject(yaffs_Object *old 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; } @@ -5043,11 +5056,13 @@ int yaffs_ResizeFile(yaffs_Object *in, l } - /* 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, @@ -5364,7 +5379,8 @@ static void yaffs_HandleShadowedObject(y /* 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; } @@ -5376,6 +5392,7 @@ static void yaffs_HandleShadowedObject(y 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 */ @@ -6303,9 +6320,7 @@ static int yaffs_ScanBackwards(yaffs_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/packages/fs/yaffs/current/src/yaffs_guts.h b/packages/fs/yaffs/current/src/yaffs_guts.h --- a/packages/fs/yaffs/current/src/yaffs_guts.h +++ b/packages/fs/yaffs/current/src/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. diff --git a/packages/fs/yaffs/current/src/yportenv.h b/packages/fs/yaffs/current/src/yportenv.h --- a/packages/fs/yaffs/current/src/yportenv.h +++ b/packages/fs/yaffs/current/src/yportenv.h @@ -96,7 +96,7 @@ #define TOUT(p) printk p #define yaffs_trace(mask, fmt, args...) \ - do { if ((mask) & (yaffs_traceMask|YAFFS_TRACE_ERROR)) \ + do { if ((mask) & (yaffs_traceMask| YAFFS_TRACE_ALWAYS)) \ printk(KERN_WARNING "yaffs: " fmt, ## args); \ } while (0)