From: charles Date: Wed, 2 Oct 2002 02:11:25 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs%2F.git;a=commitdiff_plain;h=0c0639ff1c8a2d8fe5b03ad0284bb400ec78e7cb *** empty log message *** --- diff --git a/Makefile b/Makefile index fa4c171..0b6083c 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,9 @@ # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as # published by the Free Software Foundation. +# +# $Id: Makefile,v 1.6 2002-10-02 02:11:25 charles Exp $ +# ## Change or override KERNELDIR to your kernel ## comment out USE_xxxx if you don't want these features. diff --git a/snMakefile b/snMakefile index 0b9fbb9..c2007a2 100644 --- a/snMakefile +++ b/snMakefile @@ -1,6 +1,6 @@ ######################################################### # Makefile auto generated by Cygnus Source Navigator. -# Target: yaffsdev_disk Date: Sep 27 2002 Time: 09:05:11 AM +# Target: yaffsdev_disk Date: Oct 01 2002 Time: 07:41:55 AM # diff --git a/utils/mkyaffs b/utils/mkyaffs index 94a7df3..644ea3b 100755 Binary files a/utils/mkyaffs and b/utils/mkyaffs differ diff --git a/utils/mkyaffs.c b/utils/mkyaffs.c index 91a3c9d..53055b3 100644 --- a/utils/mkyaffs.c +++ b/utils/mkyaffs.c @@ -34,7 +34,7 @@ #include #include -cost char *mkyaffs_c_version = "$Id: mkyaffs.c,v 1.3 2002-09-27 20:50:50 charles Exp $"; +const char *mkyaffs_c_version = "$Id: mkyaffs.c,v 1.4 2002-10-02 02:11:25 charles Exp $"; // 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. diff --git a/yaffs_fs.c b/yaffs_fs.c index b693305..9be8428 100644 --- a/yaffs_fs.c +++ b/yaffs_fs.c @@ -27,7 +27,8 @@ */ -const char *yaffs_fs_c_version = "$Id: yaffs_fs.c,v 1.16 2002-09-27 20:50:50 charles Exp $"; +const char *yaffs_fs_c_version = "$Id: yaffs_fs.c,v 1.17 2002-10-02 02:11:25 charles Exp $"; +extern const char *yaffs_guts_c_version; #include #include @@ -932,6 +933,9 @@ static int yaffs_rename(struct inode * old_dir, struct dentry *old_dentry, struc yaffs_GrossLock(dev); + // Unlink the target if it exists + yaffs_Unlink(yaffs_InodeToObject(new_dir),new_dentry->d_name.name); + retVal = yaffs_RenameObject(yaffs_InodeToObject(old_dir),old_dentry->d_name.name, yaffs_InodeToObject(new_dir),new_dentry->d_name.name); @@ -1306,14 +1310,14 @@ static int yaffs_proc_read( ) { - char my_buffer[2000]; + char my_buffer[3000]; char *buf; buf = my_buffer; if (offset > 0) return 0; /* Fill the buffer and get its length */ - buf +=sprintf(buf,"YAFFS built:"__DATE__ " "__TIME__"\n"); + buf +=sprintf(buf,"YAFFS built:"__DATE__ " "__TIME__"\n%s\n%s\n", yaffs_fs_c_version,yaffs_guts_c_version); if(yaffs_dev) buf = yaffs_dump_dev(buf,yaffs_dev,"yaffs"); if(yaffsram_dev) buf = yaffs_dump_dev(buf,yaffsram_dev,"yaffsram"); diff --git a/yaffs_guts.c b/yaffs_guts.c index bfe10b7..975d7c0 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.10 2002-09-27 20:50:50 charles Exp $"; +const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.11 2002-10-02 02:11:25 charles Exp $"; #include "yportenv.h" @@ -109,12 +109,8 @@ static int yaffs_CheckFileSanity(yaffs_Object *in); #define yaffs_CheckFileSanity(in) #endif -#ifdef CONFIG_YAFFS_SHORT_OP_CACHE -static void yaffs_InvalidateChunkCache(yaffs_Object *in); -#define yaffs_INVALIDATECHUNKCACHE(in) yaffs_InvalidateChunkCache(in) -#else -#define yaffs_INVALIDATECHUNKCACHE(in) -#endif +static void yaffs_InvalidateWholeChunkCache(yaffs_Object *in); +static void yaffs_InvalidateChunkCache(yaffs_Device *dev, int objectId, int chunkId); static __inline__ yaffs_BlockInfo* yaffs_GetBlockInfo(yaffs_Device *dev, int blk) @@ -1542,7 +1538,7 @@ yaffs_Object *yaffs_Link(yaffs_Object *parent, const char *name, yaffs_Object *e } -static int yaffs_ChangeObjectName(yaffs_Object *obj, yaffs_Object *newDir, const char *newName) +static int yaffs_ChangeObjectName(yaffs_Object *obj, yaffs_Object *newDir, const char *newName,int force) { int unlinkOp; @@ -1556,9 +1552,10 @@ static int yaffs_ChangeObjectName(yaffs_Object *obj, yaffs_Object *newDir, const // If the object is a file going into the unlinked directory, then it is OK to just stuff it in since // duplicate names are allowed. // Otherwise only proceed if the new name does not exist and if we're putting it into a directory. - if( unlinkOp|| - (!yaffs_FindObjectByName(newDir,newName) && - newDir->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)) + if( (unlinkOp|| + force || + !yaffs_FindObjectByName(newDir,newName)) && + newDir->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) { obj->sum = yaffs_CalcNameSum(newName); obj->dirty = 1; @@ -1580,11 +1577,22 @@ static int yaffs_ChangeObjectName(yaffs_Object *obj, yaffs_Object *newDir, const int yaffs_RenameObject(yaffs_Object *oldDir, const char *oldName, yaffs_Object *newDir, const char *newName) { yaffs_Object *obj; + int force = 0; + +#if WIN32 + // Special case for WinCE. + // While look-up is case insensitive, the name isn't. + // THerefore we might want to change x.txt to X.txt + if(oldDir == newDir && stricmp(oldName,newName) == 0) + { + force = 1; + } +#endif obj = yaffs_FindObjectByName(oldDir,oldName); if(obj && obj->renameAllowed) { - return yaffs_ChangeObjectName(obj,newDir,newName); + return yaffs_ChangeObjectName(obj,newDir,newName,force); } return YAFFS_FAIL; } @@ -1962,9 +1970,19 @@ static void yaffs_DoUnlinkedFileDeletion(yaffs_Device *dev) if(dev->unlinkedDeletion) { yaffs_Object *obj = dev->unlinkedDeletion; - int limit; int delresult; - limit = 50; // Max number of chunks to delete in a file. NB this can be exceeded, but not by much. + int limit; // Number of chunks to delete in a file. + // NB this can be exceeded, but not by much. + + if(dev->nErasedBlocks <= (YAFFS_RESERVED_BLOCKS + YAFFS_GARBAGE_COLLECT_LOW_WATER)) + { + limit = 50; // Doing GC soon, so dig deeper + } + else + { + limit = 5; + } + delresult = yaffs_DeleteWorker(obj, obj->variant.fileVariant.top, obj->variant.fileVariant.topLevel, 0,&limit); if(obj->nDataChunks == 0) @@ -2563,7 +2581,7 @@ int yaffs_UpdateObjectHeader(yaffs_Object *in,const char *name, int force) yaffs_ObjectHeader *oh = (yaffs_ObjectHeader *)bufferNew; yaffs_ObjectHeader *ohOld = (yaffs_ObjectHeader *)bufferOld; - yaffs_INVALIDATECHUNKCACHE(in); + yaffs_InvalidateWholeChunkCache(in); if(!in->fake || force) { @@ -2705,23 +2723,6 @@ int yaffs_UpdateObjectHeader(yaffs_Object *in,const char *name, int force) #ifdef CONFIG_YAFFS_SHORT_OP_CACHE -// Invalidate all the cache pages associated with this object -// Do this whenever ther file is modified... dumb as a rock remember! -static void yaffs_InvalidateChunkCache(yaffs_Object *in) -{ - int i; - yaffs_Device *dev = in->myDev; - int id = in->objectId; - - for(i = 0; i < YAFFS_N_CACHE_CHUNKS; i++) - { - if(dev->srCache[i].objectId == id) - { - dev->srCache[i].objectId = 0; - } - } -} - // Grab us a chunk for use. // First look for an empty one. @@ -2802,6 +2803,61 @@ static void yaffs_UseChunkCache(yaffs_Device *dev, yaffs_ChunkCache *cache) } +// Invalidate a single cache page +static void yaffs_InvalidateChunkCache(yaffs_Device *dev, int objectId, int chunkId) +{ + yaffs_ChunkCache *cache = yaffs_FindChunkCache(dev,objectId,chunkId); + + if(cache) + { + cache->objectId = 0; + } +} + + +// Invalidate all the cache pages associated with this object +// Do this whenever ther file is modified... dumb as a rock remember! +static void yaffs_InvalidateWholeChunkCache(yaffs_Object *in) +{ + int i; + yaffs_Device *dev = in->myDev; + int id = in->objectId; + + for(i = 0; i < YAFFS_N_CACHE_CHUNKS; i++) + { + if(dev->srCache[i].objectId == id) + { + dev->srCache[i].objectId = 0; + } + } +} + + +#else + +static yaffs_ChunkCache *yaffs_GrabChunkCache(yaffs_Device *dev) +{ + return NULL; +} + + +static yaffs_ChunkCache *yaffs_FindChunkCache(yaffs_Device *dev, int objectId, int chunkId) +{ + return NULL; +} + +static void yaffs_UseChunkCache(yaffs_Device *dev, yaffs_ChunkCache *cache) +{ +} + +static void yaffs_InvalidateChunkCache(yaffs_Device *dev, int objectId, int chunkId) +{ +} + +static void yaffs_InvalidateWholeChunkCache(yaffs_Object *in) +{ +} + #endif @@ -2828,6 +2884,7 @@ int yaffs_ReadDataFromFile(yaffs_Object *in, __u8 * buffer, __u32 offset, int nB __u8 localBuffer[YAFFS_BYTES_PER_CHUNK]; + int chunk; int start; int nToCopy; @@ -2909,8 +2966,10 @@ int yaffs_WriteDataToFile(yaffs_Object *in,const __u8 * buffer, __u32 offset, in int nToWriteBack; int endOfWrite = offset+nBytes; int chunkWritten = 0; + int nBytesRead; + + yaffs_InvalidateWholeChunkCache(in); - yaffs_INVALIDATECHUNKCACHE(in); while(n > 0 && chunkWritten >= 0) { @@ -2920,10 +2979,23 @@ int yaffs_WriteDataToFile(yaffs_Object *in,const __u8 * buffer, __u32 offset, in // OK now check for the curveball where the start and end are in // the same chunk. + if( (start + n) < YAFFS_BYTES_PER_CHUNK) { nToCopy = n; - nToWriteBack = (start + n); + + // Now folks, to calculate how many bytes to write back.... + // If we're overwriting and not writing to then end of file then + // we need to write back as much as was there before. + + nBytesRead = in->variant.fileVariant.fileSize - ((chunk -1) * YAFFS_BYTES_PER_CHUNK); + + if(nBytesRead > YAFFS_BYTES_PER_CHUNK) + { + nBytesRead = YAFFS_BYTES_PER_CHUNK; + } + nToWriteBack = (nBytesRead > (start + n)) ? nBytesRead : (start +n); + } else { @@ -2942,7 +3014,7 @@ int yaffs_WriteDataToFile(yaffs_Object *in,const __u8 * buffer, __u32 offset, in chunkWritten = yaffs_WriteChunkDataToObject(in,chunk,localBuffer,nToWriteBack,0); - //T(("Write with readback to chunk %d %d\n",chunk,chunkWritten)); + //T(("Write with readback to chunk %d %d start %d copied %d wrote back %d\n",chunk,chunkWritten,start, nToCopy, nToWriteBack)); } else @@ -2957,6 +3029,8 @@ int yaffs_WriteDataToFile(yaffs_Object *in,const __u8 * buffer, __u32 offset, in // A full chunk. Write directly from the supplied buffer. chunkWritten = yaffs_WriteChunkDataToObject(in,chunk,buffer,YAFFS_BYTES_PER_CHUNK,0); #endif + // Since we've overwritten the cached data, we better invalidate it. + yaffs_InvalidateChunkCache(in->myDev,in->objectId,chunk); //T(("Write to chunk %d %d\n",chunk,chunkWritten)); } @@ -2995,7 +3069,7 @@ int yaffs_ResizeFile(yaffs_Object *in, int newSize) __u8 localBuffer[YAFFS_BYTES_PER_CHUNK]; - yaffs_INVALIDATECHUNKCACHE(in); + yaffs_InvalidateWholeChunkCache(in); if(in->variantType != YAFFS_OBJECT_TYPE_FILE) { @@ -3099,7 +3173,7 @@ int yaffs_FlushFile(yaffs_Object *in) static int yaffs_DoGenericObjectDeletion(yaffs_Object *in) { - yaffs_INVALIDATECHUNKCACHE(in); + yaffs_InvalidateWholeChunkCache(in); yaffs_RemoveObjectFromDirectory(in); yaffs_DeleteChunk(in->myDev,in->chunkId); #if __KERNEL__ @@ -3135,7 +3209,7 @@ static int yaffs_UnlinkFile(yaffs_Object *in) #else int retVal; int immediateDeletion=0; - retVal = yaffs_ChangeObjectName(in, in->myDev->unlinkedDir,NULL); + retVal = yaffs_ChangeObjectName(in, in->myDev->unlinkedDir,NULL,0); if(retVal == YAFFS_OK) { //in->unlinked = 1; @@ -3331,7 +3405,7 @@ static int yaffs_UnlinkWorker(yaffs_Object *obj) yaffs_GetObjectName(hl,name,YAFFS_MAX_NAME_LENGTH+1); - retVal = yaffs_ChangeObjectName(obj, hl->parent, name); + retVal = yaffs_ChangeObjectName(obj, hl->parent, name,0); if(retVal == YAFFS_OK) { diff --git a/yaffsdev.c b/yaffsdev.c index 3fb6a62..ba1353f 100644 --- a/yaffsdev.c +++ b/yaffsdev.c @@ -313,14 +313,17 @@ void TestTime(yaffs_Device *dev) x = yaffs_RenameObject(yaffs_Root(dev),"Name1",NULL,"Rename"); - for(i = 0; i < 100000; i+=20) + for(i = 0; i < 100000; i+=64) { b++; if(b & 1) - written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr)); + written = yaffs_WriteDataToFile(f,testStr,i,64); else - written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2)); + written = yaffs_WriteDataToFile(f,testStr2,i,64); + + written = yaffs_WriteDataToFile(f,testStr2,1,20); + } // some short reads for(i = 1000; i < 50000; i+=2) @@ -587,7 +590,7 @@ int main(int argc,char *argv[]) int nBlocks; #if YAFFS_FILEEM - nBlocks =(32 * 1024 * 1024) / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK) ; + nBlocks =(4 * 1024 * 1024) / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK) ; device.writeChunkToNAND = yaffs_FEWriteChunkToNAND; device.readChunkFromNAND = yaffs_FEReadChunkFromNAND; device.eraseBlockInNAND = yaffs_FEEraseBlockInNAND; @@ -616,7 +619,7 @@ int main(int argc,char *argv[]) // yaffs_GutsTest(); - TestTimeBigDeletes(&device); + TestTime(&device); printf("Cache hits %d\n",device.cacheHits); printf("Retired blocks %d\n",device.nRetiredBlocks); diff --git a/yaffsdev.proj b/yaffsdev.proj index 5a97bb6..16a6a7d 100644 Binary files a/yaffsdev.proj and b/yaffsdev.proj differ