19 #include "Hashtable.h"
25 struct filedesc files[MAXFILES];
26 struct InodeBitmap ib;
27 struct BlockBitmap bb;
29 int bbbptr; // pointer to the BlockBitmap block
30 int ibbptr; // pointer to the InodeBlock block
31 int itbptr; // pointer to the InodeTable block
32 int rdiptr; // pointer to the RootDirectoryInode block
34 struct InodeBitmap* sc_ib;
35 struct BlockBitmap* sc_bb;
36 struct InodeBlock* sc_it;
42 #include "SimpleHash.h"
44 int testinode(int i) {
47 temp = sc_ib->inode[i/8]&(1<<(i%8));
48 return temp == 0 ? 0 : 1;
51 int testblock(int i) {
54 temp = sc_bb->blocks[i/8]&(1<<(i%8));
55 return temp == 0 ? 0 : 1;
58 void assertvalidmemory(int low, int high) {
59 typemap *tm=exportmodel->gettypemap();
60 assert(tm->assertvalidmemory((void*) low, (void*) high));
63 unsigned long selfcheck2(struct block* d) {
65 struct timeval begin,end;
67 gettimeofday(&begin,NULL);
69 #include "RepairCompiler/MCC/test2.cc"
71 gettimeofday(&end,NULL);
72 t=(end.tv_sec-begin.tv_sec)*1000000+end.tv_usec-begin.tv_usec;
76 void selfcheck(struct block* diskptr) {
78 /* get time information for statistics */
79 struct timeval begin,end;
81 gettimeofday(&begin,NULL);
84 /* hand written data structure consistency */
86 struct SuperBlock* sb = (struct SuperBlock*)&diskptr[0];
87 struct GroupBlock* gb = (struct GroupBlock*)&diskptr[1];
89 int numblocks = sb->NumberofBlocks;
90 int numinodes = sb->NumberofInodes;
92 SimpleHash* hash_inodeof = new SimpleHash(1000); // estimation of the number of files!
93 SimpleHash* hash_contents = new SimpleHash(1000); // contents
94 SimpleList* list_inodes = new SimpleList();
95 SimpleList* list_blocks = new SimpleList();
99 // check bitmap consistency with superblock, groupblock, inotetableblock
100 // inodebitmapblock, blockbitmapblock, rootidrectoryinode
102 sc_bbbptr = gb->BlockBitmapBlock;
103 sc_ibbptr = gb->InodeBitmapBlock;
104 sc_itbptr = gb->InodeTableBlock;
105 sc_rdiptr = sb->RootDirectoryInode;
107 // constraint 8: automatic...
108 // constraint 9: automatic...
111 if (sc_itbptr < numblocks) {
112 sc_it = (InodeBlock*)&diskptr[sc_itbptr];
118 if (sc_ibbptr < numblocks) {
119 sc_ib = (InodeBitmap*)&diskptr[sc_ibbptr];
125 if (sc_bbbptr < numblocks) {
126 sc_bb = (BlockBitmap*)&diskptr[sc_bbbptr];
134 assert(testblock(0)); // superblock
143 assert(testblock(1)); // groupblock
145 // building list_blocks
152 assert(testblock(sc_itbptr));
154 // building list_blocks
155 list_blocks->add(sc_itbptr);
161 assert(testblock(sc_ibbptr));
163 // building list_blocks
164 list_blocks->add(sc_ibbptr);
170 assert(testblock(sc_bbbptr));
172 // building list_blocks
173 list_blocks->add(sc_bbbptr);
176 // build inodeof and contents
177 if (sb->RootDirectoryInode < numinodes) {
178 int dinode = sb->RootDirectoryInode;
180 // building list_inodes
181 list_inodes->add(dinode);
183 for (int k = 0 ; k <= 11 ; k++) {
185 int block = sc_it->entries[dinode].Blockptr[k];
188 hash_contents->add(dinode, block);
189 list_blocks->add(block);
192 if (block < numblocks) {
194 DirectoryBlock* db = (DirectoryBlock*)&diskptr[block];
196 for (int j = 0; j < sb->blocksize/128 ; j++) {
198 DirectoryEntry* de = (DirectoryEntry*)&db->entries[j];
200 if (de->inodenumber < numinodes) {
201 // add <de, de.inodenumber> to inodeof
202 hash_inodeof->add((int)de, de->inodenumber);
205 if (de->inodenumber < numinodes && de->inodenumber != 0) {
208 list_inodes->add(de->inodenumber);
210 for (int j2 = 0 ; j2 <= 11 ; j2++) {
211 int block2 = sc_it->entries[de->inodenumber].Blockptr[j2];
213 hash_contents->add(de->inodenumber, block2);
214 if (block2 < numblocks) {
215 list_blocks->add(block2);
227 // rule 6 and rule 11: rootdirectoryinode
228 if (sb->RootDirectoryInode < numinodes) {
229 int inode = sb->RootDirectoryInode;
232 assert(testinode(inode));
234 int filesize = sc_it->entries[inode].filesize;
236 for (int j = 0; j <= 11; j++) {
237 int block2 = sc_it->entries[inode].Blockptr[j];
239 // TBD: needs to actual store state because
240 // there could be duplicate numbers and they
241 // shouldn't be double counted
245 if (block2 < numblocks) {
247 assert(testblock(block2));
250 //printf("%d - %d %d %d\n", inode, j, block2, hash_contents->countdata(block2));
251 assert(hash_contents->countdata(block2)==1);
257 assert(filesize <= (contents*8192));
260 assert(sc_it->entries[inode].referencecount == hash_inodeof->countdata(inode));
264 if (sb->RootDirectoryInode < numinodes) {
265 int dinode = sb->RootDirectoryInode;
267 for (int j = 0; j < sb->blocksize/128 ; j++) {
268 for (int k = 0 ; k <= 11 ; k++) {
269 int block = sc_it->entries[dinode].Blockptr[k];
270 if (block < numblocks) {
271 DirectoryBlock* db = (DirectoryBlock*)&diskptr[block];
272 DirectoryEntry* de = (DirectoryEntry*)&db->entries[j];
274 int inode = de->inodenumber;
275 if (inode < numinodes && inode != 0) {
278 assert(testinode(inode));
281 int filesize = sc_it->entries[inode].filesize;
283 for (int j2 = 0; j2 <= 11; j2++) {
284 int block2 = sc_it->entries[inode].Blockptr[j2];
290 if (block2 < numblocks) {
292 assert(testblock(block2));
295 assert(hash_contents->countdata(block2)==1);
299 assert(filesize <= (contents*8192));
302 assert(sc_it->entries[inode].referencecount == hash_inodeof->countdata(inode));
310 // interesting question is going to be how to deal with 7 and 8
311 // actually it turns out that the constraints bound to rules 7 and 8 are
312 // easy... its just that creating the lists for 7 and 8 is a little tricky...
313 // 7 can easily piggyback on the creation of inodeof/contents... it fits quite
314 // nicely into that traversal... same goes for 8
317 for (int i = 0 ; i < numinodes ; i++) {
318 if (!list_inodes->contains(i)) {
321 printf("<bad inode,%d>", i);
322 assert(testinode(i)==0);
328 for (int i = 0 ; i < numblocks ; i++) {
329 if (!list_blocks->contains(i)) {
332 printf("<bad block,%d>", i);
333 assert(testblock(i)==0);
340 gettimeofday(&end,NULL);
341 t=(end.tv_sec-begin.tv_sec)*1000000+end.tv_usec-begin.tv_usec;
343 printf("\npassed tests in %ld u-seconds!\n", t);
349 int main(int argc, char **argv)
352 for(int i=0;i<MAXFILES;i++)
357 printf("Filesystem Repair:\n\tusage: main [0..9]\n\n");
358 printf("\t 0 : creates disk\n");
359 printf("\t 1 : mount disk, creates files and writes test data\n");
361 printf("\t 3 : inserts errors to break specs\n");
380 /* mounts the disk, creates NUMFILES files, and writes "buf" in each file
382 struct block * ptr=mountdisk("disk");
384 for(int i=0; i<NUMFILES; i++) {
386 sprintf(filename,"file_%d",i);
387 openfile(ptr,filename);
390 for(int j=0; j<90; j++) {
391 for(int i=0; i<NUMFILES; i++) {
392 char *buf="01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123";
393 writefile(ptr,i,buf,122);
397 for(int i=0; i<NUMFILES; i++) {
402 printinodeblock(ptr);
410 struct block * ptr=mountdisk("disk");
412 initializeanalysis();
415 addmapping(dstring,ptr,"Disk");
418 printinodeblock(ptr);
421 unsigned long time = 0;
422 for (int i = 0; i < 50; i++) {
426 printf("\ninterpreted: %u us\n", (time/50));
434 struct block * ptr=mountdisk("disk");
436 initializeanalysis();
439 addmapping(dstring,ptr,"Disk");
442 printinodeblock(ptr);
454 struct block * ptr=mountdisk("disk");
456 initializeanalysis();
459 addmapping(dstring,ptr,"Disk");
462 printinodeblock(ptr);
466 unsigned long time = 0;
467 for (int i = 0; i < 50; i++) {
468 time += selfcheck2(ptr);
471 printf("\ncompiled: %u us\n", (time/50));
479 // insert errors that break the specs
481 struct block * ptr=mountdisk("disk");
482 initializeanalysis();
483 Hashtable *env=exportmodel->gethashtable();
485 addmapping(dstring,ptr,"Disk");
487 // insert errors that break the specs
495 // insert errors that do not break the specs
497 struct block * ptr=mountdisk("disk");
498 initializeanalysis();
499 Hashtable *env=exportmodel->gethashtable();
501 addmapping(dstring,ptr,"Disk");
503 // insert errors that do not break the specs
512 // prints the directory structure, and prints the contents of each file
513 struct block * ptr=mountdisk("disk");
515 for(int i=1; i<NUMFILES; i++) {
517 sprintf(filename,"file_%d",i);
518 printfile(filename,ptr);
525 // the same as "case '1'" only that the files are accessed in reversed order
526 struct block * ptr=mountdisk("disk");
527 for(int i=NUMFILES; i>1; i--) {
529 sprintf(filename,"file_%d",i);
530 openfile(ptr,filename);
532 for(int j=0; j<90; j++) {
533 for(int i=NUMFILES; i>1; i--) {
534 char *buf="01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123";
535 writefile(ptr,i,buf,122);
538 for(int i=NUMFILES; i>1; i--) {
546 struct block * ptr=mountdisk("disk");
547 for(int i=NUMFILES; i>=0; i--) {
549 sprintf(filename,"file_%d",i);
550 openfile(ptr,filename);
553 for(int j=0;j<6000;j++) {
554 for(int i=NUMFILES; i>=0; i--) {
556 int len=sprintf(name, "%d ",i);
557 writefile(ptr,i,name,len);
560 for(int i=NUMFILES; i>=0; i--) {
563 for(int i=NUMFILES; i>=0; i--) {
565 sprintf(filename,"file_%d",i);
566 openfile(ptr,filename);
569 for(int j=0;j<400;j++) {
570 for(int i=NUMFILES; i>=0; i--) {
573 int len=sprintf(name, "%d ",i);
574 readfile(ptr,i,name,len);
575 sscanf(name, "%d ", &l);
577 printf("ERROR in benchmark\n");
581 for(int i=NUMFILES; i>=0; i--) {
591 struct block * ptr=chmountdisk("disk");
592 initializeanalysis();
593 Hashtable *env=exportmodel->gethashtable();
595 addmapping(dstring,ptr,"Disk");
600 struct block * ptr=mountdisk("disk");
601 for(int i=NUMFILES; i>=0; i--) {
603 sprintf(filename,"file_%d",i);
604 openfile(ptr,filename);
606 for(int j=0; j<6000; j++) {
607 for(int i=NUMFILES; i>=0; i--) {
609 int len=sprintf(name, "%d ",i);
610 writefile(ptr,i,name,len);
613 for(int i=NUMFILES; i>=0; i--) {
616 for(int i=NUMFILES; i>=0; i--) {
618 sprintf(filename,"file_%d",i);
619 openfile(ptr,filename);
621 for(int j=0;j<400;j++) {
622 for(int i=NUMFILES; i>=0; i--) {
625 int len=sprintf(name, "%d ",i);
626 readfile(ptr,i,name,len);
627 sscanf(name, "%d ", &l);
629 printf("ERROR in benchmark\n");
633 for(int i=NUMFILES; i>=0; i--) {
640 for(int i=0;i<MAXFILES;i++)
644 struct block * ptr=mountdisk("disk");
646 for(int i=0; i<NUMFILES; i++)
649 sprintf(filename,"file_%d", i);
650 openfile(ptr,filename);
653 for(int i=0; i<NUMFILES; i++)
656 sprintf(buf,"This is file_%d.", i);
657 writefile(ptr,i,buf,strlen(buf));
661 createlink(ptr, "file_1", "link_1");
662 createlink(ptr, "file_1", "link_2");
664 removefile("file_1", ptr);
666 int fd = openfile(ptr, "new");
667 writefile(ptr, fd, "new", 3);
669 printfile("file_1", ptr);
670 printfile("link_1", ptr);
671 printfile("link_2", ptr);
673 for(int i=0; i<NUMFILES; i++)
685 struct block * chmountdisk(char *filename) {
686 int fd=open(filename,O_CREAT|O_RDWR);
687 struct block *ptr=(struct block *) mmap(NULL,LENGTH,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_SHARED,fd,0);
693 void chunmountdisk(struct block *vptr) {
694 int val=munmap(vptr,LENGTH);
701 // mounts the disk from the file "filename"
702 struct block * mountdisk(char *filename) {
703 int fd=open(filename,O_CREAT|O_RDWR);
704 struct block *ptr=(struct block *) mmap(NULL,LENGTH,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_SHARED,fd,0);
707 if ((int)ptr == -1) {
708 perror("mountdisk\0");
713 struct SuperBlock *sb=(struct SuperBlock *) &ptr[0];
714 struct GroupBlock *gb=(struct GroupBlock *) &ptr[1];
715 bbbptr=gb->BlockBitmapBlock;
716 ibbptr=gb->InodeBitmapBlock;
717 itbptr=gb->InodeTableBlock;
718 rdiptr=sb->RootDirectoryInode;
720 struct InodeBitmap *ibb=(struct InodeBitmap *) &ptr[ibbptr];
721 for(int i=0;i<(NUMINODES/8+1);i++)
722 ib.inode[i]=ibb->inode[i];
724 struct BlockBitmap *bbb=(struct BlockBitmap *) &ptr[bbbptr];
725 for(int i=0;i<(NUMBLOCK/8+1);i++)
726 bb.blocks[i]=bbb->blocks[i];
728 printf("Disk mounted successfully from the file %s\n", filename);
736 void unmountdisk(struct block *vptr) {
737 struct InodeBitmap *ibb=(struct InodeBitmap *) &vptr[ibbptr];
738 for(int i=0;i<(NUMINODES/8+1);i++)
739 ibb->inode[i]=ib.inode[i];
741 struct BlockBitmap *bbb=(struct BlockBitmap *) &vptr[bbbptr];
742 for(int i=0;i<(NUMBLOCK/8+1);i++)
743 bbb->blocks[i]=bb.blocks[i];
744 int val=munmap(vptr,LENGTH);
750 void removefile(char *filename, struct block *ptr) {
751 struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
752 for(int i=0;i<12;i++) {
753 struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]];
754 for(int j=0;j<BLOCKSIZE/128;j++) {
755 if (db->entries[j].name[0]!=0) {
756 if(strcmp(filename,db->entries[j].name)==0) {
758 db->entries[j].name[0]=0; //Delete entry
759 int inode=db->entries[j].inodenumber;
760 db->entries[j].inodenumber=0;
762 struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
763 itb->entries[inode].referencecount--;
765 if (itb->entries[inode].referencecount==0) {
766 for(int i=0;i<((itb->entries[inode].filesize+BLOCKSIZE-1)/BLOCKSIZE);i++) {
767 int blocknum=itb->entries[inode].Blockptr[i];
768 bb.blocks[blocknum/8]^=(1<<(blocknum%8));
770 ib.inode[inode/8]^=(1<<(inode%8));
779 void createlink(struct block *ptr,char *filename, char *linkname) {
780 struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
781 for(int i=0;i<12;i++) {
782 struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]];
783 for(int j=0;j<BLOCKSIZE/DIRECTORYENTRYSIZE;j++) {
784 if (db->entries[j].name[0]!=0) {
785 if(strcmp(filename,db->entries[j].name)==0) {
787 int inode=db->entries[j].inodenumber;
788 struct InodeBlock * itb=(struct InodeBlock *) &ptr[4];
789 itb->entries[inode].referencecount++;
790 addtode(ptr, inode, linkname);
798 void closefile(struct block *ptr, int fd) {
799 struct InodeBlock * itb=(struct InodeBlock *) &ptr[4];
802 msync(&itb->entries[fd],sizeof(DirectoryEntry),MS_SYNC);
803 files[fd].used=false;
807 bool writefile(struct block *ptr, int fd, char *s) {
808 return (writefile(ptr,fd,s,1)==1);
812 int writefile(struct block *ptr, int fd, char *s, int len) {
813 struct filedesc *tfd=&files[fd];
814 if (tfd->used==false)
816 struct InodeBlock * itb=(struct InodeBlock *) &ptr[4];
817 int filelen=itb->entries[tfd->inode].filesize;
818 if ((12*BLOCKSIZE-tfd->offset)<len)
819 len=12*BLOCKSIZE-tfd->offset;
820 for(int i=0;i<len;i++) {
821 int nbuffer=tfd->offset/BLOCKSIZE;
822 int noffset=tfd->offset%BLOCKSIZE;
823 if (tfd->offset>=filelen) {
825 int bptr=getblock(ptr);
827 if (itb->entries[files[fd].inode].filesize<files[fd].offset)
828 itb->entries[files[fd].inode].filesize=files[fd].offset;
831 itb->entries[tfd->inode].Blockptr[nbuffer]=bptr;
834 int block=itb->entries[tfd->inode].Blockptr[nbuffer];
835 char *fchar=(char *)&ptr[block];
837 if (tocopy>(BLOCKSIZE-noffset))
838 tocopy=BLOCKSIZE-noffset;
839 memcpy(&fchar[noffset],&s[i],tocopy);
840 msync(&fchar[noffset],tocopy,MS_SYNC);
844 if (itb->entries[files[fd].inode].filesize<files[fd].offset)
845 itb->entries[files[fd].inode].filesize=files[fd].offset;
850 // reads one char from the file fd and returns it
851 char readfile(struct block *ptr, int fd) {
853 if (readfile(ptr,fd,array,1)==1)
859 // reads len chars from file fd (file system *ptr) and returns them in buf
860 int readfile(struct block *ptr, int fd, char *buf, int len) {
861 struct filedesc *tfd=&files[fd];
862 if (tfd->used==false)
865 struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
866 int filelen=itb->entries[tfd->inode].filesize;
868 // if there are fewer than len chars left, read until the end
869 if ((filelen-tfd->offset)<len)
870 len=filelen-tfd->offset;
872 for(int i=0;i<len;) {
873 int nbuffer=tfd->offset/BLOCKSIZE;
874 int noffset=tfd->offset%BLOCKSIZE;
875 int block=itb->entries[tfd->inode].Blockptr[nbuffer];
876 char *fchar=(char *)&ptr[block];
878 if (tocopy>(BLOCKSIZE-noffset))
879 tocopy=BLOCKSIZE-noffset;
880 memcpy(&buf[i],&fchar[noffset],tocopy);
889 int openfile(struct block *ptr, char *filename) {
892 for(int k=0;k<MAXFILES;k++) {
900 if (fd==-1) return fd;
902 /* Check to see if file exists*/
903 struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
904 for(int i=0;i<12;i++)
906 struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]];
907 for(int j=0;j<BLOCKSIZE/DIRECTORYENTRYSIZE;j++)
909 if (db->entries[j].name[0]!=0) {
910 if(strcmp(filename, db->entries[j].name)==0)
912 files[fd].inode=db->entries[j].inodenumber;
920 /* If file doesn't exist, create it */
921 int inode=getinode(ptr);
923 files[fd].used=false;
926 itb->entries[inode].filesize=0;
927 itb->entries[inode].referencecount=1;
928 for (int i=0;i<12;i++)
929 itb->entries[inode].Blockptr[i]=0;
931 addtode(ptr, inode, filename);
932 files[fd].inode=inode;
938 void createfile(struct block *ptr,char *filename, char *buf,int buflen) {
939 int fd=openfile(ptr,filename);
940 writefile(ptr,fd,buf,buflen);
946 // adds a file to the directory entry
947 void addtode(struct block *ptr, int inode, char *filename) {
948 struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
949 for(int i=0;i<12;i++) {
950 struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]];
951 for(int j=0;j<BLOCKSIZE/DIRECTORYENTRYSIZE;j++) {
952 if (db->entries[j].name[0]==0) {
954 strncpy(db->entries[j].name,filename,124);
955 db->entries[j].inodenumber=inode;
956 msync(&db->entries[j],sizeof(DirectoryEntry),MS_SYNC);
964 // return the first free node in the InodeTable. Marks that inode as used.
965 int getinode(struct block *ptr) {
966 for(int i=0;i<NUMINODES;i++) {
967 if (!(ib.inode[i/8]&(1<<(i%8)))) {
968 ib.inode[i/8]=ib.inode[i/8]|(1<<(i%8));
976 int getblock(struct block * ptr) {
977 for(int i=0;i<NUMBLOCK;i++) {
978 if (!(bb.blocks[i/8]&(1<<(i%8)))) {
979 bb.blocks[i/8]=bb.blocks[i/8]|(1<<(i%8));
990 int blocksize=BLOCKSIZE;
991 int numblocks=NUMBLOCK;
993 int fd=open("disk",O_CREAT|O_RDWR|O_TRUNC, S_IREAD|S_IWRITE);
995 // creates numblocks and initializes them with 0
996 char *buf=(char *)calloc(1,blocksize);
997 for(int i=0;i<numblocks;i++) {
998 write(fd,buf,blocksize);
1002 // maps the file 'disk' into memory
1003 void *vptr=mmap(NULL,LENGTH,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_SHARED,fd,0);
1005 // added by dan roy for debugging
1006 if ((int)vptr == -1) {
1007 perror("createdisk()\0");
1012 struct block *ptr=(struct block *)vptr;
1014 struct SuperBlock * sb=(struct SuperBlock*) &ptr[0];
1015 sb->FreeBlockCount=NUMBLOCK-5;
1016 sb->FreeInodeCount=NUMINODES-1;
1017 sb->NumberofInodes=NUMINODES;
1018 sb->NumberofBlocks=NUMBLOCK;
1019 sb->RootDirectoryInode=0;
1020 sb->blocksize=BLOCKSIZE;
1023 struct GroupBlock * gb=(struct GroupBlock *) &ptr[1];
1024 gb->BlockBitmapBlock=2;
1025 gb->InodeBitmapBlock=3;
1026 gb->InodeTableBlock=4;
1027 gb->GroupFreeBlockCount=NUMBLOCK-5;
1028 gb->GroupFreeInodeCount=NUMINODES-1;
1031 struct BlockBitmap * bb=(struct BlockBitmap *) &ptr[2];
1032 //memset(bb, 0, sizeof(BlockBitmap));
1033 for(int i=0;i<(5+12);i++) {
1034 bb->blocks[i/8]=bb->blocks[i/8]|(1<<(i%8));
1038 struct InodeBitmap * ib=(struct InodeBitmap *) &ptr[3];
1039 //memset(ib, 0, sizeof(InodeBitmap));
1043 struct InodeBlock * itb=(struct InodeBlock *) &ptr[4];
1045 itb->entries[0].filesize=12*BLOCKSIZE;
1046 for(int i=0;i<12;i++)
1047 itb->entries[0].Blockptr[i]=i+5; // blocks 5 to 16 are RootDirectory entries
1048 itb->entries[0].referencecount=0;
1051 int val=munmap(vptr,LENGTH);
1055 printf("Disk created successfully!\n");
1059 void printdirectory(struct block *ptr)
1061 struct InodeBlock *itb=(struct InodeBlock *) &ptr[itbptr];
1063 for(int i=0;i<12;i++)
1065 struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]];
1067 for(int j=0;j<BLOCKSIZE/DIRECTORYENTRYSIZE;j++) {
1068 if (db->entries[j].name[0]!=0)
1071 //printf("%s %d\n",db->entries[j].name, db->entries[j].inodenumber);
1072 printf("%s (inode %d) (%d bytes)\n",db->entries[j].name, db->entries[j].inodenumber, itb->entries[db->entries[j].inodenumber].filesize);
1077 //printf("end of printdirectory\n");
1080 // prints the contents of the file with filename "filename"
1081 void printfile(char *filename, struct block *ptr)
1083 printf("=== BEGIN of %s ===\n", filename);
1084 struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
1085 for(int i=0;i<12;i++) {
1086 struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]];
1087 for(int j=0;j<BLOCKSIZE/DIRECTORYENTRYSIZE;j++) {
1088 if (db->entries[j].name[0]!=0) {
1089 if(strcmp(filename,db->entries[j].name)==0) {
1091 int inode=db->entries[j].inodenumber;
1093 struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
1094 for(int i=0;i<((itb->entries[inode].filesize+BLOCKSIZE-1)/BLOCKSIZE);i++) {
1095 struct block *b=&ptr[itb->entries[inode].Blockptr[i]];
1096 write(0,b,BLOCKSIZE);
1102 printf("\n=== END of %s ===\n", filename);
1106 void printinodeblock(struct block *ptr)
1108 struct InodeBlock *itb=(struct InodeBlock *) &ptr[itbptr];
1110 for (int i=0; i<NUMINODES; i++)
1112 Inode inode = itb->entries[i];
1113 printf("inode %d: (filesize %d), (referencecount %d)\n", i, inode.filesize, inode.referencecount);