changeset 61:5e1d4b26c2ef

Added the ability to write an arbitrary block of data to some file First, I also fixed some memory leaks with the file reading function Second, there seems to be a lot of code duplication at the moment, taking care of it is now my next priority I removed the blankFile function, it was absolutely useless (and unless I am mistaken, it can now be duplicated with setFileData(fid, NULL, 0); I added the setFileSize function, it will set the size of a file to be equal to some specified amount. It will not alter the data in any blocks so if downsizing everything under that point will be the same. If increasing the size, everything over that point will most likely be garbage. The function setFileData will now set the data stored in some file to be equal to data passed by the user. TODO: fix duplication, add creating files
author Jonathan Pevarnek <pevarnj@gmail.com>
date Sat, 16 Apr 2011 20:17:51 -0400
parents 21089dc88985
children 0e6f80b5a3d0
files Makefile include/fs.h src/fs.c src/testFS.c
diffstat 4 files changed, 118 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Thu Apr 14 00:23:28 2011 -0400
+++ b/Makefile	Sat Apr 16 20:17:51 2011 -0400
@@ -93,11 +93,12 @@
 
 # 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 include/fs.h
+src/dynamic.o: include/std.h include/die.h include/operations.h
+src/dynamic.o: include/stack.h
+src/fs.o: include/fs.h include/std.h include/die.h
+src/operations.o: include/operations.h include/std.h include/die.h
+src/operations.o: include/stack.h include/math.h
+src/sarpn.o: include/std.h include/die.h include/operations.h include/stack.h
+src/stack.o: include/stack.h include/std.h include/die.h
+src/std.o: include/std.h include/die.h
+src/testFS.o: include/std.h include/die.h include/fs.h
--- a/include/fs.h	Thu Apr 14 00:23:28 2011 -0400
+++ b/include/fs.h	Sat Apr 16 20:17:51 2011 -0400
@@ -7,6 +7,7 @@
 #define FNAMELEN 28 //How long the filenames are
 #define FSBLKSIZE 1024
 #define DSKBLKSIZE 512
+#define MAXBLOCKS 248
 
 struct SUPERBLOCK {
 	u32 magic;              // == 0x42420374
@@ -24,7 +25,7 @@
 	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
+	u32 blocks[MAXBLOCKS];  // file block ptrs
 };
 typedef struct INODE Inode;
 
@@ -47,10 +48,10 @@
 int init_fs(u32 devnum, u64 __memsize);
 void listFiles();
 u32 lookupFile(char *fname);
-int getFSize(u32 fid, u32 *size);
-int getFData(u32 fid, void *ptr);
+int getFileSize(u32 fid, u32 *size);
+int getFileData(u32 fid, void *ptr);
+int setFileData(u32 fid, const void *ptr, size_t size);
 short isBlockAt(u32 block);
-int blankFile(u32 fid);
 void printFname(char *name);
 void getFname(char *fname);
 int fnameCmp(const char *a, const char *b);
--- a/src/fs.c	Thu Apr 14 00:23:28 2011 -0400
+++ b/src/fs.c	Sat Apr 16 20:17:51 2011 -0400
@@ -3,6 +3,7 @@
 
 static u32 getCacheLoc(u32 blkno);
 static u32 cacheAdd(u32 blkno);
+static int setFileSize(u32 fid, size_t size);
 static int setBlockAt(u32 block, short isBlock);
 static void* readFSBlock(u32 blkno);
 static int writeFSBlock(u32 blkno, void *ptr);
@@ -42,7 +43,7 @@
 	NFiles = rootINode->size/sizeof(Direntry);
 	Direntries = malloc(rootINode->size); //get array of the files
 	if(!Direntries) return -1;
-	if(getFData(rootLoc, Direntries)) return -1;
+	if(getFileData(rootLoc, Direntries)) return -1;
 
 	return 0;
 }
@@ -69,7 +70,7 @@
 
 //PRECON:  fid is a valid file id
 //This sets *size equal to the size of the file.  Will return 0 an success
-int getFSize(u32 fid, u32 *size)
+int getFileSize(u32 fid, u32 *size)
 {
 	Inode *ptr = readFSBlock(fid);
 	if(!ptr) return -1;
@@ -79,7 +80,7 @@
 
 //PRECON:  ptr points to a large enough location to hold all the data in file
 //         fid
-int getFData(u32 fid, void *ptr)
+int getFileData(u32 fid, void *ptr)
 {
 	int i;
 	Inode *temp = readFSBlock(fid);
@@ -91,32 +92,87 @@
 
 	u32 size = inPtr->size;
 	for(i = 0; i < inPtr->nblocks; i++) {
-		Inode *filePtr;
-		filePtr = readFSBlock(inPtr->blocks[i]);
-		if(!filePtr) return -1;
+		Inode *filePtr = readFSBlock(inPtr->blocks[i]);
+		if(!filePtr) {
+			free(inPtr);
+			return -1;
+		}
 		memcpy(ptr, filePtr, Min_u32(size, FSBLKSIZE));
+		sync(inPtr->blocks[i]); //update the content of the actual file on disk
 		ptr += FSBLKSIZE;
 		size -= FSBLKSIZE;
 	}
+	if(writeFSBlock(fid, inPtr)) {
+		free(inPtr);
+		return -1;
+	}
 	free(inPtr);
 	return 0;
 }
 
-int blankFile(u32 fid)
+int setFileData(u32 fid, const void *ptr, size_t size)
 {
-	int i;
-
+	unsigned int i;
+	if(setFileSize(fid, size)) return -1; //TODO efficiency (talk to Jeff)
 	Inode *temp = readFSBlock(fid);
 	if(!temp) return -1;
 	Inode *inPtr = malloc(sizeof(Inode));
 	if(!inPtr) return -1;
 	memcpy(inPtr, temp, sizeof(Inode));
 
-	for(i = 0; i < inPtr->nblocks; i++)
-		setBlockAt(inPtr->blocks[i], 0);
-	inPtr->nblocks = 0;
-	inPtr->size = 0;
-	writeFSBlock(fid, inPtr);
+	for(i = 0; i < inPtr->nblocks; i++) {
+		Inode *filePtr = readFSBlock(inPtr->blocks[i]);
+		if(!filePtr) {
+			free(inPtr);
+			return -1;
+		}
+		memcpy(filePtr, ptr, Min_u32(size, FSBLKSIZE));
+		ptr += FSBLKSIZE;
+		size -= FSBLKSIZE;
+	}
+
+	free(inPtr);
+	return 0;
+}
+
+//sets the file to have a size equal to size.  The data will be preserved if
+//the file is currently larger than that or will be jibberish if the file is
+//currently smaller
+static int setFileSize(u32 fid, size_t size)
+{
+	unsigned int i, j;
+	u16 neededBlocks = (size + FSBLKSIZE - 1)/FSBLKSIZE;
+	if(neededBlocks > MAXBLOCKS) return -1;
+	Inode *temp = readFSBlock(fid);
+	if(!temp) return -1;
+	Inode *inPtr = malloc(sizeof(Inode));
+	if(!inPtr) return -1;
+	memcpy(inPtr, temp, sizeof(Inode));
+
+	if(inPtr->nblocks >= neededBlocks) { //get rid of some blocks
+		for(i = neededBlocks; i < inPtr->nblocks; i++) { //if it is equal, will skip this loop
+			if(setBlockAt(inPtr->blocks[i], 0)) {
+				free(inPtr);
+				return -1;
+			}
+		}
+	} else { //there are fewer blocks
+		for(i = inPtr->nblocks; i < neededBlocks; i++) {
+			inPtr->blocks[i] = 0;
+			for(j = inPtr->blocks[i - 1]; inPtr->blocks[i] == 0; j++)
+				if(!isBlockAt(j)) inPtr->blocks[i] = j;
+			if(setBlockAt(inPtr->blocks[i], 1)) {
+				free(inPtr);
+				return -1;
+			}
+		}
+	}
+	inPtr->nblocks = neededBlocks;
+	inPtr->size = size;
+	if(writeFSBlock(fid, inPtr)) {
+		free(inPtr);
+		return -1;
+	}
 	return 0;
 }
 
--- a/src/testFS.c	Thu Apr 14 00:23:28 2011 -0400
+++ b/src/testFS.c	Sat Apr 16 20:17:51 2011 -0400
@@ -25,13 +25,45 @@
 		u32 fid = lookupFile(fname);
 		if(!fid) continue; //if fid is 0, the file was not found
 		u32 fileSize;
-		if(getFSize(fid, &fileSize)) continue;
+		if(getFileSize(fid, &fileSize)) continue;
 		char *text = malloc(fileSize);
-		if(getFData(fid, text)) continue;
+		if(getFileData(fid, text)) continue;
 		dumpText(text, fileSize);
 		free(text);
 	}
 
+	/*
+	while(1) {
+		//Prints off the name of each file
+		listFiles();
+		char fname[28];
+		sPrint("Please enter the file to read: ");
+		getFname(fname);
+		u32 fid = lookupFile(fname);
+		if(!fid) continue; //if fid is 0, the file was not found
+		sPrint("Please enter the file to copy to: ");
+		getFname(fname);
+		u32 fid2 = lookupFile(fname);
+		if(!fid2) continue;
+		u32 fileSize;
+		if(getFileSize(fid, &fileSize)) continue;
+		char *text = malloc(fileSize);
+		if(!text) continue;
+		if(getFileData(fid, text)) {
+			free(text);
+			continue;
+		}
+		setFileData(fid2, text, fileSize);
+		free(text);
+		
+		if(getFileSize(fid2, &fileSize)) continue;
+		text = malloc(fileSize);
+		if(getFileData(fid2, text)) continue;
+		dumpText(text, fileSize);
+		free(text);
+	}
+	*/
+
 END:
 	sPrint("DONE\n");
 	for(;;) {