changeset 55:25be3895c62a

The filesystem now supports a much better cache system Added memcpy to the standard library readFSBlock now returns a pointer to the location of a file in memory (it loads the file to a location in the cache). init_fs now takes two arguments, a devid and the current memory size, it allocates 1% of the memory for the cache. All functions have been modified to use this idea of reading files. TODO make looking for a file in the cache more efficient
author Jonathan Pevarnek <pevarnj@gmail.com>
date Sat, 09 Apr 2011 23:48:32 -0400
parents 39fcefab46ed
children 8fef616405c0
files include/fs.h include/std.h src/dynamic.c src/fs.c src/sarpn.c src/std.c src/testFS.c
diffstat 7 files changed, 102 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/include/fs.h	Sat Apr 09 21:55:59 2011 -0400
+++ b/include/fs.h	Sat Apr 09 23:48:32 2011 -0400
@@ -21,13 +21,23 @@
 };
 typedef struct INODE Inode;
 
+struct FSBLK {
+	u8 blocks[1024];
+};
+typedef struct FSBLK FSBlk;
+
+struct DSKBLK {
+	u8 blocks[512];
+};
+typedef struct DSKBLK DskBlk;
+
 struct DIRENTRY { //32 bytes
 	char fname[28];
 	u32 inode;
 };
 typedef struct DIRENTRY Direntry;
 
-int init_fs(u32 devnum);
+int init_fs(u32 devnum, u64 __memsize);
 void listFiles();
 u32 lookupFile(char *fname);
 int getFSize(u32 fid, u32 *size);
--- a/include/std.h	Sat Apr 09 21:55:59 2011 -0400
+++ b/include/std.h	Sat Apr 09 23:48:32 2011 -0400
@@ -24,6 +24,8 @@
 
 char* append(char *dest, char *src);
 
+void* memcpy(void *destination, const void *source, size_t num);
+
 //MALLOC CODE
 
 struct header{
--- a/src/dynamic.c	Sat Apr 09 21:55:59 2011 -0400
+++ b/src/dynamic.c	Sat Apr 09 23:48:32 2011 -0400
@@ -21,9 +21,7 @@
 
 void start(u64 __memsize)
 {
-	init_io_int();
-	init_console();
-	malloc_init(__memsize - HEAP_START);
+	init_all(__memsize);
 	size_t n;
 	char *buffer;
 	char input[30];
--- a/src/fs.c	Sat Apr 09 21:55:59 2011 -0400
+++ b/src/fs.c	Sat Apr 09 23:48:32 2011 -0400
@@ -1,29 +1,44 @@
 #include <fs.h>
 #include <std.h>
 
-static int loadToCache(u32 fid);
-static int readFSBlock(u32 dev, u32 blkno, void *fsBlock);
+static u32 getCacheLoc(u32 blkno);
+static void* readFSBlock(u32 blkno);
 
 static u32 DevID;
 static Direntry *Direntries = NULL;
 static int NFiles;
 
-static u32 CacheID = 0;
-static Inode Cached;
+static u32 CacheCap; //how many blocks the cache can hold
+static u32 CacheSize; //the current number of elts in the cache
+static FSBlk *FS_Cache = NULL; //A pointer to the actual cache
+static u32 *CacheLocs; //what location each block points to
+static u32 CacheNext; //the next location to toss a cached block into
 
-int init_fs(u32 devnum)
+int init_fs(u32 devnum, u64 __memsize)
 {
+	//Create the cache
+	CacheCap = (__memsize/100)/1024;
+	FS_Cache = malloc(CacheCap*1024);
+	CacheLocs = malloc(CacheCap);
+	CacheSize = 0;
+	CacheNext = 0;
+
 	DevID = find_dev(0x100);
-	Superblock sb; //the superblock
-	if(readFSBlock(DevID, 1, &sb)) return -1;
-	Inode rootINode;
-	if(readFSBlock(DevID, sb.root_inode, &rootINode)) return -1;
-	NFiles = rootINode.size/sizeof(Direntry);
-	Direntries = malloc(rootINode.size);
-	if(getFData(sb.root_inode, Direntries)) return -1;
+	Superblock *sb;
+	sb = readFSBlock(1);
+	if(!sb) return -1;
+	Inode *rootINode;
+	u32 rootLoc = sb->root_inode;
+	rootINode = readFSBlock(rootLoc);
+	if(!rootINode) return -1;
+	NFiles = rootINode->size/sizeof(Direntry);
+	Direntries = malloc(rootINode->size); //get array of the files
+	if(getFData(rootLoc, Direntries)) return -1;
+
 	return 0;
 }
 
+//this lists all the files
 void listFiles()
 {
 	Direntry *dp;
@@ -31,6 +46,7 @@
 		printFname(dp->fname), putline("\n", 1);
 }
 
+//This returns the "file ID" of a specific file
 u32 lookupFile(char *fname)
 {
 	Direntry *dp;
@@ -46,8 +62,10 @@
 //This sets *size equal to the size of the file.  Will return 0 an success
 int getFSize(u32 fid, u32 *size)
 {
-	if(loadToCache(fid)) return -1;
-	*size = Cached.size;
+	Inode *ptr;
+	ptr = readFSBlock(fid);
+	if(!ptr) return -1;
+	*size = ptr->size;
 	return 0;
 }
 
@@ -55,24 +73,23 @@
 int getFData(u32 fid, void *ptr)
 {
 	int i;
-	loadToCache(fid);
-	u32 size = Cached.size;
-	u16 nBlocks = Cached.nblocks;
+	Inode *temp = readFSBlock(fid);
+	if(!temp) return -1;
+	Inode *inPtr = malloc(sizeof(Inode));
+	memcpy(inPtr, temp, sizeof(Inode));
+	//I need a copy so I know the block locations are not overwritten later
+
+	u32 size = inPtr->size;
+	u16 nBlocks = inPtr->nblocks;
 	for(i = 0; i < nBlocks; i++) {
-		if(size >= 1024) {
-			if(readFSBlock(DevID, Cached.blocks[i], ptr)) return -1;
-			ptr += 1024;
-			size -= 1024;
-		} else {
-			u8 *point = ptr;
-			u8 buffer[1024];
-			if(readFSBlock(DevID, Cached.blocks[i], buffer)) return -1;
-			for(i = 0; i < size; i++, point++) {
-				*point = buffer[i];
-			}
-			break; //it should do this anyways but...
-		}
+		Inode *filePtr;
+		filePtr = readFSBlock(inPtr->blocks[i]);
+		if(!filePtr) return -1;
+		memcpy(ptr, filePtr, ((size > 1024)?1024:size));
+		ptr += 1024;
+		size -= 1024;
 	}
+	free(inPtr);
 	return 0;
 }
 
@@ -81,9 +98,10 @@
 	u32 inBlock = block/0x2000 + 2; //which block the bit is in
 	u32 blockSpot = (block%0x2000)/8; //which u8 the bit is in
 	u32 spotSpot = 7 - block%8; //which bit the bit is
-	u8 buffer[1024];
-	if(readFSBlock(DevID, inBlock, buffer)) return -1; //TODO should this be optimized and only read one block?
-	return (buffer[blockSpot] >> spotSpot) & 1;
+	u8 *ptr;
+	ptr = readFSBlock(inBlock);
+	if(!ptr) return -1;
+	return (ptr[blockSpot] >> spotSpot) & 1;
 }
 
 void printFname(char *name)
@@ -111,20 +129,31 @@
 	return 0;
 }
 
-static int loadToCache(u32 fid)
+static u32 getCacheLoc(u32 blkno)
 {
-	if(CacheID == fid) return 0;
-	if(readFSBlock(DevID, fid, &Cached)) return -1;
-	CacheID = fid;
-	return 0;
+	int i;
+	for(i = 0; i < CacheSize; i++) {
+		if(CacheLocs[i] == blkno) return i;
+	}
+	return CacheCap;
 }
 
 //REQUIRES:   fsBlock points to an object with size at least 1024
 //EFFECTS:    Sets fsBlock to be equal
-static int readFSBlock(u32 dev, u32 blkno, void *fsBlock)
+static void* readFSBlock(u32 blkno)
 {
-	//assert(isBlockAt(blkno)); //DO NOT UNCOMMENT
-	if(fba_read_blk(dev, blkno*2, fsBlock)) return 1;
-	if(fba_read_blk(dev, blkno*2 + 1, fsBlock + 512)) return 1;
-	return 0;
+	u32 cacheLoc = getCacheLoc(blkno); //Do not reload if in cache
+	if(cacheLoc == CacheCap) { //It was not found in the cache
+		cacheLoc = CacheNext; //CacheNext is the next place a value should be placed
+		FSBlk *nextFSB = FS_Cache + CacheNext;
+		DskBlk *nextDSKB = (DskBlk *) nextFSB; //block to put data in
+		if(fba_read_blk(DevID, blkno*2, nextDSKB)) return NULL;
+		if(fba_read_blk(DevID, blkno*2 + 1, nextDSKB + 1)) return NULL;
+
+		CacheLocs[cacheLoc] = blkno;
+		if(CacheSize != CacheCap) CacheSize += 1;
+		if(CacheNext != CacheCap - 1) CacheNext += 1;
+		else CacheNext = 0;
+	}
+	return (void *)(FS_Cache + cacheLoc);
 }
--- a/src/sarpn.c	Sat Apr 09 21:55:59 2011 -0400
+++ b/src/sarpn.c	Sat Apr 09 23:48:32 2011 -0400
@@ -8,9 +8,7 @@
 
 void start(u64 __memsize)
 {
-	init_io_int();
-	init_console();
-	malloc_init(__memsize - HEAP_START);
+	init_all(__memsize);
 
 	Stack *stack = stack_init();
 	while(1) {
--- a/src/std.c	Sat Apr 09 21:55:59 2011 -0400
+++ b/src/std.c	Sat Apr 09 23:48:32 2011 -0400
@@ -161,6 +161,20 @@
 	return ret;
 }
 
+void* memcpy(void *destination, const void *source, size_t num)
+{
+	int i;
+	const u8 *from = source;
+	u8 *to = destination;
+	for(i = 0; i < num; i++)
+		to[i] = from[i];
+	return destination;
+}
+
+
+
+//DYNAMIC MEMORY
+
 static Header base;
 static Header *allocp = NULL; //the location of the last known free block
 
--- a/src/testFS.c	Sat Apr 09 21:55:59 2011 -0400
+++ b/src/testFS.c	Sat Apr 09 23:48:32 2011 -0400
@@ -14,7 +14,7 @@
 {
 	init_all(__memsize);
 	char buffer[256];
-	if(init_fs(0x100)) goto END;
+	if(init_fs(0x100, __memsize)) goto END;
 
 	while(1) {
 		//Prints off the name of each file