Mercurial > sos > sos
view src/fs.c @ 54:39fcefab46ed
Modified the init_fs function to take advantage of dynamic memory
init_fs (renamed) now takes advantage of dynamic memory and allocates space
for exactly as many direntries as it needs to keep track of
TODO redo caching to Jeff's far superior idea
author | Jonathan Pevarnek <pevarnj@gmail.com> |
---|---|
date | Sat, 09 Apr 2011 21:55:59 -0400 |
parents | b22b6a83cf04 |
children | 25be3895c62a |
line wrap: on
line source
#include <fs.h> #include <std.h> static int loadToCache(u32 fid); static int readFSBlock(u32 dev, u32 blkno, void *fsBlock); static u32 DevID; static Direntry *Direntries = NULL; static int NFiles; static u32 CacheID = 0; static Inode Cached; int init_fs(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); Direntries = malloc(rootINode.size); if(getFData(sb.root_inode, 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)) { return dp->inode; } } return 0; } //REQUIRES: Valid loadable fid //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; return 0; } //REQUIRES: ptr 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; } short isBlockAt(u32 block) { //TODO reconsider return value 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; } 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) { //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; }