
小型模拟文件系统报告及源代码.pdf
12页一、实验目的掌握 Linux 操作系统的使用方法;了解 Linux 系统内核代码结构;掌握实例操作系统的实现方法二、实验内容设计一个小型文件系统用磁盘中的一个文件(大小事先指定)来模拟一个磁盘确定文件目录项的结构空白块的管理(每个块连续的个文件字节)文件目录的管理扩充系统调用命令实现文件的操作:open、close、read、write、cp、rm 等三、实验原理(1)建立模拟硬盘的文件我使用了一个 1M的文件来模拟一个硬盘建立1M的文件的代码如下:char end=EOF;fseek(disk,1024*1024-1,SEEK_SET);/将文件指针移动到 1M 处fwrite(&end,1,1,disk);/将文件结尾标志字符写人文件(2)磁盘数据结构我模仿了 EXT2文件系统的结构来构件这个小型文件系统,磁盘数据结构如下图所示:引导块超级块数据块位图索引节点位图索引节点表数据每一块数据定义如下:引导块:typedef struct load_block int state;/硬盘状态,初始化后变成1 int super;int i_nodes;/i 节点号,以 1 开始load_block;超级快:typedef struct super_block int free_blocks_count;/空闲数据块数int free_inodes_count;/空闲索引节点数名师资料总结-精品资料欢迎下载-名师精心整理-第 1 页,共 12 页 -int block_size;/数据块大小super_block;索引节点:typedef struct index_node unsigned short usecount;/文件引用计数unsigned short i_type;/文件类型time_t time;/文件建立时间unsigned short i_length;/文件长度unsigned short i_mode;/1 为只读 2 为只写 3 为可读可写unsigned short i_addr8;/地址索引表index_node;目录:ypedef struct list char name12;/文件名unsigned short i_num;/文件索引节点好unsigned short ftype;/1 为普通文件,2 为目录文件list;(3)空白块的管理我使用了块位图来描述数据块的占用情况,用了数组int bitmap15这个数组来作为块位图,这个数组的每一位表示一个块。
一共描述了15*32=480 块数据块数据块的管理包括找到空闲块,修改块位图;释放数据库,修改块位图我使用了移位操作和位相与结合来实现之代码如下:int find_free_block()/找到空闲数据块int bitmap15,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&bitmapi;j32)break;while(k!=0);/只有遇到 bitmapi=0 的时候 k 才等于 0 if(l33)break;if(i=15)printf(no datblock left);exit(0);名师资料总结-精品资料欢迎下载-名师精心整理-第 2 页,共 12 页 -else return i*32+l;void renew_block_bitmap(int num,int mode)/修改数据块位图int bitmap15,bitmap115,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;bitmapi=bitmapi&l;if(mode=1)/占用l=j;bitmapi=(bitmapi)|l;fseek(disk,BLOCK_BITMAP_START,SEEK_SET);fwrite(bitmap,15*sizeof(int),1,disk);(4)目录项管理每一个索引节点对应一个文件,如果是个数据文件,则地址索引表指向的是数据块,如果是目录文件,则地址索引表指向的是文件目录,文件目录的I节点号再指向索引节点。
我使用了和数据库类似的方法来管理索引节点,即使用了索引节点位图和位操作来找到空闲块、释放和修改位图具体代码如下:int find_free_inode()/找到空闲索引节点int bitmap,i=1,j,k=0;fseek(disk,I_BITMAP_START,SEEK_SET);fread(&bitmap,sizeof(int),1,disk);do j=i&bitmap;iI_MOUNT)printf(no free i_node left);exit(0);while(j!=0);return k;名师资料总结-精品资料欢迎下载-名师精心整理-第 3 页,共 12 页 -void renew_i_bitmap(int i,int mode)/更新 i 节点位图int bitmap,j=1;fseek(disk,I_BITMAP_START,SEEK_SET);fread(&bitmap,sizeof(int),1,disk);jinum,k;if(k=check_file(selectname,inum)80)printf(没有此文件!n);else int i,j,l;index_node node;名师资料总结-精品资料欢迎下载-名师精心整理-第 4 页,共 12 页 -list readedlist;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_addri-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);opened0.inum=readedlist.i_num;opened0.mode=node.i_mode;strcpy(opened0.name,readedlist.name);return 1;else return-1;2.read read 功能的实现,则是从opened0 中读取索引节点好,再从该索引节点的索引地址表中读取数据块号和文件长度,将数据读出。
代码如下:void fileread()int i,length;int datnum,leftnum,k,j,l=0;char*text;index_node node;fseek(disk,INODE_START+(opened0.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+)名师资料总结-精品资料欢迎下载-名师精心整理-第 5 页,共 12 页 -fseek(disk,DAT_START+BLOCK_SIZE*(node.i_addrk-1),SEEK_SET);for(j=0;j64;j+)textl+=fgetc(disk);fseek(disk,DAT_START+BLOCK_SIZE*(node.i_addrk-1),SEEK_SET);for(j=0;jleftnum;j+)textl+=fgetc(disk);textl=0;else fseek(disk,DAT_START+BLOCK_SIZE*(node.i_addr0-1),SEEK_SET);for(j=0;jleftnum;j+)textl+=fgetc(disk);textl=0;edittext=text;3.write write的实现和 read 类似,只是读取变为了写入,得到索引节点号之后,找到空闲的数据块,将数据写入数据库,再将该数据块的地址写入索引节点的索引地址表,同时将文件长度写入索引节点对应数据项中。
代码如下:void filewrite()int i;int length=0,freeblock,j,k;char*ch;index_node node;fseek(disk,INODE_START+(opened0.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_addrj=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(chk,disk);if(*ch)=0)名师资料总结-精品资料欢迎下载-名师精心整理-第 6 页,共 12 页 -length=length+k;printf(completed);break;length=length+k;for(j+;jinum;if(check_file(filename,inum)80)printf(error!the name%s has being used!n,filename);else index_node node;list readedlist4;int i,j=0;unsigned short readedinum,freeinode;fseek(disk,INODE_START+(inum-1)*sizeof(index_node),SEEK_SET);fread(&node,sizeof(index_node),1,disk);for(i=0;i8;i+)名师资料总结-精品资料欢迎下载-名师精心整理-第 7 页,共 12 页 -fseek(disk,DAT_START+BLOCK_SIZE*(node.i_addri-1),SEEK_SET);fread(readedlist,4*sizeof(list),1,disk);for(j=0;j4;j+)if(readedlistj.i_num=0)break;if(j1)node1.usecount-;fseek(disk,INODE_START+(readedlistj.i_num-1)*sizeof(index_node),SEEK_SET);fwrite(&node1,sizeof(index_node),1,disk);else if(readedlistj.ftype=2)int l,m;list readedlist14;for(l=0;l8;l+)fseek(disk,DAT_START+BLOCK_SIZE*(no。












