Mercurial > sos > sos
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