From 4ea4ae4d2c7c99f1130fa844ad671705d61354fb Mon Sep 17 00:00:00 2001 From: bdemsky Date: Tue, 18 May 2004 02:51:28 +0000 Subject: [PATCH] Filesystem benchmark --- Repair/RepairCompiler/MCC/Runtime/danfile.cc | 1055 ++++++++++++++++++ Repair/RepairCompiler/MCC/Runtime/file.h | 104 ++ 2 files changed, 1159 insertions(+) create mode 100755 Repair/RepairCompiler/MCC/Runtime/danfile.cc create mode 100755 Repair/RepairCompiler/MCC/Runtime/file.h diff --git a/Repair/RepairCompiler/MCC/Runtime/danfile.cc b/Repair/RepairCompiler/MCC/Runtime/danfile.cc new file mode 100755 index 0000000..4832151 --- /dev/null +++ b/Repair/RepairCompiler/MCC/Runtime/danfile.cc @@ -0,0 +1,1055 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +extern int errno; + +#include "file.h" + +#include "test3_aux.h" +#include "memory.h" + +char *dstring="d\0"; +struct filedesc files[MAXFILES]; +struct InodeBitmap ib; +struct BlockBitmap bb; + +int bbbptr; // pointer to the BlockBitmap block +int ibbptr; // pointer to the InodeBlock block +int itbptr; // pointer to the InodeTable block +int rdiptr; // pointer to the RootDirectoryInode block + +struct InodeBitmap* sc_ib; +struct BlockBitmap* sc_bb; +struct InodeBlock* sc_it; +int sc_bbbptr; +int sc_ibbptr; +int sc_itbptr; +int sc_rdiptr; + +#include "SimpleHash.h" + +int testinode(int i) { + char temp; + assert(sc_ib); + temp = sc_ib->inode[i/8]&(1<<(i%8)); + return temp == 0 ? 0 : 1; +} + +int testblock(int i) { + char temp; + assert(sc_bb); + temp = sc_bb->blocks[i/8]&(1<<(i%8)); + return temp == 0 ? 0 : 1; +} + +unsigned long selfcheck2(struct block* d) { + + struct timeval begin,end; + unsigned long t; + gettimeofday(&begin,NULL); + +#include "test3.cc" + + gettimeofday(&end,NULL); + t=(end.tv_sec-begin.tv_sec)*1000000+end.tv_usec-begin.tv_usec; + return t; +} + +void selfcheck(struct block* diskptr) { + + /* get time information for statistics */ + struct timeval begin,end; + unsigned long t; + gettimeofday(&begin,NULL); + + + /* hand written data structure consistency */ + + struct SuperBlock* sb = (struct SuperBlock*)&diskptr[0]; + struct GroupBlock* gb = (struct GroupBlock*)&diskptr[1]; + + int numblocks = sb->NumberofBlocks; + int numinodes = sb->NumberofInodes; + + SimpleHash* hash_inodeof = new SimpleHash(1000); // estimation of the number of files! + SimpleHash* hash_contents = new SimpleHash(1000); // contents + SimpleList* list_inodes = new SimpleList(); + SimpleList* list_blocks = new SimpleList(); + + // simple test + + // check bitmap consistency with superblock, groupblock, inotetableblock + // inodebitmapblock, blockbitmapblock, rootidrectoryinode + + sc_bbbptr = gb->BlockBitmapBlock; + sc_ibbptr = gb->InodeBitmapBlock; + sc_itbptr = gb->InodeTableBlock; + sc_rdiptr = sb->RootDirectoryInode; + + // constraint 8: automatic... + // constraint 9: automatic... + + // constraint 10: + if (sc_itbptr < numblocks) { + sc_it = (InodeBlock*)&diskptr[sc_itbptr]; + } else { + sc_it = NULL; + } + + // constraint 11: + if (sc_ibbptr < numblocks) { + sc_ib = (InodeBitmap*)&diskptr[sc_ibbptr]; + } else { + sc_ib = NULL; + } + + // constraint 12: + if (sc_bbbptr < numblocks) { + sc_bb = (BlockBitmap*)&diskptr[sc_bbbptr]; + } else { + sc_bb = NULL; + } + + // rule 1 + if (sc_bb) { + // constraint 3 + assert(testblock(0)); // superblock + + // building blocks + list_blocks->add(0); + } + + // rule 2 + if (sc_bb) { + // constraint 3 + assert(testblock(1)); // groupblock + + // building list_blocks + list_blocks->add(1); + } + + // rule 3 + if (sc_bb) { + // constraint 3 + assert(testblock(sc_itbptr)); + + // building list_blocks + list_blocks->add(sc_itbptr); + } + + // rule 4 + if (sc_bb) { + // constraint 3 + assert(testblock(sc_ibbptr)); + + // building list_blocks + list_blocks->add(sc_ibbptr); + } + + // rule 5 + if (sc_bb) { + // constraint 3 + assert(testblock(sc_bbbptr)); + + // building list_blocks + list_blocks->add(sc_bbbptr); + } + + // build inodeof and contents + if (sb->RootDirectoryInode < numinodes) { + int dinode = sb->RootDirectoryInode; + + // building list_inodes + list_inodes->add(dinode); + + for (int k = 0 ; k <= 11 ; k++) { + + int block = sc_it->entries[dinode].Blockptr[k]; + + if (block != 0) { + hash_contents->add(dinode, block); + list_blocks->add(block); + } + + if (block < numblocks) { + + DirectoryBlock* db = (DirectoryBlock*)&diskptr[block]; + + for (int j = 0; j < sb->blocksize/128 ; j++) { + + DirectoryEntry* de = (DirectoryEntry*)&db->entries[j]; + + if (de->inodenumber < numinodes) { + // add to inodeof + hash_inodeof->add((int)de, de->inodenumber); + } + + if (de->inodenumber < numinodes && de->inodenumber != 0) { + + // build list_inodes + list_inodes->add(de->inodenumber); + + for (int j2 = 0 ; j2 <= 11 ; j2++) { + int block2 = sc_it->entries[de->inodenumber].Blockptr[j2]; + if (block2 != 0) { + hash_contents->add(de->inodenumber, block2); + if (block2 < numblocks) { + list_blocks->add(block2); + } + } + } + } + } + } + } + } + + //printf("\n"); + + // rule 6 and rule 11: rootdirectoryinode + if (sb->RootDirectoryInode < numinodes) { + int inode = sb->RootDirectoryInode; + + // constraint 1 + assert(testinode(inode)); + + int filesize = sc_it->entries[inode].filesize; + int contents = 0; + for (int j = 0; j <= 11; j++) { + int block2 = sc_it->entries[inode].Blockptr[j]; + if (block2 != 0) { + // TBD: needs to actual store state because + // there could be duplicate numbers and they + // shouldn't be double counted + contents++; + + // rule 11 + if (block2 < numblocks) { + // constraint 3 + assert(testblock(block2)); + + // constraint 7 + //printf("%d - %d %d %d\n", inode, j, block2, hash_contents->countdata(block2)); + assert(hash_contents->countdata(block2)==1); + } + } + } + + // constraint 6 + assert(filesize <= (contents*8192)); + + // constraint 5: + assert(sc_it->entries[inode].referencecount == hash_inodeof->countdata(inode)); + } + + // rule 14 + if (sb->RootDirectoryInode < numinodes) { + int dinode = sb->RootDirectoryInode; + + for (int j = 0; j < sb->blocksize/128 ; j++) { + for (int k = 0 ; k <= 11 ; k++) { + int block = sc_it->entries[dinode].Blockptr[k]; + if (block < numblocks) { + DirectoryBlock* db = (DirectoryBlock*)&diskptr[block]; + DirectoryEntry* de = (DirectoryEntry*)&db->entries[j]; + + int inode = de->inodenumber; + if (inode < numinodes && inode != 0) { + + // constraint 1 + assert(testinode(inode)); + + // constraint 6 + int filesize = sc_it->entries[inode].filesize; + int contents = 0; + for (int j2 = 0; j2 <= 11; j2++) { + int block2 = sc_it->entries[inode].Blockptr[j2]; + if (block2 != 0) { + // TBD + contents++; + + // rule 11 + if (block2 < numblocks) { + // constraint 3 + assert(testblock(block2)); + + // constraint 7 + assert(hash_contents->countdata(block2)==1); + } + } + } + assert(filesize <= (contents*8192)); + + // constraint 5: + assert(sc_it->entries[inode].referencecount == hash_inodeof->countdata(inode)); + } + } + } + } + } + + // to go, [7, 8 ] + // interesting question is going to be how to deal with 7 and 8 + // actually it turns out that the constraints bound to rules 7 and 8 are + // easy... its just that creating the lists for 7 and 8 is a little tricky... + // 7 can easily piggyback on the creation of inodeof/contents... it fits quite + // nicely into that traversal... same goes for 8 + + // rule 7 + for (int i = 0 ; i < numinodes ; i++) { + if (!list_inodes->contains(i)) { + // constraint 2 + if (testinode(i)) { + printf("", i); + assert(testinode(i)==0); + } + } + } + + // rule 8 + for (int i = 0 ; i < numblocks ; i++) { + if (!list_blocks->contains(i)) { + // constraint 4 + if (testblock(i)) { + printf("", i); + assert(testblock(i)==0); + } + + } + } + + + gettimeofday(&end,NULL); + t=(end.tv_sec-begin.tv_sec)*1000000+end.tv_usec-begin.tv_usec; + + printf("\npassed tests in %ld u-seconds!\n", t); + + +} + + +int main(int argc, char **argv) +{ + initializemmap(); + + for(int i=0;i1; i--) { + char filename[10]; + sprintf(filename,"file_%d",i); + openfile(ptr,filename); + } + for(int j=0; j<90; j++) { + for(int i=NUMFILES; i>1; i--) { + char *buf="01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123"; + writefile(ptr,i,buf,122); + } + } + for(int i=NUMFILES; i>1; i--) { + closefile(ptr,i); + } + unmountdisk(ptr); + break; + } + + case '7': { + struct block * ptr=mountdisk("disk"); + for(int i=NUMFILES; i>=0; i--) { + char filename[10]; + sprintf(filename,"file_%d",i); + openfile(ptr,filename); + } + + for(int j=0;j<6000;j++) { + for(int i=NUMFILES; i>=0; i--) { + char name[10]; + int len=sprintf(name, "%d ",i); + writefile(ptr,i,name,len); + } + } + for(int i=NUMFILES; i>=0; i--) { + closefile(ptr,i); + } + for(int i=NUMFILES; i>=0; i--) { + char filename[10]; + sprintf(filename,"file_%d",i); + openfile(ptr,filename); + } + + for(int j=0;j<400;j++) { + for(int i=NUMFILES; i>=0; i--) { + int l=0; + char name[10]; + int len=sprintf(name, "%d ",i); + readfile(ptr,i,name,len); + sscanf(name, "%d ", &l); + if (l!=i) { + printf("ERROR in benchmark\n"); + } + } + } + for(int i=NUMFILES; i>=0; i--) { + closefile(ptr,i); + } + unmountdisk(ptr); + } + break; + + + case '8': { + { + struct block * ptr=chmountdisk("disk"); + chunmountdisk(ptr); + } + struct block * ptr=mountdisk("disk"); + for(int i=NUMFILES; i>=0; i--) { + char filename[10]; + sprintf(filename,"file_%d",i); + openfile(ptr,filename); + } + for(int j=0; j<6000; j++) { + for(int i=NUMFILES; i>=0; i--) { + char name[10]; + int len=sprintf(name, "%d ",i); + writefile(ptr,i,name,len); + } + } + for(int i=NUMFILES; i>=0; i--) { + closefile(ptr,i); + } + for(int i=NUMFILES; i>=0; i--) { + char filename[10]; + sprintf(filename,"file_%d",i); + openfile(ptr,filename); + } + for(int j=0;j<400;j++) { + for(int i=NUMFILES; i>=0; i--) { + int l=0; + char name[10]; + int len=sprintf(name, "%d ",i); + readfile(ptr,i,name,len); + sscanf(name, "%d ", &l); + if (l!=i) { + printf("ERROR in benchmark\n"); + } + } + } + for(int i=NUMFILES; i>=0; i--) { + closefile(ptr,i); + } + unmountdisk(ptr); + } + + case '9': { + for(int i=0;iBlockBitmapBlock; + ibbptr=gb->InodeBitmapBlock; + itbptr=gb->InodeTableBlock; + rdiptr=sb->RootDirectoryInode; + + struct InodeBitmap *ibb=(struct InodeBitmap *) &ptr[ibbptr]; + for(int i=0;i<(NUMINODES/8+1);i++) + ib.inode[i]=ibb->inode[i]; + + struct BlockBitmap *bbb=(struct BlockBitmap *) &ptr[bbbptr]; + for(int i=0;i<(NUMBLOCK/8+1);i++) + bb.blocks[i]=bbb->blocks[i]; + + printf("Disk mounted successfully from the file %s\n", filename); + fflush(NULL); + + return ptr; +} + + + +void unmountdisk(struct block *vptr) { + struct InodeBitmap *ibb=(struct InodeBitmap *) &vptr[ibbptr]; + for(int i=0;i<(NUMINODES/8+1);i++) + ibb->inode[i]=ib.inode[i]; + + struct BlockBitmap *bbb=(struct BlockBitmap *) &vptr[bbbptr]; + for(int i=0;i<(NUMBLOCK/8+1);i++) + bbb->blocks[i]=bb.blocks[i]; + int val=munmap(vptr,LENGTH); + dealloc(vptr); + if (val!=0) + printf("Error!\n"); +} + + +void removefile(char *filename, struct block *ptr) { + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + for(int i=0;i<12;i++) { + struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]]; + for(int j=0;jentries[j].name[0]!=0) { + if(strcmp(filename,db->entries[j].name)==0) { + /* Found file */ + db->entries[j].name[0]=0; //Delete entry + int inode=db->entries[j].inodenumber; + db->entries[j].inodenumber=0; + + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + itb->entries[inode].referencecount--; + + if (itb->entries[inode].referencecount==0) { + for(int i=0;i<((itb->entries[inode].filesize+BLOCKSIZE-1)/BLOCKSIZE);i++) { + int blocknum=itb->entries[inode].Blockptr[i]; + bb.blocks[blocknum/8]^=(1<<(blocknum%8)); + } + ib.inode[inode/8]^=(1<<(inode%8)); + } + } + } + } + } +} + + +void createlink(struct block *ptr,char *filename, char *linkname) { + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + for(int i=0;i<12;i++) { + struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]]; + for(int j=0;jentries[j].name[0]!=0) { + if(strcmp(filename,db->entries[j].name)==0) { + /* Found file */ + int inode=db->entries[j].inodenumber; + struct InodeBlock * itb=(struct InodeBlock *) &ptr[4]; + itb->entries[inode].referencecount++; + addtode(ptr, inode, linkname); + } + } + } + } +} + + +void closefile(struct block *ptr, int fd) { + struct InodeBlock * itb=(struct InodeBlock *) &ptr[4]; + + + msync(&itb->entries[fd],sizeof(DirectoryEntry),MS_SYNC); + files[fd].used=false; +} + + +bool writefile(struct block *ptr, int fd, char *s) { + return (writefile(ptr,fd,s,1)==1); +} + + +int writefile(struct block *ptr, int fd, char *s, int len) { + struct filedesc *tfd=&files[fd]; + if (tfd->used==false) + return -1; + struct InodeBlock * itb=(struct InodeBlock *) &ptr[4]; + int filelen=itb->entries[tfd->inode].filesize; + if ((12*BLOCKSIZE-tfd->offset)offset; + for(int i=0;ioffset/BLOCKSIZE; + int noffset=tfd->offset%BLOCKSIZE; + if (tfd->offset>=filelen) { + if (noffset==0) { + int bptr=getblock(ptr); + if (bptr==-1) { + if (itb->entries[files[fd].inode].filesizeentries[files[fd].inode].filesize=files[fd].offset; + return i; + } + itb->entries[tfd->inode].Blockptr[nbuffer]=bptr; + } + } + int block=itb->entries[tfd->inode].Blockptr[nbuffer]; + char *fchar=(char *)&ptr[block]; + int tocopy=len-i; + if (tocopy>(BLOCKSIZE-noffset)) + tocopy=BLOCKSIZE-noffset; + memcpy(&fchar[noffset],&s[i],tocopy); + msync(&fchar[noffset],tocopy,MS_SYNC); + i+=tocopy; + tfd->offset+=tocopy; + } + if (itb->entries[files[fd].inode].filesizeentries[files[fd].inode].filesize=files[fd].offset; + return len; +} + + +// reads one char from the file fd and returns it +char readfile(struct block *ptr, int fd) { + char array[1]; + if (readfile(ptr,fd,array,1)==1) + return array[0]; + else + return EOF; +} + +// reads len chars from file fd (file system *ptr) and returns them in buf +int readfile(struct block *ptr, int fd, char *buf, int len) { + struct filedesc *tfd=&files[fd]; + if (tfd->used==false) + return -1; + + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + int filelen=itb->entries[tfd->inode].filesize; + + // if there are fewer than len chars left, read until the end + if ((filelen-tfd->offset)offset; + + for(int i=0;ioffset/BLOCKSIZE; + int noffset=tfd->offset%BLOCKSIZE; + int block=itb->entries[tfd->inode].Blockptr[nbuffer]; + char *fchar=(char *)&ptr[block]; + int tocopy=len-i; + if (tocopy>(BLOCKSIZE-noffset)) + tocopy=BLOCKSIZE-noffset; + memcpy(&buf[i],&fchar[noffset],tocopy); + i+=tocopy; + tfd->offset+=tocopy; + } + return len; +} + + + +int openfile(struct block *ptr, char *filename) { + /* Locate fd */ + int fd=-1; + for(int k=0;kentries[rdiptr].Blockptr[i]]; + for(int j=0;jentries[j].name[0]!=0) { + if(strcmp(filename, db->entries[j].name)==0) + { + files[fd].inode=db->entries[j].inodenumber; + files[fd].offset=0; + return fd; + } + } + } + } + + /* If file doesn't exist, create it */ + int inode=getinode(ptr); + if (inode==-1) { + files[fd].used=false; + return -1; + } + itb->entries[inode].filesize=0; + itb->entries[inode].referencecount=1; + for (int i=0;i<12;i++) + itb->entries[inode].Blockptr[i]=0; + + addtode(ptr, inode, filename); + files[fd].inode=inode; + files[fd].offset=0; + return fd; +} + + +void createfile(struct block *ptr,char *filename, char *buf,int buflen) { + int fd=openfile(ptr,filename); + writefile(ptr,fd,buf,buflen); + closefile(ptr,fd); +} + + + +// adds a file to the directory entry +void addtode(struct block *ptr, int inode, char *filename) { + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + for(int i=0;i<12;i++) { + struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]]; + for(int j=0;jentries[j].name[0]==0) { + /* lets finish */ + strncpy(db->entries[j].name,filename,124); + db->entries[j].inodenumber=inode; + msync(&db->entries[j],sizeof(DirectoryEntry),MS_SYNC); + return; + } + } + } +} + + +// return the first free node in the InodeTable. Marks that inode as used. +int getinode(struct block *ptr) { + for(int i=0;iFreeBlockCount=NUMBLOCK-5; + sb->FreeInodeCount=NUMINODES-1; + sb->NumberofInodes=NUMINODES; + sb->NumberofBlocks=NUMBLOCK; + sb->RootDirectoryInode=0; + sb->blocksize=BLOCKSIZE; + } + { + struct GroupBlock * gb=(struct GroupBlock *) &ptr[1]; + gb->BlockBitmapBlock=2; + gb->InodeBitmapBlock=3; + gb->InodeTableBlock=4; + gb->GroupFreeBlockCount=NUMBLOCK-5; + gb->GroupFreeInodeCount=NUMINODES-1; + } + { + struct BlockBitmap * bb=(struct BlockBitmap *) &ptr[2]; + //memset(bb, 0, sizeof(BlockBitmap)); + for(int i=0;i<(5+12);i++) { + bb->blocks[i/8]=bb->blocks[i/8]|(1<<(i%8)); + } + } + { + struct InodeBitmap * ib=(struct InodeBitmap *) &ptr[3]; + //memset(ib, 0, sizeof(InodeBitmap)); + ib->inode[0]=1; + } + { + struct InodeBlock * itb=(struct InodeBlock *) &ptr[4]; + + itb->entries[0].filesize=12*BLOCKSIZE; + for(int i=0;i<12;i++) + itb->entries[0].Blockptr[i]=i+5; // blocks 5 to 16 are RootDirectory entries + itb->entries[0].referencecount=0; + } + + int val=munmap(vptr,LENGTH); + dealloc(vptr); + if (val!=0) + printf("Error!\n"); + + printf("Disk created successfully!\n"); +} + + +void printdirectory(struct block *ptr) +{ + struct InodeBlock *itb=(struct InodeBlock *) &ptr[itbptr]; + + for(int i=0;i<12;i++) + { + struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]]; + + for(int j=0;jentries[j].name[0]!=0) + { + /* lets finish */ + //printf("%s %d\n",db->entries[j].name, db->entries[j].inodenumber); + printf("%s (inode %d) (%d bytes)\n",db->entries[j].name, db->entries[j].inodenumber, itb->entries[db->entries[j].inodenumber].filesize); + } + } + } + + //printf("end of printdirectory\n"); +} + +// prints the contents of the file with filename "filename" +void printfile(char *filename, struct block *ptr) +{ + printf("=== BEGIN of %s ===\n", filename); + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + for(int i=0;i<12;i++) { + struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]]; + for(int j=0;jentries[j].name[0]!=0) { + if(strcmp(filename,db->entries[j].name)==0) { + /* Found file */ + int inode=db->entries[j].inodenumber; + + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + for(int i=0;i<((itb->entries[inode].filesize+BLOCKSIZE-1)/BLOCKSIZE);i++) { + struct block *b=&ptr[itb->entries[inode].Blockptr[i]]; + write(0,b,BLOCKSIZE); + } + } + } + } + } + printf("\n=== END of %s ===\n", filename); +} + + +void printinodeblock(struct block *ptr) +{ + struct InodeBlock *itb=(struct InodeBlock *) &ptr[itbptr]; + + for (int i=0; ientries[i]; + printf("inode %d: (filesize %d), (referencecount %d)\n", i, inode.filesize, inode.referencecount); + } +} + + diff --git a/Repair/RepairCompiler/MCC/Runtime/file.h b/Repair/RepairCompiler/MCC/Runtime/file.h new file mode 100755 index 0000000..1dc3436 --- /dev/null +++ b/Repair/RepairCompiler/MCC/Runtime/file.h @@ -0,0 +1,104 @@ +#ifndef FILE_H +#define FILE_H + +#define BLOCKSIZE 8192 +#define NUMBLOCK 1024 +#define LENGTH BLOCKSIZE*NUMBLOCK +#define NUMINODES BLOCKSIZE/56 +#define NUMFILES 100 + +struct block { + char array[BLOCKSIZE]; +}; + + +struct SuperBlock { + int FreeBlockCount; + int FreeInodeCount; + int NumberofBlocks; + int NumberofInodes; + int RootDirectoryInode; + int blocksize; +}; + + +struct GroupBlock { + int BlockBitmapBlock; + int InodeBitmapBlock; + int InodeTableBlock; + int GroupFreeBlockCount; + int GroupFreeInodeCount; +}; + + +struct BlockBitmap { + char blocks[NUMBLOCK/8+1]; +}; + + +struct InodeBitmap { + char inode[NUMINODES/8+1]; +}; + + +struct Inode { + int filesize; + int Blockptr[12]; + int referencecount; +}; + + +//the inode table +struct InodeBlock { + struct Inode entries[NUMINODES]; +}; + + +#define DIRECTORYENTRYSIZE 128 +struct DirectoryEntry { + char name[124]; + int inodenumber; +}; + + + +struct DirectoryBlock { + struct DirectoryEntry entries[BLOCKSIZE/128]; +}; + + + + + +void createdisk(); +void createfile(struct block *ptr,char *filename, char *buf,int buflen); +void addtode(struct block *ptr, int inode, char * filename); +int getinode(struct block *ptr); +int getblock(struct block * ptr); + +void removefile(char *filename, struct block *ptr); +void createlink(struct block *ptr,char *filename, char *linkname); +struct block * chmountdisk(char *filename); +void chunmountdisk(struct block *vptr); +struct block * mountdisk(char *filename); +void unmountdisk(struct block *vptr); +void closefile(struct block *ptr, int fd); +bool writefile(struct block *ptr, int fd, char *s); +int writefile(struct block *ptr, int fd, char *s, int len); +char readfile(struct block *ptr, int fd); +int readfile(struct block *ptr, int fd, char *buf, int len); +int openfile(struct block *ptr, char *filename); + +void printdirectory(struct block *ptr); +void printfile(char *filename, struct block *ptr); +void printinodeblock(struct block* ptr); + + +#define MAXFILES 300 +struct filedesc { + int inode; + int offset; + bool used; +}; +#endif + -- 2.34.1