X-Git-Url: http://www.aleph1.co.uk/gitweb/?a=blobdiff_plain;f=yaffs_guts.c;h=bcd3da1082675e008e918e5491a3af772d77af64;hb=8cc260c1954603f2efcd13bca480eed8bd47a7e2;hp=5cbd371a938ecafc39814e049f7ca0381eac1e78;hpb=2f1fbd5011ef15fa3d1c95dc24dcc656a9aa9b5f;p=yaffs%2F.git diff --git a/yaffs_guts.c b/yaffs_guts.c index 5cbd371..bcd3da1 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -14,7 +14,7 @@ */ //yaffs_guts.c -const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.27 2003-08-16 08:17:32 charles Exp $"; +const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.34 2004-06-08 08:47:55 charles Exp $"; #include "yportenv.h" @@ -782,11 +782,16 @@ static void yaffs_FreeTnode(yaffs_Device*dev, yaffs_Tnode *tn) static void yaffs_DeinitialiseTnodes(yaffs_Device*dev) { // Free the list of allocated tnodes - + yaffs_TnodeList *tmp; + while(dev->allocatedTnodeList) { + tmp = dev->allocatedTnodeList->next; + YFREE(dev->allocatedTnodeList->tnodes); - dev->allocatedTnodeList = dev->allocatedTnodeList->next; + YFREE(dev->allocatedTnodeList); + dev->allocatedTnodeList = tmp; + } dev->freeTnodes = NULL; @@ -1080,7 +1085,7 @@ static int yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level, in if(limit) { *limit = *limit-1; - if(limit <= 0) + if(*limit <= 0) { hitLimit = 1; } @@ -1151,6 +1156,8 @@ static int yaffs_SoftDeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level { if(tn->level0[i]) { + // Note this does not find the real chunk, only the chunk group. + // We make an assumption that a chunk group is niot larger than a block. theChunk = (tn->level0[i] << in->myDev->chunkGroupBits); T(YAFFS_TRACE_SCAN,(TSTR("soft delete tch %d cgb %d chunk %d" TENDSTR), tn->level0[i],in->myDev->chunkGroupBits,theChunk)); @@ -1452,10 +1459,15 @@ static void yaffs_DeinitialiseObjects(yaffs_Device *dev) { // Free the list of allocated Objects + yaffs_ObjectList *tmp; + while( dev->allocatedObjectList) { + tmp = dev->allocatedObjectList->next; YFREE(dev->allocatedObjectList->objects); - dev->allocatedObjectList = dev->allocatedObjectList->next; + YFREE(dev->allocatedObjectList); + + dev->allocatedObjectList = tmp; } dev->freeObjects = NULL; @@ -1731,7 +1743,7 @@ yaffs_Object *yaffs_MknodObject( yaffs_ObjectType type, #ifdef CONFIG_YAFFS_WINCE yfsd_WinFileTimeNow(in->win_atime); in->win_ctime[0] = in->win_mtime[0] = in->win_atime[0]; - in->win_ctime[1] = in->win_mtime[1] = in->win_atime[0]; + in->win_ctime[1] = in->win_mtime[1] = in->win_atime[1]; #else #if defined(CONFIG_KERNEL_2_5) @@ -2290,6 +2302,7 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev,int block) { // It's a header object->chunkId = newChunk; + object->serial = tags.serialNumber; } else { @@ -2831,6 +2844,7 @@ int yaffs_ReadChunkDataFromObject(yaffs_Object *in,int chunkInInode, __u8 *buffe } else { + memset(buffer,0,YAFFS_BYTES_PER_CHUNK); return 0; } @@ -2853,7 +2867,14 @@ static void yaffs_DeleteChunk(yaffs_Device *dev,int chunkId,int markNAND) if(markNAND) { yaffs_SpareInitialise(&spare); - + +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE + + //read data before write, to ensure correct ecc + //if we're using MTD verification under Linux + yaffs_ReadChunkFromNAND(dev,chunkId,NULL,&spare,0); +#endif + spare.pageStatus = 0; // To mark it as deleted. @@ -3649,8 +3670,10 @@ int yaffs_ResizeFile(yaffs_Object *in, int newSize) int lastChunk = 1+ newSize/YAFFS_BYTES_PER_CHUNK; // Got to read and rewrite the last chunk with its new size. + // NB Got to zero pad to nuke old data yaffs_ReadChunkDataFromObject(in,lastChunk,dev->localBuffer); - + memset(dev->localBuffer + sizeOfPartialChunk,0, YAFFS_BYTES_PER_CHUNK - sizeOfPartialChunk); + yaffs_WriteChunkDataToObject(in,lastChunk,dev->localBuffer,sizeOfPartialChunk,1); } @@ -4205,8 +4228,9 @@ static int yaffs_Scan(yaffs_Device *dev) { // Hoosterman, another problem.... // We're trying to use a non-directory as a directory - // Todo ... handle - T(YAFFS_TRACE_ERROR, (TSTR("yaffs tragedy: attempting to use non-directory as a directory in scan" TENDSTR))); + + T(YAFFS_TRACE_ERROR, (TSTR("yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found." TENDSTR))); + parent = dev->lostNFoundDir; } @@ -4656,8 +4680,7 @@ int yaffs_GutsInitialise(yaffs_Device *dev) int extraBits; int nBlocks; - if( dev->nBytesPerChunk != YAFFS_BYTES_PER_CHUNK || - + if( dev->nBytesPerChunk != YAFFS_BYTES_PER_CHUNK || dev->nChunksPerBlock < 2 || dev->nReservedBlocks < 2 || dev->startBlock <= 0 || @@ -4724,7 +4747,18 @@ int yaffs_GutsInitialise(yaffs_Device *dev) { dev->chunkGroupBits = bits - 16; } + dev->chunkGroupSize = 1 << dev->chunkGroupBits; + + if(dev->nChunksPerBlock < dev->chunkGroupSize) + { + // We have a problem because the soft delete won't work if + // the chunk group size > chunks per block. + // This can be remedied by using larger "virtual blocks". + + return YAFFS_FAIL; + } + @@ -4810,6 +4844,8 @@ void yaffs_Deinitialise(yaffs_Device *dev) yaffs_DeinitialiseBlocks(dev); yaffs_DeinitialiseTnodes(dev); yaffs_DeinitialiseObjects(dev); + if(dev->nShortOpCaches > 0) + YFREE(dev->srCache); YFREE(dev->localBuffer); }