From f312fc5a4e1e46509129caf3d7fd2edafc743d15 Mon Sep 17 00:00:00 2001 From: charles Date: Thu, 3 Apr 2003 17:32:11 +0000 Subject: [PATCH] *** empty log message *** --- direct/dtest.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++- yaffs_guts.c | 46 +++++++++++++++++---- 2 files changed, 146 insertions(+), 10 deletions(-) diff --git a/direct/dtest.c b/direct/dtest.c index de1eaa2..6f32cb5 100644 --- a/direct/dtest.c +++ b/direct/dtest.c @@ -32,6 +32,30 @@ void copy_in_a_file(char *yaffsName,char *inName) close(inh); } +void make_a_file(char *yaffsName,char bval,int sizeOfFile) +{ + int outh; + int i; + unsigned char buffer[100]; + + outh = yaffs_open(yaffsName, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE); + + memset(buffer,bval,100); + + do{ + i = sizeOfFile; + if(i > 100) i = 100; + sizeOfFile -= i; + + yaffs_write(outh,buffer,i); + + } while (sizeOfFile > 0); + + + yaffs_close(outh); + +} + @@ -555,10 +579,94 @@ int directory_rename_test(void) } +int cache_read_test(void) +{ + int a,b,c; + int i; + int sizeOfFiles = 500000; + char buffer[100]; + + yaffs_StartUp(); + + yaffs_mount("/boot"); + + make_a_file("/boot/a",'a',sizeOfFiles); + make_a_file("/boot/b",'b',sizeOfFiles); + + a = yaffs_open("/boot/a",O_RDONLY,0); + b = yaffs_open("/boot/b",O_RDONLY,0); + c = yaffs_open("/boot/c", O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE); + + do{ + i = sizeOfFiles; + if (i > 100) i = 100; + sizeOfFiles -= i; + yaffs_read(a,buffer,i); + yaffs_read(b,buffer,i); + yaffs_write(c,buffer,i); + } while(sizeOfFiles > 0); + + + + return 1; + +} + +int cache_bypass_bug_test(void) +{ + // This test reporoduces a bug whereby YAFFS caching is buypassed + // resulting in erroneous reads after writes. + int a; + int i; + char buffer1[1000]; + char buffer2[1000]; + + memset(buffer1,0,sizeof(buffer1)); + memset(buffer2,0,sizeof(buffer2)); + + yaffs_StartUp(); + + yaffs_mount("/boot"); + + // Create a file of 2000 bytes. + make_a_file("/boot/a",'X',2000); + + a = yaffs_open("/boot/a",O_RDWR, S_IREAD | S_IWRITE); + + // Write a short sequence to the file. + // This will go into the cache. + yaffs_lseek(a,0,SEEK_SET); + yaffs_write(a,"abcdefghijklmnopqrstuvwxyz",20); + + // Read a short sequence from the file. + // This will come from the cache. + yaffs_lseek(a,0,SEEK_SET); + yaffs_read(a,buffer1,30); + + // Read a page size sequence from the file. + yaffs_lseek(a,0,SEEK_SET); + yaffs_read(a,buffer2,512); + + printf("buffer 1 %s\n",buffer1); + printf("buffer 2 %s\n",buffer2); + + if(strncmp(buffer1,buffer2,20)) + { + printf("Cache bypass bug detected!!!!!\n"); + } + + + return 1; +} + + + int main(int argc, char *argv[]) { //return long_test(argc,argv); - return directory_rename_test(); + //return cache_read_test(); + + return cache_bypass_bug_test(); } diff --git a/yaffs_guts.c b/yaffs_guts.c index dfef9de..d724659 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.22 2003-03-11 05:16:53 charles Exp $"; +const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.23 2003-04-03 17:32:11 charles Exp $"; #include "yportenv.h" @@ -3128,6 +3128,7 @@ static void yaffs_FlushFilesChunkCache(yaffs_Object *obj) cache->nBytes,1); cache->dirty = 0; + cache->object = NULL; } } while(cache && chunkWritten > 0); @@ -3160,10 +3161,14 @@ static yaffs_ChunkCache *yaffs_GrabChunkCacheWorker(yaffs_Device *dev) if(!dev->srCache[i].object) { //T(("Grabbing empty %d\n",i)); + + printf("Grabbing empty %d\n",i); return &dev->srCache[i]; } } + + return NULL; theOne = -1; usage = 0; // just to stop the compiler grizzling @@ -3180,6 +3185,9 @@ static yaffs_ChunkCache *yaffs_GrabChunkCacheWorker(yaffs_Device *dev) } //T(("Grabbing non-empty %d\n",theOne)); + + if(theOne >= 0) printf("Grabbed non-empty cache %d\n",theOne); + return theOne >= 0 ? &dev->srCache[theOne] : NULL; } else @@ -3196,6 +3204,7 @@ static yaffs_ChunkCache *yaffs_GrabChunkCache(yaffs_Device *dev) yaffs_Object *theObj; int usage; int i; + int pushout; if(dev->nShortOpCaches > 0) { @@ -3212,6 +3221,8 @@ static yaffs_ChunkCache *yaffs_GrabChunkCache(yaffs_Device *dev) theObj = dev->srCache[0].object; usage = dev->srCache[0].lastUse; + cache = &dev->srCache[0]; + pushout = 0; for(i = 1; i < dev->nShortOpCaches; i++) { @@ -3220,15 +3231,27 @@ static yaffs_ChunkCache *yaffs_GrabChunkCache(yaffs_Device *dev) { usage = dev->srCache[i].lastUse; theObj = dev->srCache[i].object; + cache = &dev->srCache[i]; + pushout = i; } } - yaffs_FlushFilesChunkCache(theObj); + if(!cache || cache->dirty) + { + + printf("Dirty "); + yaffs_FlushFilesChunkCache(theObj); - // Try again - cache = yaffs_GrabChunkCacheWorker(dev); + // Try again + cache = yaffs_GrabChunkCacheWorker(dev); + } + else + { + printf(" pushout %d\n",pushout); + } + } - + return cache; } else @@ -3346,6 +3369,7 @@ int yaffs_ReadDataFromFile(yaffs_Object *in, __u8 * buffer, __u32 offset, int nB int nToCopy; int n = nBytes; int nDone = 0; + yaffs_ChunkCache *cache; yaffs_Device *dev; @@ -3367,14 +3391,18 @@ int yaffs_ReadDataFromFile(yaffs_Object *in, __u8 * buffer, __u32 offset, int nB nToCopy = YAFFS_BYTES_PER_CHUNK - start; } - if(nToCopy != YAFFS_BYTES_PER_CHUNK) + cache = yaffs_FindChunkCache(in,chunk); + + // If the chunk is already in the cache or it is less than a whole chunk + // then use the cache (if there is caching) + // else bypass the cache. + if( cache || nToCopy != YAFFS_BYTES_PER_CHUNK) { - // An incomplete start or end chunk (or maybe both start and end chunk) if(dev->nShortOpCaches > 0) { - yaffs_ChunkCache *cache; + // If we can't find the data in the cache, then load it up. - cache = yaffs_FindChunkCache(in,chunk); + if(!cache) { cache = yaffs_GrabChunkCache(in->myDev); -- 2.30.2