10 #include "test3_aux.h"
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) {
24 for(i=0;i<MAXFILES;i++)
27 case '0': createdisk();
31 struct block * ptr=mountdisk("disk");
34 sprintf(filename,"fil%d",i);
35 openfile(ptr,filename);
40 char *buf="01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123";
41 writefile2(ptr,i,buf,122);
51 struct block * ptr=chmountdisk("disk");
57 struct block * ptr=mountdisk("disk");
61 sprintf(filename,"fil%d",i);
62 printfile(filename,ptr);
69 struct block * ptr=mountdisk("disk");
72 sprintf(filename,"fil%d",i);
73 openfile(ptr,filename);
78 char *buf="01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123";
79 writefile2(ptr,i,buf,122);
90 struct block * ptr=mountdisk("disk");
93 sprintf(filename,"fil%d",i);
94 openfile(ptr,filename);
100 int len=sprintf(name, "%d ",i);
101 writefile2(ptr,i,name,len);
109 sprintf(filename,"fil%d",i);
110 openfile(ptr,filename);
117 int len=sprintf(name, "%d ",i);
118 readfile2(ptr,i,name,len);
119 sscanf(name, "%d ", &l);
121 printf("ERROR in benchmark\n");
134 struct block * ptr=chmountdisk("disk");
137 struct block * ptr=mountdisk("disk");
138 for(i=145;i>=0;i--) {
140 sprintf(filename,"fil%d",i);
141 openfile(ptr,filename);
143 for(j=0;j<6000;j++) {
145 for(i=145;i>=0;i--) {
147 int len=sprintf(name, "%d ",i);
148 writefile2(ptr,i,name,len);
151 for(i=145;i>=0;i--) {
154 for(i=145;i>=0;i--) {
156 sprintf(filename,"fil%d",i);
157 openfile(ptr,filename);
161 for(i=145;i>=0;i--) {
164 int len=sprintf(name, "%d ",i);
165 readfile2(ptr,i,name,len);
166 sscanf(name, "%d ", &l);
168 printf("ERROR in benchmark\n");
172 for(i=145;i>=0;i--) {
179 struct block * ptr=mountdisk("disk");
185 unsigned long time = 0;
187 time += selfcheck2(ptr);
189 printf("\ncompiled: %u us\n", (time));
201 unsigned long selfcheck2(struct block* d) {
203 struct timeval begin,end;
205 gettimeofday(&begin,NULL);
209 gettimeofday(&end,NULL);
210 t=(end.tv_sec-begin.tv_sec)*1000000+end.tv_usec-begin.tv_usec;
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);
222 void chunmountdisk(struct block *vptr) {
223 int val=munmap(vptr,LENGTH);
227 struct block * mountdisk(char *filename) {
228 int fd=open(filename,O_CREAT|O_RDWR);
230 struct block *ptr=(struct block *) mmap(NULL,LENGTH,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_SHARED,fd,0);
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;
240 struct InodeBitmap *ibb=(struct InodeBitmap *) &ptr[ibbptr];
241 struct BlockBitmap *bbb=(struct BlockBitmap *) &ptr[bbbptr];
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];
251 void unmountdisk(struct block *vptr) {
252 struct InodeBitmap *ibb=(struct InodeBitmap *) &vptr[ibbptr];
254 for(i=0;i<(NUMINODES/8+1);i++)
255 ibb->inode[i]=ib.inode[i];
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);
266 void printdirectory(struct block *ptr) {
267 struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
270 struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]];
272 for(j=0;j<BLOCKSIZE/128;j++) {
273 if (db->entries[j].name[0]!=0) {
275 printf("%s %d inode %d bytes\n",db->entries[j].name, db->entries[j].inodenumber,itb->entries[db->entries[j].inodenumber].filesize);
281 void printfile(char *filename, struct block *ptr) {
282 struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
285 struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]];
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) {
291 int inode=db->entries[j].inodenumber;
293 struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
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);
305 void removefile(char *filename, struct block *ptr) {
306 struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
309 struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]];
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) {
315 db->entries[j].name[0]=0; //Delete entry
317 int inode=db->entries[j].inodenumber;
319 struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
320 itb->entries[inode].referencecount--;
322 if (itb->entries[inode].referencecount==0) {
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));
328 ib.inode[inode/8]^=(1<<(inode%8));
337 void createlink(struct block *ptr,char *filename, char *linkname) {
338 struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
341 struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]];
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) {
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);
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;
363 bool writefile(struct block *ptr, int fd, char *s) {
364 return (writefile2(ptr,fd,s,1)==1);
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;
373 if (tfd->used==false)
376 if ((12*BLOCKSIZE-tfd->offset)<len)
377 len=12*BLOCKSIZE-tfd->offset;
379 int nbuffer=tfd->offset/BLOCKSIZE;
380 int noffset=tfd->offset%BLOCKSIZE;
381 if (tfd->offset>=filelen) {
383 int bptr=getblock(ptr);
385 if (itb->entries[files[fd].inode].filesize<files[fd].offset)
386 itb->entries[files[fd].inode].filesize=files[fd].offset;
389 itb->entries[tfd->inode].Blockptr[nbuffer]=bptr;
393 int block=itb->entries[tfd->inode].Blockptr[nbuffer];
394 char *fchar=(char *)&ptr[block];
396 if (tocopy>(BLOCKSIZE-noffset))
397 tocopy=BLOCKSIZE-noffset;
398 memcpy(&fchar[noffset],&s[i],tocopy);
399 msync(&fchar[noffset],tocopy,MS_SYNC);
404 if (itb->entries[files[fd].inode].filesize<files[fd].offset)
405 itb->entries[files[fd].inode].filesize=files[fd].offset;
410 char readfile(struct block *ptr, int fd) {
412 if (readfile2(ptr,fd,array,1)==1)
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;
424 if (tfd->used==false)
426 if ((filelen-tfd->offset)<len)
427 len=filelen-tfd->offset;
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];
434 if (tocopy>(BLOCKSIZE-noffset))
435 tocopy=BLOCKSIZE-noffset;
436 memcpy(&buf[i],&fchar[noffset],tocopy);
443 int openfile(struct block *ptr, char *filename) {
447 struct InodeBlock * itb;
451 for(k=0;k<MAXFILES;k++) {
459 if (fd==-1) return fd;
461 /* Check to see if file exists*/
462 itb=(struct InodeBlock *) &ptr[itbptr];
464 struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]];
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;
480 files[fd].used=false;
483 itb->entries[inode].filesize=0;
484 itb->entries[inode].referencecount=1;
486 addtode(ptr, inode, filename);
487 files[fd].inode=inode;
492 void createfile(struct block *ptr,char *filename, char *buf,int buflen) {
493 int fd=openfile(ptr,filename);
494 writefile2(ptr,fd,buf,buflen);
498 void addtode(struct block *ptr, int inode, char * filename) {
499 struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr];
502 struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]];
504 for(j=0;j<BLOCKSIZE/128;j++) {
505 if (db->entries[j].name[0]==0) {
507 strncpy(db->entries[j].name,filename,124);
508 db->entries[j].inodenumber=inode;
509 msync(&db->entries[j],sizeof(struct DirectoryEntry),MS_SYNC);
516 int getinode(struct block *ptr) {
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));
527 int getblock(struct block * ptr) {
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));
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);
548 for(i=0;i<numblocks;i++) {
549 write(fd,buf,blocksize);
552 vptr=mmap(NULL,LENGTH,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_SHARED,fd,0);
554 ptr=(struct block *)vptr;
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;
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;
573 struct BlockBitmap * bb=(struct BlockBitmap *) &ptr[2];
575 for(i=0;i<(5+12);i++)
576 bb->blocks[i/8]=bb->blocks[i/8]|(1<<(i%8));
579 struct InodeBitmap * ib=(struct InodeBitmap *) &ptr[3];
584 struct InodeBlock * itb=(struct InodeBlock *) &ptr[4];
585 itb->entries[0].filesize=12*BLOCKSIZE;
587 itb->entries[0].Blockptr[i]=i+5;
588 itb->entries[0].referencecount=1;
591 int val=munmap(vptr,LENGTH);