X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_guts.c;h=3fa5da5271dcabba45e3f49efeb2c6c3501dfcff;hp=ae6e342502f40d585a39a47f74e771016316b95c;hb=9aea1b1a930d249e5c0272b80f21ab7eca9dece6;hpb=cc0617d99eaa089a61ac49b21d07a16280638806 diff --git a/yaffs_guts.c b/yaffs_guts.c index ae6e342..3fa5da5 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -11,8 +11,9 @@ * published by the Free Software Foundation. */ + const char *yaffs_guts_c_version = - "$Id: yaffs_guts.c,v 1.70 2009-01-09 02:52:28 charles Exp $"; + "$Id: yaffs_guts.c,v 1.76 2009-01-23 06:36:49 charles Exp $"; #include "yportenv.h" @@ -33,11 +34,6 @@ const char *yaffs_guts_c_version = #include "yaffs_packedtags2.h" -#ifdef CONFIG_YAFFS_WINCE -void yfsd_LockYAFFS(BOOL fsLockOnly); -void yfsd_UnlockYAFFS(BOOL fsLockOnly); -#endif - #define YAFFS_PASSIVE_GC_CHUNKS 2 #include "yaffs_ecc.h" @@ -751,10 +747,15 @@ static void yaffs_VerifyObject(yaffs_Object *obj) __u32 chunkMax; __u32 chunkIdOk; - __u32 chunkIsLive; + __u32 chunkInRange; + __u32 chunkShouldNotBeDeleted; + __u32 chunkValid; if(!obj) return; + + if(obj->beingCreated) + return; dev = obj->myDev; @@ -766,21 +767,24 @@ static void yaffs_VerifyObject(yaffs_Object *obj) chunkMin = dev->internalStartBlock * dev->nChunksPerBlock; chunkMax = (dev->internalEndBlock+1) * dev->nChunksPerBlock - 1; - chunkIdOk = (((unsigned)(obj->hdrChunk)) >= chunkMin && ((unsigned)(obj->hdrChunk)) <= chunkMax); - chunkIsLive = chunkIdOk && + chunkInRange = (((unsigned)(obj->hdrChunk)) >= chunkMin && ((unsigned)(obj->hdrChunk)) <= chunkMax); + chunkIdOk = chunkInRange || obj->hdrChunk == 0; + chunkValid = chunkInRange && yaffs_CheckChunkBit(dev, obj->hdrChunk / dev->nChunksPerBlock, obj->hdrChunk % dev->nChunksPerBlock); + chunkShouldNotBeDeleted = chunkInRange && !chunkValid; + if(!obj->fake && - (!chunkIdOk || !chunkIsLive)) { + (!chunkIdOk || chunkShouldNotBeDeleted)) { T(YAFFS_TRACE_VERIFY, (TSTR("Obj %d has chunkId %d %s %s"TENDSTR), obj->objectId,obj->hdrChunk, chunkIdOk ? "" : ",out of range", - chunkIsLive || !chunkIdOk ? "" : ",marked as deleted")); + chunkShouldNotBeDeleted ? ",marked as deleted" : "")); } - if(chunkIdOk && chunkIsLive &&!yaffs_SkipNANDVerification(dev)) { + if(chunkValid &&!yaffs_SkipNANDVerification(dev)) { yaffs_ExtendedTags tags; yaffs_ObjectHeader *oh; __u8 *buffer = yaffs_GetTempBuffer(dev,__LINE__); @@ -1925,6 +1929,8 @@ static yaffs_Object *yaffs_AllocateEmptyObject(yaffs_Device * dev) /* Now sweeten it up... */ memset(tn, 0, sizeof(yaffs_Object)); + tn->beingCreated = 1; + tn->myDev = dev; tn->hdrChunk = 0; tn->variantType = YAFFS_OBJECT_TYPE_UNKNOWN; @@ -1946,6 +1952,8 @@ static yaffs_Object *yaffs_AllocateEmptyObject(yaffs_Device * dev) if (dev->lostNFoundDir) { yaffs_AddObjectToDirectory(dev->lostNFoundDir, tn); } + + tn->beingCreated = 0; } dev->nCheckpointBlocksRequired = 0; /* force recalculation*/ @@ -4363,7 +4371,6 @@ static int yaffs_CheckpointTnodeWorker(yaffs_Object * in, yaffs_Tnode * tn, } } else if (level == 0) { __u32 baseOffset = chunkOffset << YAFFS_TNODES_LEVEL0_BITS; - /* printf("write tnode at %d\n",baseOffset); */ ok = (yaffs_CheckpointWrite(dev,&baseOffset,sizeof(baseOffset)) == sizeof(baseOffset)); if(ok) ok = (yaffs_CheckpointWrite(dev,tn,tnodeSize) == tnodeSize); @@ -4412,7 +4419,6 @@ static int yaffs_ReadCheckpointTnodes(yaffs_Object *obj) /* Read level 0 tnode */ - /* printf("read tnode at %d\n",baseChunk); */ tn = yaffs_GetTnodeRaw(dev); if(tn) ok = (yaffs_CheckpointRead(dev,tn,tnodeSize) == tnodeSize); @@ -4772,14 +4778,9 @@ int yaffs_ReadDataFromFile(yaffs_Object * in, __u8 * buffer, loff_t offset, cache->locked = 1; -#ifdef CONFIG_YAFFS_WINCE - yfsd_UnlockYAFFS(TRUE); -#endif + memcpy(buffer, &cache->data[start], nToCopy); -#ifdef CONFIG_YAFFS_WINCE - yfsd_LockYAFFS(TRUE); -#endif cache->locked = 0; } else { /* Read into the local buffer then copy..*/ @@ -4788,41 +4789,19 @@ int yaffs_ReadDataFromFile(yaffs_Object * in, __u8 * buffer, loff_t offset, yaffs_GetTempBuffer(dev, __LINE__); yaffs_ReadChunkDataFromObject(in, chunk, localBuffer); -#ifdef CONFIG_YAFFS_WINCE - yfsd_UnlockYAFFS(TRUE); -#endif + memcpy(buffer, &localBuffer[start], nToCopy); -#ifdef CONFIG_YAFFS_WINCE - yfsd_LockYAFFS(TRUE); -#endif + yaffs_ReleaseTempBuffer(dev, localBuffer, __LINE__); } } else { -#ifdef CONFIG_YAFFS_WINCE - __u8 *localBuffer = yaffs_GetTempBuffer(dev, __LINE__); - - /* Under WinCE can't do direct transfer. Need to use a local buffer. - * This is because we otherwise screw up WinCE's memory mapper - */ - yaffs_ReadChunkDataFromObject(in, chunk, localBuffer); - -#ifdef CONFIG_YAFFS_WINCE - yfsd_UnlockYAFFS(TRUE); -#endif - memcpy(buffer, localBuffer, dev->nDataBytesPerChunk); - -#ifdef CONFIG_YAFFS_WINCE - yfsd_LockYAFFS(TRUE); - yaffs_ReleaseTempBuffer(dev, localBuffer, __LINE__); -#endif -#else /* A full chunk. Read directly into the supplied buffer. */ yaffs_ReadChunkDataFromObject(in, chunk, buffer); -#endif + } n -= nToCopy; @@ -4934,16 +4913,12 @@ int yaffs_WriteDataToFile(yaffs_Object * in, const __u8 * buffer, loff_t offset, if (cache) { yaffs_UseChunkCache(dev, cache, 1); cache->locked = 1; -#ifdef CONFIG_YAFFS_WINCE - yfsd_UnlockYAFFS(TRUE); -#endif + memcpy(&cache->data[start], buffer, nToCopy); -#ifdef CONFIG_YAFFS_WINCE - yfsd_LockYAFFS(TRUE); -#endif + cache->locked = 0; cache->nBytes = nToWriteBack; @@ -4971,15 +4946,10 @@ int yaffs_WriteDataToFile(yaffs_Object * in, const __u8 * buffer, loff_t offset, yaffs_ReadChunkDataFromObject(in, chunk, localBuffer); -#ifdef CONFIG_YAFFS_WINCE - yfsd_UnlockYAFFS(TRUE); -#endif + memcpy(&localBuffer[start], buffer, nToCopy); -#ifdef CONFIG_YAFFS_WINCE - yfsd_LockYAFFS(TRUE); -#endif chunkWritten = yaffs_WriteChunkDataToObject(in, chunk, localBuffer, @@ -4994,30 +4964,13 @@ int yaffs_WriteDataToFile(yaffs_Object * in, const __u8 * buffer, loff_t offset, } else { /* A full chunk. Write directly from the supplied buffer. */ -#ifdef CONFIG_YAFFS_WINCE - /* Under WinCE can't do direct transfer. Need to use a local buffer. - * This is because we otherwise screw up WinCE's memory mapper - */ - __u8 *localBuffer = yaffs_GetTempBuffer(dev, __LINE__); -#ifdef CONFIG_YAFFS_WINCE - yfsd_UnlockYAFFS(TRUE); -#endif - memcpy(localBuffer, buffer, dev->nDataBytesPerChunk); -#ifdef CONFIG_YAFFS_WINCE - yfsd_LockYAFFS(TRUE); -#endif - chunkWritten = - yaffs_WriteChunkDataToObject(in, chunk, localBuffer, - dev->nDataBytesPerChunk, - 0); - yaffs_ReleaseTempBuffer(dev, localBuffer, __LINE__); -#else + chunkWritten = yaffs_WriteChunkDataToObject(in, chunk, buffer, dev->nDataBytesPerChunk, 0); -#endif + /* Since we've overwritten the cached data, we better invalidate it. */ yaffs_InvalidateChunkCache(in, chunk); } @@ -5514,6 +5467,35 @@ struct yaffs_ShadowFixerStruct { struct yaffs_ShadowFixerStruct *next; }; + +static void yaffs_StripDeletedObjects(yaffs_Device *dev) +{ + /* + * Sort out state of unlinked and deleted objects after scanning. + */ + struct ylist_head *i; + struct ylist_head *n; + yaffs_Object *l; + + /* Soft delete all the unlinked files */ + ylist_for_each_safe(i, n, + &dev->unlinkedDir->variant.directoryVariant.children) { + if (i) { + l = ylist_entry(i, yaffs_Object, siblings); + yaffs_DestroyObject(l); + } + } + + ylist_for_each_safe(i, n, + &dev->deletedDir->variant.directoryVariant.children) { + if (i) { + l = ylist_entry(i, yaffs_Object, siblings); + yaffs_DestroyObject(l); + } + } + +} + static int yaffs_Scan(yaffs_Device * dev) { yaffs_ExtendedTags tags; @@ -5914,25 +5896,6 @@ static int yaffs_Scan(yaffs_Device * dev) yaffs_HardlinkFixup(dev,hardList); - /* Handle the unlinked files. Since they were left in an unlinked state we should - * just delete them. - */ - { - struct ylist_head *i; - struct ylist_head *n; - - yaffs_Object *l; - /* Soft delete all the unlinked files */ - ylist_for_each_safe(i, n, - &dev->unlinkedDir->variant.directoryVariant. - children) { - if (i) { - l = ylist_entry(i, yaffs_Object, siblings); - yaffs_DestroyObject(l); - } - } - } - /* Fix up any shadowed objects */ { struct yaffs_ShadowFixerStruct *fixer; @@ -6276,7 +6239,14 @@ static int yaffs_ScanBackwards(yaffs_Device * dev) dev->nFreeChunks++; - } else if (tags.chunkId > 0) { + } else if (tags.eccResult == YAFFS_ECC_RESULT_UNFIXED){ + T(YAFFS_TRACE_SCAN, + (TSTR(" Unfixed ECC in chunk(%d:%d), chunk ignored"TENDSTR), + blk, c)); + + dev->nFreeChunks++; + + }else if (tags.chunkId > 0) { /* chunkId > 0 so it is a data chunk... */ unsigned int endpos; __u32 chunkBase = @@ -6664,37 +6634,6 @@ static int yaffs_ScanBackwards(yaffs_Device * dev) */ yaffs_HardlinkFixup(dev,hardList); - - /* - * Sort out state of unlinked and deleted objects. - */ - { - struct ylist_head *i; - struct ylist_head *n; - - yaffs_Object *l; - - /* Soft delete all the unlinked files */ - ylist_for_each_safe(i, n, - &dev->unlinkedDir->variant.directoryVariant. - children) { - if (i) { - l = ylist_entry(i, yaffs_Object, siblings); - yaffs_DestroyObject(l); - } - } - - /* Soft delete all the deletedDir files */ - ylist_for_each_safe(i, n, - &dev->deletedDir->variant.directoryVariant. - children) { - if (i) { - l = ylist_entry(i, yaffs_Object, siblings); - yaffs_DestroyObject(l); - - } - } - } yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__); @@ -7507,6 +7446,8 @@ int yaffs_GutsInitialise(yaffs_Device * dev) }else if(!yaffs_Scan(dev)) init_failed = 1; + + yaffs_StripDeletedObjects(dev); } if(init_failed){