# HG changeset patch # User Jonathan Pevarnek # Date 1302999471 14400 # Node ID 5e1d4b26c2ef12325c5d514434277cc1d28b0c79 # Parent 21089dc889852308a48b98c8f10ee3680812b66c 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 diff -r 21089dc88985 -r 5e1d4b26c2ef Makefile --- 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 diff -r 21089dc88985 -r 5e1d4b26c2ef 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); diff -r 21089dc88985 -r 5e1d4b26c2ef src/fs.c --- 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; } diff -r 21089dc88985 -r 5e1d4b26c2ef src/testFS.c --- 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(;;) {