*** empty log message ***
authorcharles <charles>
Thu, 3 Apr 2003 17:32:11 +0000 (17:32 +0000)
committercharles <charles>
Thu, 3 Apr 2003 17:32:11 +0000 (17:32 +0000)
direct/dtest.c
yaffs_guts.c

index de1eaa2d66fb7776ca60bcf2e1220b6c799b0a38..6f32cb53d81ac028a86c20f00f08ae4df32de1db 100644 (file)
@@ -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();
        
 }
index dfef9def4c17a10e89afb2e304f93993baf5d068..d7246590925400795b7831e3e74fe9d4fac54c8e 100644 (file)
@@ -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);