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);
+
+}
+
}
+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();
}
*/
//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"
cache->nBytes,1);
cache->dirty = 0;
+ cache->object = NULL;
}
} while(cache && chunkWritten > 0);
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
}
//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
yaffs_Object *theObj;
int usage;
int i;
+ int pushout;
if(dev->nShortOpCaches > 0)
{
theObj = dev->srCache[0].object;
usage = dev->srCache[0].lastUse;
+ cache = &dev->srCache[0];
+ pushout = 0;
for(i = 1; i < dev->nShortOpCaches; i++)
{
{
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
int nToCopy;
int n = nBytes;
int nDone = 0;
+ yaffs_ChunkCache *cache;
yaffs_Device *dev;
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);