X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_guts.c;h=74b73ddefc3d36c351b25b8b3041380c703d3ee7;hp=9872305f6c1ff26b59ffb3185245f031313ff266;hb=9b9950b65bae80f37e783de48d424ff4691a201b;hpb=84875495636bc4c91fa330851f25af98325aa38e diff --git a/yaffs_guts.c b/yaffs_guts.c index 9872305..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.87 2009-07-29 04:30:24 charles Exp $"; + "$Id: yaffs_guts.c,v 1.91 2009-10-15 00:45:46 charles Exp $"; #include "yportenv.h" @@ -1545,11 +1545,16 @@ static int yaffs_FindChunkInGroup(yaffs_Device *dev, int theChunk, for (j = 0; theChunk && j < dev->chunkGroupSize; j++) { if (yaffs_CheckChunkBit(dev, theChunk / dev->nChunksPerBlock, theChunk % dev->nChunksPerBlock)) { - yaffs_ReadChunkWithTagsFromNAND(dev, theChunk, NULL, - tags); - if (yaffs_TagsMatch(tags, objectId, chunkInInode)) { - /* found it; */ + + if(dev->chunkGroupSize == 1) return theChunk; + else { + yaffs_ReadChunkWithTagsFromNAND(dev, theChunk, NULL, + tags); + if (yaffs_TagsMatch(tags, objectId, chunkInInode)) { + /* found it; */ + return theChunk; + } } } theChunk++; @@ -2461,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) @@ -2468,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. @@ -2477,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; @@ -2495,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; } @@ -5026,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, @@ -5055,23 +5075,27 @@ loff_t yaffs_GetFileSize(yaffs_Object *obj) -int yaffs_FlushFile(yaffs_Object *in, int updateTime) +int yaffs_FlushFile(yaffs_Object *in, int updateTime, int dataSync) { int retVal; if (in->dirty) { yaffs_FlushFilesChunkCache(in); - if (updateTime) { + if(dataSync) /* Only sync data */ + retVal=YAFFS_OK; + else { + if (updateTime) { #ifdef CONFIG_YAFFS_WINCE - yfsd_WinFileTimeNow(in->win_mtime); + yfsd_WinFileTimeNow(in->win_mtime); #else - in->yst_mtime = Y_CURRENT_TIME; + in->yst_mtime = Y_CURRENT_TIME; #endif - } + } - retVal = (yaffs_UpdateObjectHeader(in, NULL, 0, 0, 0) >= - 0) ? YAFFS_OK : YAFFS_FAIL; + retVal = (yaffs_UpdateObjectHeader(in, NULL, 0, 0, 0) >= + 0) ? YAFFS_OK : YAFFS_FAIL; + } } else { retVal = YAFFS_OK; } @@ -5172,14 +5196,19 @@ int yaffs_DeleteFile(yaffs_Object *in) } } -static int yaffs_DeleteDirectory(yaffs_Object *in) +static int yaffs_IsNonEmptyDirectory(yaffs_Object *obj) { - /* First check that the directory is empty. */ - if (ylist_empty(&in->variant.directoryVariant.children)) - return yaffs_DoGenericObjectDeletion(in); + return (obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) && + !(ylist_empty(&obj->variant.directoryVariant.children)); +} - return YAFFS_FAIL; +static int yaffs_DeleteDirectory(yaffs_Object *obj) +{ + /* First check that the directory is empty. */ + if (yaffs_IsNonEmptyDirectory(obj)) + return YAFFS_FAIL; + return yaffs_DoGenericObjectDeletion(obj); } static int yaffs_DeleteSymLink(yaffs_Object *in) @@ -5295,7 +5324,9 @@ static int yaffs_UnlinkWorker(yaffs_Object *obj) default: return YAFFS_FAIL; } - } else + } else if(yaffs_IsNonEmptyDirectory(obj)) + return YAFFS_FAIL; + else return yaffs_ChangeObjectName(obj, obj->myDev->unlinkedDir, _Y("unlinked"), 0, 0); } @@ -5334,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; } @@ -5346,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 */ @@ -6263,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 || @@ -6811,7 +6842,7 @@ yaffs_Object *yaffs_FindObjectByName(yaffs_Object *directory, * Do a real check */ yaffs_GetObjectName(l, buffer, - YAFFS_MAX_NAME_LENGTH); + YAFFS_MAX_NAME_LENGTH + 1); if (yaffs_strncmp(name, buffer, YAFFS_MAX_NAME_LENGTH) == 0) return l; } @@ -7060,7 +7091,7 @@ int yaffs_DumpObject(yaffs_Object *obj) { YCHAR name[257]; - yaffs_GetObjectName(obj, name, 256); + yaffs_GetObjectName(obj, name, YAFFS_MAX_NAME_LENGTH + 1); T(YAFFS_TRACE_ALWAYS, (TSTR