changeset 51:eda059d74100

Started to librarize (is that a word) the filesystem
author Jonathan Pevarnek <pevarnj@gmail.com>
date Fri, 08 Apr 2011 13:41:58 -0400
parents eda962110e0e
children 2de1c2597a60
files Makefile include/fs.h src/fs.c src/testFS.c
diffstat 4 files changed, 182 insertions(+), 122 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Fri Apr 08 10:33:40 2011 -0400
+++ b/Makefile	Fri Apr 08 13:41:58 2011 -0400
@@ -13,9 +13,9 @@
 
 BINS=sarpn dynamic testFS
 
-sarpn_OBJS=src/sarpn.o arch/arch.a src/std.o src/stack.o src/operations.o src/math.o
-dynamic_OBJS=src/dynamic.o arch/arch.a src/std.o src/stack.o
-testFS_OBJS=src/testFS.o arch/arch.a src/std.o
+sarpn_OBJS=src/sarpn.o src/std.o src/stack.o src/operations.o src/math.o arch/arch.a
+dynamic_OBJS=src/dynamic.o src/std.o src/stack.o arch/arch.a
+testFS_OBJS=src/testFS.o src/std.o src/fs.o arch/arch.a
 
 ARCH_OBJS=arch/io.o arch/cons.o arch/ebcdic.o arch/fba.o arch/ioint.o
 
@@ -28,7 +28,7 @@
 clean:
 	rm -f $(sarpn_OBJS)
 	rm -f $(dynamic_OBJS)
-	rm -f $(fs_OBJS)
+	rm -f $(testFS_OBJS)
 	rm -f $(ARCH_OBJS)
 	rm -f $(BINS)
 	rm -f loader.bin ipl/*.o ipl/*.rto ipl/ipl_ccws.S cscope.out
@@ -94,9 +94,10 @@
 # DO NOT DELETE
 
 src/dynamic.o: include/std.h include/operations.h include/stack.h
+src/fs.o: include/fs.h
 src/operations.o: include/operations.h include/std.h include/stack.h
 src/operations.o: include/math.h
 src/sarpn.o: include/std.h include/operations.h include/stack.h
 src/stack.o: include/stack.h include/std.h
 src/std.o: include/std.h
-src/testFS.o: include/std.h
+src/testFS.o: include/std.h include/fs.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/fs.h	Fri Apr 08 13:41:58 2011 -0400
@@ -0,0 +1,39 @@
+#ifndef __FS_H
+#define __FS_H
+
+struct SUPERBLOCK {
+	u32 magic;              // == 0x42420374
+	u32 root_inode;         // the disk block containing the root inode
+	u32 nblocks;            // number of block on the disk
+	u32 _pad[253];          // unused (should be '\0' filled)
+};
+typedef struct SUPERBLOCK Superblock;
+
+struct INODE {
+	u32 size;               // file length in bytes
+	u32 _pad0;              // unused (should be 0)
+	u64 ctime;              // creation time stamp
+	u64 mtime;              // last modification time stamp
+	u16 nblocks;            // number of data blocks in this file
+	u16 _pad1;              // unused (should be 0)
+	u32 _pad2;              // unused (should be 0)
+	u32 blocks[248];        // file block ptrs
+};
+typedef struct INODE Inode;
+
+struct DIRENTRY { //32 bytes
+	char fname[28];
+	u32 inode;
+};
+typedef struct DIRENTRY Direntry;
+
+int fsInit(u32 devnum);
+void listFiles();
+u32 lookupFile(char *fname);
+u32 getFSize(u32 fid);
+int getFData(u32 fid, void *ptr);
+void printFname(char *name);
+void getFname(char *fname);
+int fnameCmp(const char *a, const char *b);
+
+#endif //__FSH_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/fs.c	Fri Apr 08 13:41:58 2011 -0400
@@ -0,0 +1,125 @@
+#include <fs.h>
+#include <std.h>
+
+static int loadToCache(u32 fid);
+static int readFSBlock(u32 dev, u32 blkno, void *fsBlock);
+
+static u32 DevID;
+//static Superblock sb; //the superblock
+static Direntry Direntries[32];
+static int NFiles;
+
+static u32 CacheID = 0;
+static Inode Cached;
+
+int fsInit(u32 devnum)
+{
+	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);
+	if(NFiles > 32) return -1; //for the moment, I do not feel like having support
+	                           //for this.  TODO add support
+	int i;
+	for(i = 0; i*32 < NFiles; i++) { //this will only run once...  It is useless
+		if(readFSBlock(DevID, rootINode.blocks[i], Direntries)) return -1;
+	}
+	return 0;
+}
+
+void listFiles()
+{
+	Direntry *dp;
+	for(dp = Direntries; dp - Direntries < NFiles; dp++)
+		printFname(dp->fname), putline("\n", 1);
+}
+
+u32 lookupFile(char *fname)
+{
+	Direntry *dp;
+	for(dp = Direntries; dp - Direntries < NFiles; dp++) {
+		if(!fnameCmp(fname, dp->fname)) {
+			if(loadToCache(dp->inode)) return 0;
+			return dp->inode;
+		}
+	}
+	return 0;
+}
+
+//REQUIRES:   Valid loadable fid
+u32 getFSize(u32 fid)
+{
+	loadToCache(fid);
+	return Cached.size;
+}
+
+
+//REQUIRES:   point is large enough to hold everything
+int getFData(u32 fid, void *ptr)
+{
+	int i;
+	loadToCache(fid);
+	u32 size = Cached.size;
+	u16 nBlocks = Cached.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...
+		}
+	}
+	return 0;
+}
+
+
+void printFname(char *name)
+{
+	putline(name, 28);
+}
+
+//Sets name to contain a filename entered by the user
+//REQUIRES:   fname is 28 characters long
+void getFname(char *fname)
+{
+	int chars = getline(fname, 28);
+	for(;chars < 28; chars++) {
+		fname[chars] = ' ';
+	}
+}
+
+//Checks whether two file names are equal
+int fnameCmp(const char *a, const char *b)
+{
+	int i;
+	for(i = 0; i < 28; i++, a++, b++) {
+		if(*a - *b) return *a - *b;
+	}
+	return 0;
+}
+
+static int loadToCache(u32 fid)
+{
+	if(CacheID == fid) return 0;
+	if(readFSBlock(DevID, fid, &Cached)) return -1;
+	CacheID = fid;
+	return 0;
+}
+
+//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)
+{
+	if(fba_read_blk(dev, blkno*2, fsBlock)) return 1;
+	if(fba_read_blk(dev, blkno*2 + 1, fsBlock + 512)) return 1;
+	return 0;
+}
--- a/src/testFS.c	Fri Apr 08 10:33:40 2011 -0400
+++ b/src/testFS.c	Fri Apr 08 13:41:58 2011 -0400
@@ -1,73 +1,5 @@
 #include <std.h>
-
-struct SUPERBLOCK {
-	u32 magic;              // == 0x42420374
-	u32 root_inode;         // the disk block containing the root inode
-	u32 nblocks;            // number of block on the disk
-	u32 _pad[253];          // unused (should be '\0' filled)
-};
-typedef struct SUPERBLOCK Superblock;
-
-struct INODE {
-	u32 size;               // file length in bytes
-	u32 _pad0;              // unused (should be 0)
-	u64 ctime;              // creation time stamp
-	u64 mtime;              // last modification time stamp
-	u16 nblocks;            // number of data blocks in this file
-	u16 _pad1;              // unused (should be 0)
-	u32 _pad2;              // unused (should be 0)
-	u32 blocks[248];        // file block ptrs
-};
-typedef struct INODE Inode;
-
-struct DIRENTRY { //32 bytes
-	char fname[28];
-	u32 inode;
-};
-typedef struct DIRENTRY Direntry;
-
-//REQUIRES:   fsBlock points to an object with size at least 1024
-//EFFECTS:    Sets fsBlock to be equal
-int readFSBlock(u32 dev, u32 blkno, void *fsBlock)
-{
-	if(fba_read_blk(dev, blkno*2, fsBlock)) return 1;
-	if(fba_read_blk(dev, blkno*2 + 1, fsBlock + 512)) return 1;
-	return 0;
-}
-
-void printFname(char *name)
-{
-	putline(name, 28);
-}
-
-//Sets name to contain a filename entered by the user
-//REQUIRES:   name is 28 characters long
-void getFname(char *fname)
-{
-	int chars = getline(fname, 28);
-	for(;chars < 28; chars++) {
-		fname[chars] = ' ';
-	}
-}
-
-//Checks whether two file names are equal
-int fnameCmp(const char *a, const char *b)
-{
-	int i;
-	for(i = 0; i < 28; i++, a++, b++) {
-		if(*a - *b) return *a - *b;
-	}
-	return 0;
-}
-
-//Finds the item within an array of filenames with the same name as fname
-int fnameLookup(char *fname, const Direntry array[], int last)
-{
-	int i;
-	for(i = 0; i < last; i++)
-		if(!fnameCmp(fname, array[i].fname)) return i;
-	return last;
-}
+#include <fs.h>
 
 void dumpText(char *text, int size)
 {
@@ -82,68 +14,31 @@
 {
 	init_io_int();
 	init_console();
+	malloc_init(__memsize - HEAP_START);
 	char buffer[256];
-	int i;
-	
-	u32 dev = find_dev(0x100);
-	Superblock sb;
-	if(readFSBlock(dev, 1, &sb)) { //get the super block
-		sPrint("ERROR\n");
-		goto END;
-	}
-	Inode root;
-	if(readFSBlock(dev, sb.root_inode, &root)) { //get the root inode
-		sPrint("ERROR\n");
-		goto END;
-	}
-	int nFiles = root.size/sizeof(Direntry);
-		//calculate how many files (assume less than 32 for the moment)
-		//TODO get rid of assumption
-	Direntry direntries[32];
-	if(readFSBlock(dev, root.blocks[0], direntries)) { //get the "first 32" files
-		sPrint("ERROR\n");
-		goto END;
-	}
+	if(fsInit(0x100)) goto END;
 
 	while(1) {
 		
 		//Prints off the name of each file
-		Direntry *dp;
-		for(dp = direntries; dp - direntries < nFiles; dp++) {
-			printFname(dp->fname), sPrint("\n");
-		}
+		listFiles();
 		char fname[28];
 		sPrint("Please enter the file to read: ");
 		getFname(fname);
-		int file = fnameLookup(fname, direntries, nFiles);
-
-		u32 fileLoc = direntries[file].inode;
-		if(fileLoc == nFiles) continue;
-
-		Inode fileToRead;
-		if(readFSBlock(dev, fileLoc, &fileToRead)) {
-			sPrint("ERROR\n");
-			goto END;
-		}
+		u32 fid = lookupFile(fname);
+		if(!fid) continue; //if fid is 0, the file was not found
 
-		u32 fileSize = fileToRead.size;
-
-		for(i = 0; i < fileToRead.nblocks; i++) {
-			char text[1024];
-			if(readFSBlock(dev, fileToRead.blocks[i], text)) {
-				sPrint("ERROR\n");
-				goto END;
-			}
-			dumpText(text, (fileSize > 1024)?1024:fileSize);
-			fileSize -= 1024;
-		}
+		u32 fileSize = getFSize(fid);
+		char *text = malloc(fileSize);
+		text = text;
+		getFData(fid, text);
+		dumpText(text, fileSize);
+		free(text);
 	}
 
-
 END:
 	sPrint("DONE\n");
 	for(;;) {
 		sGet(buffer, 0);
 	}
 }
-