Fix grammar and Sum bug.
[repair.git] / Repair / RepairInterpreter / file.cc
1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <string.h>
4 #include <fcntl.h>
5 #include <unistd.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <sys/mman.h>
9 #include "file.h"
10 extern "C" {
11 #include "test.h"
12 }
13 #include "Hashtable.h"
14 #include "model.h"
15 #include "element.h"
16
17 char *dstring="d\0";
18 struct filedesc files[MAXFILES];
19 struct InodeBitmap ib;
20 struct BlockBitmap bb;
21 int bbbptr,ibbptr,itbptr,rdiptr;
22 int main(int argc, char **argv) {
23   for(int i=0;i<MAXFILES;i++)
24     files[i].used=false;
25   switch(argv[1][0]) {
26   case '0': createdisk();
27     return 1;
28   case '1': {
29     struct block * ptr=mountdisk("disk");
30     for(int i=0;i<145;i++) {
31       char filename[10];
32       sprintf(filename,"fil%d",i);
33       openfile(ptr,filename);
34     }
35     for(int j=0;j<90;j++) {
36       for(int i=0;i<145;i++) {
37         char *buf="01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123";
38         writefile(ptr,i,buf,122);
39       }
40     }
41     for(int i=0;i<145;i++) {
42       closefile(ptr,i);
43     }
44     unmountdisk(ptr);
45     break;
46   }
47   case '2': {
48     struct block * ptr=chmountdisk("disk");
49     initializeanalysis();
50     Hashtable *env=exportmodel->gethashtable();
51     alloc(ptr,LENGTH);
52     addmapping(dstring,ptr,"Disk");
53     //    env->put(dstring,new Element(ptr,exportmodel->getstructure("Disk")));//should be of badstruct
54     doanalysis();
55     dealloc(ptr);
56     chunmountdisk(ptr);
57     break;
58   }
59   case '3': {
60     struct block * ptr=mountdisk("disk");
61     printdirectory(ptr);
62     for(int i=1;i<145;i++) {
63       char filename[10];
64       sprintf(filename,"fil%d",i);
65       printfile(filename,ptr);
66     }
67     unmountdisk(ptr);
68     break;
69   }
70   case '4': {
71     struct block * ptr=mountdisk("disk");
72     for(int i=145;i>1;i--) {
73       char filename[10];
74       sprintf(filename,"fil%d",i);
75       openfile(ptr,filename);
76     }
77     for(int j=0;j<90;j++) {
78       for(int i=145;i>1;i--) {
79         char *buf="01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123";
80         writefile(ptr,i,buf,122);
81       }
82     }
83     for(int i=145;i>1;i--) {
84       closefile(ptr,i);
85     }
86     unmountdisk(ptr);
87     break;
88   }
89   case '5': {
90     struct block * ptr=mountdisk("disk");
91     for(int i=145;i>=0;i--) {
92       char filename[10];
93       sprintf(filename,"fil%d",i);
94       openfile(ptr,filename);
95     }
96     for(int j=0;j<6000;j++) {
97       for(int i=145;i>=0;i--) {
98         char name[10];
99         int len=sprintf(name, "%d ",i);
100         writefile(ptr,i,name,len);
101       }
102     }
103     for(int i=145;i>=0;i--) {
104       closefile(ptr,i);
105     }
106     for(int i=145;i>=0;i--) {
107       char filename[10];
108       sprintf(filename,"fil%d",i);
109       openfile(ptr,filename);
110     }
111     for(int j=0;j<400;j++) {
112       for(int i=145;i>=0;i--) {
113         int l=0;
114         char name[10];
115         int len=sprintf(name, "%d ",i);
116         readfile(ptr,i,name,len);
117         sscanf(name, "%d ", &l);
118         if (l!=i) {
119           printf("ERROR in benchmark\n");
120         }
121       }
122     }
123     for(int i=145;i>=0;i--) {
124       closefile(ptr,i);
125     }
126     unmountdisk(ptr);
127   }
128   break;
129   case '6': {
130     {
131       struct block * ptr=chmountdisk("disk");
132       initializeanalysis();
133       Hashtable *env=exportmodel->gethashtable();
134       alloc(ptr,LENGTH);
135       addmapping(dstring,ptr,"Disk");
136       doanalysis();
137       dealloc(ptr);
138       chunmountdisk(ptr);
139     }
140     struct block * ptr=mountdisk("disk");
141     for(int i=145;i>=0;i--) {
142       char filename[10];
143       sprintf(filename,"fil%d",i);
144       openfile(ptr,filename);
145     }
146     for(int j=0;j<6000;j++) {
147       for(int i=145;i>=0;i--) {
148         char name[10];
149         int len=sprintf(name, "%d ",i);
150         writefile(ptr,i,name,len);
151       }
152     }
153     for(int i=145;i>=0;i--) {
154       closefile(ptr,i);
155     }
156     for(int i=145;i>=0;i--) {
157       char filename[10];
158       sprintf(filename,"fil%d",i);
159       openfile(ptr,filename);
160     }
161     for(int j=0;j<400;j++) {
162       for(int i=145;i>=0;i--) {
163         int l=0;
164         char name[10];
165         int len=sprintf(name, "%d ",i);
166         readfile(ptr,i,name,len);
167         sscanf(name, "%d ", &l);
168         if (l!=i) {
169           printf("ERROR in benchmark\n");
170         }
171       }
172     }
173     for(int i=145;i>=0;i--) {
174       closefile(ptr,i);
175     }
176     unmountdisk(ptr);
177   }
178   }
179 }
180
181 struct block * chmountdisk(char *filename) {
182   int fd=open(filename,O_CREAT|O_RDWR);
183   struct block *ptr=(struct block *) mmap(NULL,LENGTH,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_SHARED,fd,0);
184   return ptr;
185 }
186
187 void chunmountdisk(struct block *vptr) {
188   int val=munmap(vptr,LENGTH);
189 }
190
191 struct block * mountdisk(char *filename) {
192   int fd=open(filename,O_CREAT|O_RDWR);
193   struct block *ptr=(struct block *) mmap(NULL,LENGTH,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_SHARED,fd,0);
194   struct SuperBlock *sb=(struct SuperBlock *) &ptr[0];
195   struct GroupBlock *gb=(struct GroupBlock *) &ptr[1];
196   bbbptr=gb->BlockBitmapBlock;
197   ibbptr=gb->InodeBitmapBlock;
198   itbptr=gb->InodeTableBlock;
199   rdiptr=sb->RootDirectoryInode;
200
201   struct InodeBitmap *ibb=(struct InodeBitmap *) &ptr[ibbptr];
202   for(int i=0;i<(NUMINODES/8+1);i++)
203     ib.inode[i]=ibb->inode[i];
204   struct BlockBitmap *bbb=(struct BlockBitmap *) &ptr[bbbptr];
205   for(int i=0;i<(NUMBLOCK/8+1);i++)
206     bb.blocks[i]=bbb->blocks[i];
207   return ptr;
208 }
209
210 void unmountdisk(struct block *vptr) {
211   struct InodeBitmap *ibb=(struct InodeBitmap *) &vptr[ibbptr];
212   for(int i=0;i<(NUMINODES/8+1);i++)
213     ibb->inode[i]=ib.inode[i];
214
215   struct BlockBitmap *bbb=(struct BlockBitmap *) &vptr[bbbptr];
216   for(int i=0;i<(NUMBLOCK/8+1);i++)
217     bbb->blocks[i]=bb.blocks[i];
218   int val=munmap(vptr,LENGTH);
219 }
220
221 void printdirectory(struct block *ptr) {
222   struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
223   for(int i=0;i<12;i++) {
224     struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]];
225     for(int j=0;j<BLOCKSIZE/128;j++) {
226       if (db->entries[j].name[0]!=0) {
227         /* lets finish */
228         printf("%s %d inode %d bytes\n",db->entries[j].name, db->entries[j].inodenumber,itb->entries[db->entries[j].inodenumber].filesize);
229       }
230     }
231   }
232 }
233
234 void printfile(char *filename, struct block *ptr) {
235   struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
236   for(int i=0;i<12;i++) {
237     struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]];
238     for(int j=0;j<BLOCKSIZE/128;j++) {
239       if (db->entries[j].name[0]!=0) {
240         if(strcmp(filename,db->entries[j].name)==0) {
241           /* Found file */
242           int inode=db->entries[j].inodenumber;
243
244           struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
245           for(int i=0;i<((itb->entries[inode].filesize+BLOCKSIZE-1)/BLOCKSIZE);i++) {
246             struct block *b=&ptr[itb->entries[inode].Blockptr[i]];
247             write(0,b,BLOCKSIZE);
248           }
249         }
250       }
251     }
252   }
253 }
254
255 void removefile(char *filename, struct block *ptr) {
256   struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
257   for(int i=0;i<12;i++) {
258     struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]];
259     for(int j=0;j<BLOCKSIZE/128;j++) {
260       if (db->entries[j].name[0]!=0) {
261         if(strcmp(filename,db->entries[j].name)==0) {
262           /* Found file */
263           db->entries[j].name[0]=0; //Delete entry
264           int inode=db->entries[j].inodenumber;
265           
266           struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
267           itb->entries[inode].referencecount--;
268
269           if (itb->entries[inode].referencecount==0) {
270             for(int i=0;i<((itb->entries[inode].filesize+BLOCKSIZE-1)/BLOCKSIZE);i++) {
271               int blocknum=itb->entries[inode].Blockptr[i];
272               bb.blocks[blocknum/8]^=(1<<(blocknum%8));
273             }
274             ib.inode[inode/8]^=(1<<(inode%8));
275           }
276         }
277       }
278     }
279   }
280 }
281
282 void createlink(struct block *ptr,char *filename, char *linkname) {
283   struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
284   for(int i=0;i<12;i++) {
285     struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]];
286     for(int j=0;j<BLOCKSIZE/128;j++) {
287       if (db->entries[j].name[0]!=0) {
288         if(strcmp(filename,db->entries[j].name)==0) {
289           /* Found file */
290           int inode=db->entries[j].inodenumber;
291           struct InodeBlock * itb=(struct InodeBlock *) &ptr[4];
292           itb->entries[inode].referencecount++;
293           addtode(ptr, inode, linkname);
294         }
295       }
296     }
297   }
298 }
299
300 void closefile(struct block *ptr, int fd) {
301   struct InodeBlock * itb=(struct InodeBlock *) &ptr[4];
302   
303
304   msync(&itb->entries[fd],sizeof(DirectoryEntry),MS_SYNC);
305   files[fd].used=false;
306 }
307
308 bool writefile(struct block *ptr, int fd, char *s) {
309   return (writefile(ptr,fd,s,1)==1);
310 }
311
312 int writefile(struct block *ptr, int fd, char *s, int len) {
313   struct filedesc *tfd=&files[fd];
314   if (tfd->used==false)
315     return -1;
316   struct InodeBlock * itb=(struct InodeBlock *) &ptr[4];
317   int filelen=itb->entries[tfd->inode].filesize;
318   if ((12*BLOCKSIZE-tfd->offset)<len)
319     len=12*BLOCKSIZE-tfd->offset;
320   for(int i=0;i<len;i++) {
321     int nbuffer=tfd->offset/BLOCKSIZE;
322     int noffset=tfd->offset%BLOCKSIZE;
323     if (tfd->offset>=filelen) {
324       if (noffset==0) {
325         int bptr=getblock(ptr);
326         if (bptr==-1) {
327           if (itb->entries[files[fd].inode].filesize<files[fd].offset)
328             itb->entries[files[fd].inode].filesize=files[fd].offset; 
329           return i;
330         }
331         itb->entries[tfd->inode].Blockptr[nbuffer]=bptr;
332       }
333     }
334     int block=itb->entries[tfd->inode].Blockptr[nbuffer];
335     char *fchar=(char *)&ptr[block];
336     int tocopy=len-i;
337     if (tocopy>(BLOCKSIZE-noffset))
338       tocopy=BLOCKSIZE-noffset;
339     memcpy(&fchar[noffset],&s[i],tocopy);
340     msync(&fchar[noffset],tocopy,MS_SYNC);
341     i+=tocopy;
342     tfd->offset+=tocopy;
343   }
344   if (itb->entries[files[fd].inode].filesize<files[fd].offset)
345     itb->entries[files[fd].inode].filesize=files[fd].offset;
346   return len;
347 }
348
349
350 char readfile(struct block *ptr, int fd) {
351   char array[1];
352   if (readfile(ptr,fd,array,1)==1)
353     return array[0];
354   else
355     return EOF;
356 }
357
358 int readfile(struct block *ptr, int fd, char *buf, int len) {
359   struct filedesc *tfd=&files[fd];
360   if (tfd->used==false)
361     return -1;
362
363   struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
364   int filelen=itb->entries[tfd->inode].filesize;
365   if ((filelen-tfd->offset)<len)
366     len=filelen-tfd->offset;
367   for(int i=0;i<len;) {
368     int nbuffer=tfd->offset/BLOCKSIZE;
369     int noffset=tfd->offset%BLOCKSIZE;
370     int block=itb->entries[tfd->inode].Blockptr[nbuffer];
371     char *fchar=(char *)&ptr[block];
372     int tocopy=len-i;
373     if (tocopy>(BLOCKSIZE-noffset))
374       tocopy=BLOCKSIZE-noffset;
375     memcpy(&buf[i],&fchar[noffset],tocopy);
376     i+=tocopy;
377     tfd->offset+=tocopy;
378   }
379   return len;
380 }
381
382 int openfile(struct block *ptr, char *filename) {
383   /* Locate fd */
384   int fd=-1;
385   for(int k=0;k<MAXFILES;k++) {
386     /* Found file */
387     if(!files[k].used) {
388       fd=k;
389       files[fd].used=true;
390       break;
391     }
392   }
393   if (fd==-1) return fd;
394
395   /* Check to see if file exists*/
396   struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
397   for(int i=0;i<12;i++) {
398     struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]];
399     for(int j=0;j<BLOCKSIZE/128;j++) {
400       if (db->entries[j].name[0]!=0) {
401         if(strcmp(filename,db->entries[j].name)==0) {
402           files[fd].inode=db->entries[j].inodenumber;
403           files[fd].offset=0;
404           return fd;
405         }
406       }
407     }
408   }
409   /* Create file */
410
411   int inode=getinode(ptr);
412   if (inode==-1) {
413     files[fd].used=false;
414     return -1;
415   }
416   itb->entries[inode].filesize=0;
417   itb->entries[inode].referencecount=1;
418
419   addtode(ptr, inode, filename);
420   files[fd].inode=inode;
421   files[fd].offset=0;
422   return fd;
423 }
424
425 void createfile(struct block *ptr,char *filename, char *buf,int buflen) {
426   int fd=openfile(ptr,filename);
427   writefile(ptr,fd,buf,buflen);
428   closefile(ptr,fd);
429 }
430
431 void addtode(struct block *ptr, int inode, char * filename) {
432   struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
433   for(int i=0;i<12;i++) {
434     struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]];
435     for(int j=0;j<BLOCKSIZE/128;j++) {
436       if (db->entries[j].name[0]==0) {
437         /* lets finish */
438         strncpy(db->entries[j].name,filename,124);
439         db->entries[j].inodenumber=inode;
440         msync(&db->entries[j],sizeof(DirectoryEntry),MS_SYNC);
441         return;
442       }
443     }
444   }
445 }
446
447 int getinode(struct block *ptr) {
448   for(int i=0;i<NUMINODES;i++) {
449     if (!(ib.inode[i/8]&(1<<(i%8)))) {
450       ib.inode[i/8]=ib.inode[i/8]|(1<<(i%8));
451       return i;
452     }
453   }
454   return -1;
455 }
456
457 int getblock(struct block * ptr) {
458   for(int i=0;i<NUMBLOCK;i++) {
459     if (!(bb.blocks[i/8]&(1<<(i%8)))) {
460       bb.blocks[i/8]=bb.blocks[i/8]|(1<<(i%8));
461       return i;
462     }
463   }
464   return -1;
465 }
466
467
468
469 void createdisk() {
470   int blocksize=BLOCKSIZE;
471   int numblocks=NUMBLOCK;
472   int fd=open("disk",O_CREAT|O_RDWR|O_TRUNC);
473   char *buf=(char *)calloc(1,blocksize);
474   for(int i=0;i<numblocks;i++) {
475     write(fd,buf,blocksize);
476   }
477   free(buf);
478   void *vptr=mmap(NULL,LENGTH,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_SHARED,fd,0);
479   struct block *ptr=(struct block *)vptr;
480   {
481     struct SuperBlock * sb=(struct SuperBlock*) &ptr[0];
482     sb->FreeBlockCount=BLOCKSIZE-5;
483     sb->FreeInodeCount=NUMINODES-1;
484     sb->NumberofInodes=NUMINODES;
485     sb->NumberofBlocks=NUMBLOCK;
486     sb->RootDirectoryInode=0;
487     sb->blocksize=BLOCKSIZE;
488   }
489   {
490     struct GroupBlock * gb=(struct GroupBlock *) &ptr[1];
491     gb->BlockBitmapBlock=2;
492     gb->InodeBitmapBlock=3;
493     gb->InodeTableBlock=4;
494     gb->GroupFreeBlockCount=BLOCKSIZE-5;
495     gb->GroupFreeInodeCount=NUMINODES-1;
496   }
497   {
498     struct BlockBitmap * bb=(struct BlockBitmap *) &ptr[2];
499     for(int i=0;i<(5+12);i++)
500       bb->blocks[i/8]=bb->blocks[i/8]|(1<<(i%8));
501   }
502   {
503     struct InodeBitmap * ib=(struct InodeBitmap *) &ptr[3];
504     ib->inode[0]=1;
505   }
506   {
507     struct InodeBlock * itb=(struct InodeBlock *) &ptr[4];
508     itb->entries[0].filesize=12*BLOCKSIZE;
509     for(int i=0;i<12;i++)
510       itb->entries[0].Blockptr[i]=i+5;
511     itb->entries[0].referencecount=1;
512   }
513
514   int val=munmap(vptr,LENGTH);
515   if (val!=0)
516     printf("Error!\n");
517 }
518