您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > 小型模拟文件系统报告及源代码
一、实验目的掌握Linux操作系统的使用方法;了解Linux系统内核代码结构;掌握实例操作系统的实现方法。二、实验内容设计一个小型文件系统用磁盘中的一个文件(大小事先指定)来模拟一个磁盘确定文件目录项的结构空白块的管理(每个块=连续的N个文件字节)文件目录的管理扩充系统调用命令实现文件的操作:open、close、read、write、cp、rm等三、实验原理(1)建立模拟硬盘的文件我使用了一个1M的文件来模拟一个硬盘。建立1M的文件的代码如下:charend=EOF;fseek(disk,1024*1024-1,SEEK_SET);//将文件指针移动到1M处fwrite(&end,1,1,disk);//将文件结尾标志字符写人文件(2)磁盘数据结构我模仿了EXT2文件系统的结构来构件这个小型文件系统,磁盘数据结构如下图所示:引导块超级块数据块位图索引节点位图索引节点表数据每一块数据定义如下:引导块:typedefstructload_block{intstate;//硬盘状态,初始化后变成1intsuper;inti_nodes;//i节点号,以1开始}load_block;超级快:typedefstructsuper_block{intfree_blocks_count;//空闲数据块数intfree_inodes_count;//空闲索引节点数intblock_size;//数据块大小}super_block;索引节点:typedefstructindex_node{unsignedshortusecount;//文件引用计数unsignedshorti_type;//文件类型time_ttime;//文件建立时间unsignedshorti_length;//文件长度unsignedshorti_mode;//1为只读2为只写3为可读可写unsignedshorti_addr[8];//地址索引表}index_node;目录:ypedefstructlist{charname[12];//文件名unsignedshorti_num;//文件索引节点好unsignedshortftype;//1为普通文件,2为目录文件}list;(3)空白块的管理我使用了块位图来描述数据块的占用情况,用了数组intbitmap[15]这个数组来作为块位图,这个数组的每一位表示一个块。一共描述了15*32=480块数据块。数据块的管理包括找到空闲块,修改块位图;释放数据库,修改块位图。我使用了移位操作和位相与结合来实现之。代码如下:intfind_free_block(){//找到空闲数据块intbitmap[15],i,j,k,l;fseek(disk,BLOCK_BITMAP_START,SEEK_SET);fread(bitmap,15*sizeof(int),1,disk);for(i=0;i15;i++){j=1;l=0;//令j=1,从第一块开始找。do{k=j&bitmap[i];j=1;l++;if(l32)break;}while(k!=0);//只有遇到bitmap[i]==0的时候k才等于0if(l33)break;}if(i==15){printf(nodatblockleft);exit(0);}elsereturni*32+l;}voidrenew_block_bitmap(intnum,intmode){//修改数据块位图intbitmap[15],bitmap1[15],i,j,l=1;fseek(disk,BLOCK_BITMAP_START,SEEK_SET);fread(bitmap,15*sizeof(int),1,disk);i=(num-1)/32;j=(num-1)%32;if(mode==0){//释放l=(j+1);l=~l;bitmap[i]=bitmap[i]&l;}if(mode==1){//占用l=j;bitmap[i]=(bitmap[i])|l;}fseek(disk,BLOCK_BITMAP_START,SEEK_SET);fwrite(bitmap,15*sizeof(int),1,disk);}(4)目录项管理每一个索引节点对应一个文件,如果是个数据文件,则地址索引表指向的是数据块,如果是目录文件,则地址索引表指向的是文件目录,文件目录的I节点号再指向索引节点。我使用了和数据库类似的方法来管理索引节点,即使用了索引节点位图和位操作来找到空闲块、释放和修改位图。具体代码如下:intfind_free_inode(){//找到空闲索引节点intbitmap,i=1,j,k=0;fseek(disk,I_BITMAP_START,SEEK_SET);fread(&bitmap,sizeof(int),1,disk);do{j=i&bitmap;i=1;k++;if(kI_MOUNT){printf(nofreei_nodeleft);exit(0);}}while(j!=0);returnk;}voidrenew_i_bitmap(inti,intmode){//更新i节点位图intbitmap,j=1;fseek(disk,I_BITMAP_START,SEEK_SET);fread(&bitmap,sizeof(int),1,disk);j=(i-1);if(mode==0){//释放j=~j;bitmap=bitmap&j;}if(mode==1){//占用bitmap=bitmap|j;}fseek(disk,I_BITMAP_START,SEEK_SET);fwrite(&bitmap,sizeof(int),1,disk);}(5)功能函数1.open使用了一个结构来描述打开的文件,当要编辑这个文件的时候,就从该结构体中读取相应的信息,找到对应的数据进行修改。该结构如下:typedefstructfile_table{charname[12];unsignedshortmode;unsignedshortinum;}file_table;file_tableopened[8];//打开文件表本来设想是可以同时打开多个文件,即有一个打开文件表,最后由于时间问题,没有使用文件打开表,只使用了第一个,即opened[0],只能一次打开一个文件。每打开一个文件,就将该文件的相关信息写入opened[0]。Open函数代码如下:intfileopen(){intinum=workdir-inum,k;if((k=check_file(selectname,inum))80){printf(没有此文件!\n);}else{inti,j,l;index_nodenode;listreadedlist;i=k/10;j=k%10;fseek(disk,INODE_START+(inum-1)*sizeof(index_node),SEEK_SET);fread(&node,sizeof(index_node),1,disk);fseek(disk,DAT_START+(node.i_addr[i]-1)*BLOCK_SIZE+j*sizeof(list),SEEK_SET);fread(&readedlist,sizeof(list),1,disk);if(readedlist.ftype==1){fseek(disk,INODE_START+(readedlist.i_num-1)*sizeof(index_node),SEEK_SET);fread(&node,sizeof(index_node),1,disk);opened[0].inum=readedlist.i_num;opened[0].mode=node.i_mode;strcpy(opened[0].name,readedlist.name);return1;}elsereturn-1;}}2.readread功能的实现,则是从opened[0]中读取索引节点好,再从该索引节点的索引地址表中读取数据块号和文件长度,将数据读出。代码如下:voidfileread(){inti,length;intdatnum,leftnum,k,j,l=0;char*text;index_nodenode;fseek(disk,INODE_START+(opened[0].inum-1)*sizeof(index_node),SEEK_SET);fread(&node,sizeof(index_node),1,disk);length=node.i_length;datnum=length/64;leftnum=length%64;text=(char*)malloc(length+1);if(datnum0){for(k=0;kdatnum;k++){fseek(disk,DAT_START+BLOCK_SIZE*(node.i_addr[k]-1),SEEK_SET);for(j=0;j64;j++)text[l++]=fgetc(disk);}fseek(disk,DAT_START+BLOCK_SIZE*(node.i_addr[k]-1),SEEK_SET);for(j=0;jleftnum;j++)text[l++]=fgetc(disk);text[l]='\0';}else{fseek(disk,DAT_START+BLOCK_SIZE*(node.i_addr[0]-1),SEEK_SET);for(j=0;jleftnum;j++)text[l++]=fgetc(disk);text[l]='\0';}edittext=text;}3.writewrite的实现和read类似,只是读取变为了写入,得到索引节点号之后,找到空闲的数据块,将数据写入数据库,再将该数据块的地址写入索引节点的索引地址表,同时将文件长度写入索引节点对应数据项中。代码如下:voidfilewrite(){inti;intlength=0,freeblock,j,k;char*ch;index_nodenode;fseek(disk,INODE_START+(opened[0].inum-1)*sizeof(index_node),SEEK_SET);fread(&node,sizeof(index_node),1,disk);for(j=0;j8;j++){freeblock=find_free_block();node.i_addr[j]=freeblock;renew_block_bitmap(freeblock,1);fseek(disk,DAT_START+(freeblock-1)*BLOCK_SIZE,SEEK_SET);ch=edittext;for(k=0;k64&&(*ch)!='\0';k++){fputc(ch[k],disk);}if((*ch)=='\0'){length=length+k;printf(completed);break;}length=length+k;}for(j++;j8;j++)node.i_addr[j]=0;node.i_length=length;fseek(disk,INODE_START+(opened[0].inum-1)*sizeof(index_node),SEEK_SET);fwrite(&node,sizeof(index_node),1,disk);edittext=NULL;}4.closeclose的实现和open刚好相反,将opened[0]中内容改为未打开的标志状态。代码如下:voidfileclose(){inti;strcpy(opened[0].name,0);opened[0].inum=0;opened[0].mode=0;}5.creat如果是创建目录文件,目录文件的地址
本文标题:小型模拟文件系统报告及源代码
链接地址:https://www.777doc.com/doc-7650211 .html