From e7944bf67d156b9ecb1c8cdf9223dfb0e3154ba4 Mon Sep 17 00:00:00 2001 From: charles Date: Wed, 21 Aug 2002 09:01:27 +0000 Subject: [PATCH] *** empty log message *** --- Documentation/yaffs-todo.html | 5 +- snMakefile | 2 +- yaffs_fileem.c | 70 ++++++++- yaffs_fs.c | 7 +- yaffs_guts.c | 277 +++++++++++++++++++++++++++------- yaffs_guts.h | 15 +- yaffsdev | Bin 109461 -> 113516 bytes yaffsdev.c | 9 +- yaffsdev.proj | Bin 36864 -> 36864 bytes 9 files changed, 317 insertions(+), 68 deletions(-) diff --git a/Documentation/yaffs-todo.html b/Documentation/yaffs-todo.html index 59ebd0a..831b2d3 100644 --- a/Documentation/yaffs-todo.html +++ b/Documentation/yaffs-todo.html @@ -10,13 +10,11 @@ -

YAFFS Todo as at 09/07/2002

+

YAFFS Todo as at 21/08/2002

Stuff not yet done

  1. Directory locking during directory walk.

  2. Other locking.... investigate what is needed.

    -
  3. Test disk full condition.... investigate might not be being - handled correctly.

  4. Add write memory mapping. We probably need this to support loop mounting.

  5. At scan time, check that the file size in the ObjectHeader @@ -51,6 +49,7 @@ significant testing) the spirit of mkcramfs).

  6. Added support for special inodes (pipes, character & block devices, sockets).

    +
  7. Added generic read/write support to use page caching.

Done, but currently known to be broken

    diff --git a/snMakefile b/snMakefile index 1573c7b..936c08d 100644 --- a/snMakefile +++ b/snMakefile @@ -1,6 +1,6 @@ ######################################################### # Makefile auto generated by Cygnus Source Navigator. -# Target: yaffsdev_disk Date: Aug 09 2002 Time: 09:26:40 AM +# Target: yaffsdev_disk Date: Aug 21 2002 Time: 03:51:36 PM # diff --git a/yaffs_fileem.c b/yaffs_fileem.c index dbbe5f8..dd77b37 100644 --- a/yaffs_fileem.c +++ b/yaffs_fileem.c @@ -54,6 +54,62 @@ static int IsAMarkedBadBlock(int blk) } +static __u8 yaffs_WriteFailCorruption(int chunkInNAND) +{ + switch(chunkInNAND) + { + case 2000: + case 2003: + case 3000: + case 3001: + return 3;// ding two bits + case 2001: + case 3003: + case 3004: + case 3005: + case 3006: + case 3007: return 1;// ding one bit + + default: return 0; + + } +} + +static void yaffs_ModifyWriteData(int chunkInNAND,__u8 *data) +{ + if(data) + { + *data ^= yaffs_WriteFailCorruption(chunkInNAND); + } +} + +static __u8 yaffs_ReadFailCorruption(int chunkInNAND) +{ + switch(chunkInNAND) + { + case 500: + return 3;// ding two bits + case 700: + case 750: + return 1;// ding one bit + + default: return 0; + + } +} + +static void yaffs_ModifyReadData(int chunkInNAND,__u8 *data) +{ + if(data) + { + *data ^= yaffs_ReadFailCorruption(chunkInNAND); + } +} + + + + + static void CheckInit(yaffs_Device *dev) { static int initialised = 0; @@ -100,6 +156,8 @@ static void CheckInit(yaffs_Device *dev) int yaffs_FEWriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_Spare *spare) { + __u8 localData[512]; + int pos; pos = chunkInNAND * 528; @@ -109,8 +167,10 @@ int yaffs_FEWriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, if(data) { + memcpy(localData,data,512); + yaffs_ModifyWriteData(chunkInNAND,localData); lseek(h,pos,SEEK_SET); - write(h,data,512); + write(h,localData,512); } pos += 512; @@ -138,6 +198,7 @@ int yaffs_FEReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaf { lseek(h,pos,SEEK_SET); read(h,data,512); + yaffs_ModifyReadData(chunkInNAND,data); } pos += 512; @@ -168,6 +229,13 @@ int yaffs_FEEraseBlockInNAND(yaffs_Device *dev,int blockInNAND) { write(h,ffChunk,528); } + + switch(blockInNAND) + { + case 10: + case 15: return YAFFS_FAIL; + + } return YAFFS_OK; } diff --git a/yaffs_fs.c b/yaffs_fs.c index 8bea30d..b0608f9 100644 --- a/yaffs_fs.c +++ b/yaffs_fs.c @@ -109,7 +109,7 @@ static struct address_space_operations yaffs_file_address_operations = { static struct file_operations yaffs_file_operations = { -#if CONFIG_YAFFS_USE_GENERIC_RW +#ifdef CONFIG_YAFFS_USE_GENERIC_RW read: generic_file_read, write: generic_file_write, #else @@ -341,7 +341,7 @@ static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, T((KERN_DEBUG"yaffs_commit_write returning %d\n",nWritten)); - return nWritten /* != nBytes ? -ENOMEM : 0 */ ; + return nWritten; } @@ -445,6 +445,7 @@ static ssize_t yaffs_file_read(struct file *f, char *buf, size_t n, loff_t *pos) } + static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, loff_t *pos) { yaffs_Object *obj; @@ -489,7 +490,7 @@ static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, loff_ } } - return nWritten; + return nWritten != n ? -ENOSPC : nWritten; } diff --git a/yaffs_guts.c b/yaffs_guts.c index caf9289..abb01e2 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -29,7 +29,7 @@ int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc); // countBits is a quick way of counting the number of bits in a byte. // ie. countBits[n] holds the number of 1 bits in a byte with the value n. -static const char yaffs_countBits[256] = +static const char yaffs_countBitsTable[256] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4, 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, @@ -49,6 +49,13 @@ static const char yaffs_countBits[256] = 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 }; +static int yaffs_CountBits(__u8 x) +{ + int retVal; + retVal = yaffs_countBitsTable[x]; + return retVal; +} + // Device info @@ -71,6 +78,21 @@ static void yaffs_DeleteChunk(yaffs_Device *dev,int chunkId); static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj); static int yaffs_CheckStructures(void); +// Robustification +static void yaffs_RetireBlock(yaffs_Device *dev,int blockInNAND); +static void yaffs_HandleReadDataError(yaffs_Device *dev,int chunkInNAND); +static void yaffs_HandleWriteChunkError(yaffs_Device *dev,int chunkInNAND); +static void yaffs_HandleWriteChunkOk(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_Spare *spare); +static void yaffs_HandleUpdateChunk(yaffs_Device *dev,int chunkInNAND, const yaffs_Spare *spare); + +static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,int chunkInNAND); + + + +static int yaffs_VerifyCompare(const __u8 *d0, const __u8 * d1, const yaffs_Spare *s0, const yaffs_Spare *s1); + + + loff_t yaffs_GetFileSize(yaffs_Object *obj); static int yaffs_ReadChunkTagsFromNAND(yaffs_Device *dev,int chunkInNAND, yaffs_Tags *tags, int *chunkDeleted); @@ -108,7 +130,8 @@ static int yaffs_WriteChunkToNAND(struct yaffs_DeviceStruct *dev,int chunkInNAND return dev->writeChunkToNAND(dev,chunkInNAND,data,spare); } -int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare) + +int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare,int doErrorCorrection) { int retVal; __u8 calcEcc[3]; @@ -125,7 +148,7 @@ int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,int chunkInNAND, __u8 } retVal = dev->readChunkFromNAND(dev,chunkInNAND,data,spare); - if(data) + if(data && doErrorCorrection) { // Do ECC correction //Todo handle any errors @@ -151,22 +174,26 @@ int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,int chunkInNAND, __u8 { T((TSTR("**>>ecc error unfixed on chunk %d:1" TENDSTR),chunkInNAND)); } + + if(eccResult1 || eccResult2) + { + // Hoosterman, we had a data problem on this page + yaffs_HandleReadDataError(dev,chunkInNAND); + } } return retVal; } -#ifdef YAFFS_PARANOID static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,int chunkInNAND) { +#if 1 + static int init = 0; static __u8 cmpbuf[YAFFS_BYTES_PER_CHUNK]; static __u8 data[YAFFS_BYTES_PER_CHUNK]; static __u8 spare[16]; - int retVal; - - retVal = YAFFS_OK; dev->readChunkFromNAND(dev,chunkInNAND,data,(yaffs_Spare *)spare); @@ -178,14 +205,15 @@ static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,int chunkInNAND init = 1; } - if(memcmp(cmpbuf,data,YAFFS_BYTES_PER_CHUNK)) retVal = YAFFS_FAIL; - if(memcmp(cmpbuf,spare,16)) retVal = YAFFS_FAIL; + if(memcmp(cmpbuf,data,YAFFS_BYTES_PER_CHUNK)) return YAFFS_FAIL; + if(memcmp(cmpbuf,spare,16)) return YAFFS_FAIL; + +#endif - return retVal; + return YAFFS_OK; } -#endif int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,int blockInNAND) @@ -203,7 +231,7 @@ static int yaffs_WriteNewChunkToNAND(struct yaffs_DeviceStruct *dev, const __u8 { int chunk; - int writeOk = 0; + int writeOk = 1; int attempts = 0; unsigned char rbData[YAFFS_BYTES_PER_CHUNK]; @@ -214,7 +242,14 @@ static int yaffs_WriteNewChunkToNAND(struct yaffs_DeviceStruct *dev, const __u8 if(chunk >= 0) { - writeOk = yaffs_WriteChunkToNAND(dev,chunk,data,spare); + + // First check this chunk is erased... + writeOk = yaffs_CheckChunkErased(dev,chunk); + + if(writeOk) + { + writeOk = yaffs_WriteChunkToNAND(dev,chunk,data,spare); + } attempts++; if(writeOk) { @@ -222,33 +257,32 @@ static int yaffs_WriteNewChunkToNAND(struct yaffs_DeviceStruct *dev, const __u8 // If verify fails, then delete this chunk and try again // To verify we compare everything except the block and // page status bytes. - yaffs_ReadChunkFromNAND(dev,chunk,rbData,&rbSpare); + // NB We check a raw read without ECC correction applied + yaffs_ReadChunkFromNAND(dev,chunk,rbData,&rbSpare,0); - if(memcmp(data,rbData,YAFFS_BYTES_PER_CHUNK) != 0 || - spare->tagByte0 != rbSpare.tagByte0 || - spare->tagByte1 != rbSpare.tagByte1 || - spare->tagByte2 != rbSpare.tagByte2 || - spare->tagByte3 != rbSpare.tagByte3 || - spare->tagByte4 != rbSpare.tagByte4 || - spare->tagByte5 != rbSpare.tagByte5 || - spare->tagByte6 != rbSpare.tagByte6 || - spare->tagByte7 != rbSpare.tagByte7 || - spare->ecc1[0] != rbSpare.ecc1[0] || - spare->ecc1[1] != rbSpare.ecc1[1] || - spare->ecc1[2] != rbSpare.ecc1[2] || - spare->ecc2[0] != rbSpare.ecc2[0] || - spare->ecc2[1] != rbSpare.ecc2[1] || - spare->ecc2[2] != rbSpare.ecc2[2] ) - { + if(!yaffs_VerifyCompare(data,rbData,spare,&rbSpare)) + { // Didn't verify - yaffs_DeleteChunk(dev,chunk); T((TSTR("**>> yaffs write failed on chunk %d" TENDSTR), chunk)); + // yaffs_DeleteChunk(dev,chunk); writeOk = 0; } } + if(writeOk) + { + // Copy the data into the write buffer. + // NB We do this at the end to prevent duplicates in the case of a write error. + //Todo + yaffs_HandleWriteChunkOk(dev,chunk,data,spare); + } + else + { + yaffs_HandleWriteChunkError(dev,chunk); + } } + } while(chunk >= 0 && ! writeOk); if(attempts > 1) @@ -260,8 +294,94 @@ static int yaffs_WriteNewChunkToNAND(struct yaffs_DeviceStruct *dev, const __u8 return chunk; } +/// +// Functions for robustisizing +// +// + +static void yaffs_RetireBlock(yaffs_Device *dev,int blockInNAND) +{ + // Ding the blockStatus in the first two pages of the block. + + yaffs_Spare spare; + + memset(&spare, 0xff,sizeof(yaffs_Spare)); + + spare.blockStatus = 0; + + yaffs_WriteChunkToNAND(dev, blockInNAND * YAFFS_CHUNKS_PER_BLOCK, NULL , &spare); + yaffs_WriteChunkToNAND(dev, blockInNAND * YAFFS_CHUNKS_PER_BLOCK + 1, NULL , &spare); + + dev->blockInfo[blockInNAND].blockState = YAFFS_BLOCK_STATE_DEAD; + dev->nRetiredBlocks++; +} + +static int yaffs_RewriteBufferedBlock(yaffs_Device *dev) +{ + dev->doingBufferedBlockRewrite = 1; + // + // Remove erased chunks + // Rewrite existing chunks to a new block + // Set current write block to the new block + + dev->doingBufferedBlockRewrite = 0; +} + + +static void yaffs_HandleReadDataError(yaffs_Device *dev,int chunkInNAND) +{ + + // Just do a garbage collection on the affected block then retire the block + // NB recursion +} + + +static void yaffs_CheckWrittenBlock(yaffs_Device *dev,int chunkInNAND) +{ +} + +static void yaffs_HandleWriteChunkOk(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_Spare *spare) +{ +} + +static void yaffs_HandleUpdateChunk(yaffs_Device *dev,int chunkInNAND, const yaffs_Spare *spare) +{ +} + +static void yaffs_HandleWriteChunkError(yaffs_Device *dev,int chunkInNAND) +{ +} + + + + +static int yaffs_VerifyCompare(const __u8 *d0, const __u8 * d1, const yaffs_Spare *s0, const yaffs_Spare *s1) +{ + + if( memcmp(d0,d1,YAFFS_BYTES_PER_CHUNK) != 0 || + s0->tagByte0 != s1->tagByte0 || + s0->tagByte1 != s1->tagByte1 || + s0->tagByte2 != s1->tagByte2 || + s0->tagByte3 != s1->tagByte3 || + s0->tagByte4 != s1->tagByte4 || + s0->tagByte5 != s1->tagByte5 || + s0->tagByte6 != s1->tagByte6 || + s0->tagByte7 != s1->tagByte7 || + s0->ecc1[0] != s1->ecc1[0] || + s0->ecc1[1] != s1->ecc1[1] || + s0->ecc1[2] != s1->ecc1[2] || + s0->ecc2[0] != s1->ecc2[0] || + s0->ecc2[1] != s1->ecc2[1] || + s0->ecc2[2] != s1->ecc2[2] ) + { + return 0; + } + + return 1; +} + ///////////////////////// Object management ////////////////// // List of spare objects @@ -1291,7 +1411,12 @@ yaffs_Object *yaffs_MknodObject( yaffs_ObjectType type, break; } - yaffs_UpdateObjectHeader(in,name); + if(yaffs_UpdateObjectHeader(in,name) < 0) + { + // Could not create the object header, fail the creation + yaffs_UnlinkWorker(in); + in = NULL; + } } @@ -1468,6 +1593,7 @@ void yaffs_ObjectTest(yaffs_Device *dev) static void yaffs_InitialiseBlocks(yaffs_Device *dev) { + //Todo we're assuming the malloc will pass. dev->blockInfo = YMALLOC(dev->nBlocks * sizeof(yaffs_BlockInfo)); memset(dev->blockInfo,0,dev->nBlocks * sizeof(yaffs_BlockInfo)); dev->allocationBlock = -1; // force it to get a new one @@ -1554,15 +1680,25 @@ static void yaffs_BlockBecameDirty(yaffs_Device *dev,int blockNo) { yaffs_BlockInfo *bi = &dev->blockInfo[blockNo]; - // Mark as dirty, erase it and mark as clean. + // Mark as dirty. + // If the block is still healthy erase it and mark as clean. + // If the block has had a data failure, then retire it. bi->blockState = YAFFS_BLOCK_STATE_DIRTY; - yaffs_EraseBlockInNAND(dev,blockNo); - bi->blockState = YAFFS_BLOCK_STATE_EMPTY; - dev->nErasedBlocks++; - bi->pagesInUse = 0; - bi->pageBits = 0; - T((TSTR("Erased block %d" TENDSTR),blockNo)); + if(!bi->needsRetiring && yaffs_EraseBlockInNAND(dev,blockNo)) + { + bi->blockState = YAFFS_BLOCK_STATE_EMPTY; + dev->nErasedBlocks++; + bi->pagesInUse = 0; + bi->pageBits = 0; + + T((TSTR("Erased block %d" TENDSTR),blockNo)); + } + else + { + yaffs_RetireBlock(dev,blockNo); + T((TSTR("**>> Block %d retired" TENDSTR),blockNo)); + } } @@ -1642,7 +1778,7 @@ int yaffs_GarbageCollectBlock(yaffs_Device *dev,int block) //T(("copying page %x from %d to %d\n",mask,oldChunk,newChunk)); - yaffs_ReadChunkFromNAND(dev,oldChunk,buffer, &spare); + yaffs_ReadChunkFromNAND(dev,oldChunk,buffer, &spare,1); yaffs_GetTagsFromSpare(&spare,&tags); tags.serialNumber++; @@ -1696,7 +1832,15 @@ int yaffs_CheckGarbageCollection(yaffs_Device *dev) if(dev->garbageCollectionRequired) { dev->garbageCollectionRequired = 0; - block = yaffs_FindDirtiestBlock(dev); + if(dev->blockSelectedForGC >= 0) + { + block = dev->blockSelectedForGC; + } + else + { + block = yaffs_FindDirtiestBlock(dev); + } + if(block >= 0) { return yaffs_GarbageCollectBlock(dev,block); @@ -1755,9 +1899,9 @@ static int yaffs_ReadChunkTagsFromNAND(yaffs_Device *dev,int chunkInNAND, yaffs_ if(tags) { yaffs_Spare spare; - if(yaffs_ReadChunkFromNAND(dev,chunkInNAND,NULL,&spare) == YAFFS_OK) + if(yaffs_ReadChunkFromNAND(dev,chunkInNAND,NULL,&spare,1) == YAFFS_OK) { - *chunkDeleted = (yaffs_countBits[spare.pageStatus] < 7) ? 1 : 0; + *chunkDeleted = (yaffs_CountBits(spare.pageStatus) < 7) ? 1 : 0; yaffs_GetTagsFromSpare(&spare,tags); return YAFFS_OK; } @@ -2089,7 +2233,7 @@ int yaffs_ReadChunkDataFromObject(yaffs_Object *in,int chunkInInode, __u8 *buffe if(chunkInNAND >= 0) { - return yaffs_ReadChunkFromNAND(in->myDev,chunkInNAND,buffer,NULL); + return yaffs_ReadChunkFromNAND(in->myDev,chunkInNAND,buffer,NULL,1); } else { @@ -2101,16 +2245,21 @@ int yaffs_ReadChunkDataFromObject(yaffs_Object *in,int chunkInInode, __u8 *buffe static void yaffs_DeleteChunk(yaffs_Device *dev,int chunkId) { - int block = chunkId / YAFFS_CHUNKS_PER_BLOCK; - int page = chunkId % YAFFS_CHUNKS_PER_BLOCK; + int block; + int page; yaffs_Spare spare; + + if(chunkId <= 0) return; + block = chunkId / YAFFS_CHUNKS_PER_BLOCK; + page = chunkId % YAFFS_CHUNKS_PER_BLOCK; yaffs_SpareInitialise(&spare); spare.pageStatus = 0; // To mark it as deleted. yaffs_WriteChunkToNAND(dev,chunkId,NULL,&spare); + yaffs_HandleUpdateChunk(dev,chunkId,&spare); // Pull out of the management area. @@ -2250,7 +2399,7 @@ int yaffs_UpdateObjectHeader(yaffs_Object *in,const char *name) if(prevChunkId >= 0) { - yaffs_ReadChunkFromNAND(dev,prevChunkId,bufferOld,NULL); + yaffs_ReadChunkFromNAND(dev,prevChunkId,bufferOld,NULL,1); } // Header data @@ -2842,16 +2991,31 @@ static int yaffs_IsBlockBad(yaffs_Device *dev, int blk) { yaffs_Spare spare; - yaffs_ReadChunkFromNAND(dev,blk * YAFFS_CHUNKS_PER_BLOCK,NULL,&spare); + yaffs_ReadChunkFromNAND(dev,blk * YAFFS_CHUNKS_PER_BLOCK,NULL,&spare,1); +#if 1 + if(yaffs_CountBits(spare.blockStatus) < 7) + { + return 1; + } +#else if(spare.blockStatus != 0xFF) { return 1; } - yaffs_ReadChunkFromNAND(dev,blk * YAFFS_CHUNKS_PER_BLOCK + 1,NULL,&spare); +#endif + yaffs_ReadChunkFromNAND(dev,blk * YAFFS_CHUNKS_PER_BLOCK + 1,NULL,&spare,1); + +#if 1 + if(yaffs_CountBits(spare.blockStatus) < 7) + { + return 1; + } +#else if(spare.blockStatus != 0xFF) { return 1; } +#endif return 0; @@ -2902,13 +3066,13 @@ static int yaffs_Scan(yaffs_Device *dev) // Read the spare area and decide what to do chunk = blk * YAFFS_CHUNKS_PER_BLOCK + c; - yaffs_ReadChunkFromNAND(dev,chunk,NULL,&spare); + yaffs_ReadChunkFromNAND(dev,chunk,NULL,&spare,1); // This block looks ok, now what's in this chunk? yaffs_GetTagsFromSpare(&spare,&tags); - if(yaffs_countBits[spare.pageStatus] < 6) + if(yaffs_CountBits(spare.pageStatus) < 6) { // A deleted chunk deleted++; @@ -2963,7 +3127,7 @@ static int yaffs_Scan(yaffs_Device *dev) dev->blockInfo[blk].pageBits |= (1 << c); dev->blockInfo[blk].pagesInUse++; - yaffs_ReadChunkFromNAND(dev,chunk,chunkData,NULL); + yaffs_ReadChunkFromNAND(dev,chunk,chunkData,NULL,1); oh = (yaffs_ObjectHeader *)chunkData; @@ -3235,7 +3399,7 @@ int yaffs_GetObjectName(yaffs_Object *obj,char *name,int buffSize) if(obj->chunkId >= 0) { - yaffs_ReadChunkFromNAND(obj->myDev,obj->chunkId,buffer,NULL); + yaffs_ReadChunkFromNAND(obj->myDev,obj->chunkId,buffer,NULL,1); } strncpy(name,oh->name,buffSize - 1); } @@ -3411,7 +3575,6 @@ int yaffs_GutsInitialise(yaffs_Device *dev) int bits; - dev = dev; if(!yaffs_CheckStructures()) { @@ -3447,12 +3610,15 @@ int yaffs_GutsInitialise(yaffs_Device *dev) else { dev->chunkGroupBits = bits - 16; - dev->chunkGroupSize = nChunks/0x10000; + dev->chunkGroupSize = nChunks>> 16; } // More device initialisation dev->garbageCollectionRequired = 0; dev->currentDirtyChecker = 0; + dev->bufferedBlock = -1; + dev->doingBufferedBlockRewrite = 0; + dev->blockSelectedForGC = -1; yaffs_InitialiseBlocks(dev); @@ -3476,6 +3642,7 @@ int yaffs_GutsInitialise(yaffs_Device *dev) dev->nBlockErasures = 0; dev->nGCCopies = 0; dev->nRetriedWrites = 0; + dev->nRetiredBlocks = 0; return YAFFS_OK; diff --git a/yaffs_guts.h b/yaffs_guts.h index d37ac44..23aeefc 100644 --- a/yaffs_guts.h +++ b/yaffs_guts.h @@ -123,7 +123,7 @@ typedef enum { YAFFS_BLOCK_STATE_DIRTY, // All pages have been allocated and deleted. // Erase me, reuse me. - YAFFS_BLOCK_STATE_DEAD = 0x99 // This block has failed and is not in use + YAFFS_BLOCK_STATE_DEAD = 0x77 // This block has failed and is not in use } yaffs_BlockState; @@ -135,6 +135,8 @@ typedef struct __u32 pageBits; // bitmap of pages in use __u8 blockState; // One of the above block states __u8 pagesInUse; // number of pages in use + __u8 needsRetiring:1; // Data has failed on this block, need to get valid data off + // and retire the block. } yaffs_BlockInfo; @@ -386,14 +388,23 @@ struct yaffs_DeviceStruct int nBlockErasures; int nGCCopies; int nRetriedWrites; + int nRetiredBlocks; yaffs_Object *rootDir; yaffs_Object *lostNFoundDir; + // Buffer areas for storing data to recover from write failures + __u8 bufferedData[YAFFS_CHUNKS_PER_BLOCK][YAFFS_BYTES_PER_CHUNK]; + yaffs_Spare bufferedSpare[YAFFS_CHUNKS_PER_BLOCK]; + int bufferedBlock; // Which block is buffered here? + int doingBufferedBlockRewrite; + + int blockSelectedForGC; + }; - typedef struct yaffs_DeviceStruct yaffs_Device; +typedef struct yaffs_DeviceStruct yaffs_Device; diff --git a/yaffsdev b/yaffsdev index 4e083b0f7cfa448d6a10d70841ec5a5db6b81e12..551fec2a0d6716be1461e4a817d5cac6202fa002 100755 GIT binary patch delta 47042 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 WWE4n_r$b+pBk552=x`?Vx#TyxKtU=1 delta 42925 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 DR|;Lo delta 2207 zcmbVMZ){Ul6d%3sm6dg4j4^OfxU;~z(UsSB9aN3WSYaY#n_Ge5!1C62yFJ^zSKgnx zvUHmo)I?$!$7o_moPIMVOH4l)V$>KC6ZM09F&ILOL_T1mBKl3^pL^eHfw4i1X>RYm z=ltIJ{qDKv+}U}@?7ZXbqbqKF@R%RFF1io7FS;AtuM|(>_3m0-HMJyB#9W(zgF-}r z^ZwA5h#=sQ5W(U0Aa0LF**r<-9qrMM9l=O@@kf8N_mQY`yYnypCjT>koxjFk;-`6o z*Z4I5Id_3u;NIotxjF86F3Tz0G45&ZAlJ(|Dk~}+bS^$QpgUl6Xd}!FcEDSMo=rl< zsA`P+=^&ck_M9dg-ik4ajnOvvc(9+27L*rLbk2Y>=-dz&$8ZuV>@Ou3aNOsk0}o|I>ggYSmL!cQaKb{zNQM~Xh^nQDhACM} zPb{Xfb~b9CoFRBXGZls}EvOz{K1HyhO6nGzQcXp|hSK(UhU7>_z(?q*NK7pFNLv5ryH?2{EcSNj#J9nKyNbIb(2#{$(orlIdwWJ4A+vd&yJ zi!1~v6Wlz;!_|DHGp_b^^~IPnxSX$c#8sG1JVYrfd08|J4TO=M<<+pq8H*pHegS_Pn=-lYVWaG@~RG|6}5z9p?GW0 zLb$EfP=2CUR?0wt0QBnz~BCE38t0k=p~qarF& zf>!h$SJ?uedOdK!w+6mSABGdHmGEmbx3bqNz&Ok`H(7O1+S7!=H5tRgb{B8;1DqUR zUu74*z3)sv+!ZIf5tk=OsqWRJsp~{qR^ReacwY87?XO|JrO9=>fh_WQ+2yqR#&X(A zR-sH8bC$mRTk=-fORGU)R`zZ!^F2sRIgWe4G_1E`zhbD2YW3ZQGGT415-NT5@R7GE zY~pf!QD?sgu@D==jtYNn8-Xult6;X*4Nu7)*mb;t*{g2%KW!PxUvt;KM87$O^I26h zh>{D8moNQ}1wQj`f`JsjZc$NK_eCxA=AVJ%TcgmQS_z+Q^A`)5myz>|o~1N!a|q!F_M#$ z)Udn)e478`1R)sg z2ngXIUJe-y?OH;+TvXp!uBCu=B|*~!jg1Yk(Ce!09v77{Vn1p0L1Woi>j{PgN*82w zMmYsGgr)!%bkEjcC>&fudQU8R&bHP6H+*RKe+ch~)6xdmexS}DY7d3(r?`Nr_pS