X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_guts.c;h=2b9bf7bd66228b3b173d276ffbcc416c1cd59f39;hp=0db60b971b2f5c8c5fd9de667f955d9cd7cb47e9;hb=3eeb7039cdf6bfef271c20ea3e579a120af5e251;hpb=d07df594fdcdd1dd3ae02c4d86c6c6d5e5c42c6e diff --git a/yaffs_guts.c b/yaffs_guts.c index 0db60b9..2b9bf7b 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.84 2009-05-26 04:50:08 charles Exp $"; + "$Id: yaffs_guts.c,v 1.90 2009-09-23 23:24:55 charles Exp $"; #include "yportenv.h" @@ -760,7 +760,7 @@ static void yaffs_VerifyObject(yaffs_Object *obj) chunkMax = (dev->internalEndBlock+1) * dev->nChunksPerBlock - 1; chunkInRange = (((unsigned)(obj->hdrChunk)) >= chunkMin && ((unsigned)(obj->hdrChunk)) <= chunkMax); - chunkIdOk = chunkInRange || obj->hdrChunk == 0; + chunkIdOk = chunkInRange || (obj->hdrChunk == 0); chunkValid = chunkInRange && yaffs_CheckChunkBit(dev, obj->hdrChunk / dev->nChunksPerBlock, @@ -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++; @@ -2969,7 +2974,6 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block, isCheckpointBlock = (bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT); - bi->blockState = YAFFS_BLOCK_STATE_COLLECTING; T(YAFFS_TRACE_TRACING, (TSTR("Collecting block %d, in use %d, shrink %d, wholeBlock %d" TENDSTR), @@ -2980,12 +2984,16 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block, /*yaffs_VerifyFreeChunks(dev); */ + if(bi->blockState == YAFFS_BLOCK_STATE_FULL) + bi->blockState = YAFFS_BLOCK_STATE_COLLECTING; + bi->hasShrinkHeader = 0; /* clear the flag so that the block can erase */ /* Take off the number of soft deleted entries because * they're going to get really deleted during GC. */ - dev->nFreeChunks -= bi->softDeletions; + if(dev->gcChunk == 0) /* first time through for this block */ + dev->nFreeChunks -= bi->softDeletions; dev->isDoingGC = 1; @@ -3629,7 +3637,7 @@ static int yaffs_WriteChunkDataToObject(yaffs_Object *in, int chunkInInode, newTags.chunkId = chunkInInode; newTags.objectId = in->objectId; newTags.serialNumber = - (prevChunkId >= 0) ? prevTags.serialNumber + 1 : 1; + (prevChunkId > 0) ? prevTags.serialNumber + 1 : 1; newTags.byteCount = nBytes; if (nBytes < 1 || nBytes > dev->totalBytesPerChunk) { @@ -3645,7 +3653,7 @@ static int yaffs_WriteChunkDataToObject(yaffs_Object *in, int chunkInInode, if (newChunkId >= 0) { yaffs_PutChunkIntoFile(in, chunkInInode, newChunkId, 0); - if (prevChunkId >= 0) + if (prevChunkId > 0) yaffs_DeleteChunk(dev, prevChunkId, 1, __LINE__); yaffs_CheckFileSanity(in); @@ -3731,7 +3739,7 @@ int yaffs_UpdateObjectHeader(yaffs_Object *in, const YCHAR *name, int force, if (name && *name) { memset(oh->name, 0, sizeof(oh->name)); yaffs_strncpy(oh->name, name, YAFFS_MAX_NAME_LENGTH); - } else if (prevChunkId >= 0) + } else if (prevChunkId > 0) memcpy(oh->name, oldName, sizeof(oh->name)); else memset(oh->name, 0, sizeof(oh->name)); @@ -3789,13 +3797,13 @@ int yaffs_UpdateObjectHeader(yaffs_Object *in, const YCHAR *name, int force, /* Create new chunk in NAND */ newChunkId = yaffs_WriteNewChunkWithTagsToNAND(dev, buffer, &newTags, - (prevChunkId >= 0) ? 1 : 0); + (prevChunkId > 0) ? 1 : 0); if (newChunkId >= 0) { in->hdrChunk = newChunkId; - if (prevChunkId >= 0) { + if (prevChunkId > 0) { yaffs_DeleteChunk(dev, prevChunkId, 1, __LINE__); } @@ -5052,23 +5060,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; } @@ -5169,14 +5181,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) @@ -5292,7 +5309,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); } @@ -6808,7 +6827,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; } @@ -7057,7 +7076,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