view src/fs.c @ 52:2de1c2597a60

Modified getFSize so it now returns a value indicating success/failure Also modified the lookup function so it does not load the file into the cache
author Jonathan Pevarnek <pevarnj@gmail.com>
date Sat, 09 Apr 2011 01:28:06 -0400
parents eda059d74100
children b22b6a83cf04
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 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)) {
			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;
}


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;
}