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