ImageVerifierCode 换一换
格式:DOCX , 页数:23 ,大小:28.56KB ,
资源ID:26066260      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/26066260.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(pintos pro4 filesystem 设计报告.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

pintos pro4 filesystem 设计报告.docx

1、pintos pro4 filesystem 设计报告Project 4 FileSystem作者:西安电子科技大学王永刚 文件系统是操作系统的五大功能模块之一,主要实现操作系统对程序、数据、设备等的管理。一、 当前pintos文件系统的功能当前pintos文件系统已经实现了基本的文件创建删除功能。文件是固定大小,连续存放的。文件在磁盘的存储方式: 每个文件都有一个disk_inode存放在磁盘的一个扇区上,其结构如下:struct inode_disk block_sector_t start; 位图文件大小显然与磁盘大小有关,用一个位表示一个扇区是否被分配,一个扇区512字节,一个扇区作为

2、一个物理块,创建一个2M的磁盘,有1024*1024*2/512bit=4096bit= 4096/8=512Byte。文件系统初始化过程:在:main()函数中调用了filesys_init();1. 在filesys_init()中,初始化了bitmap,而且对磁盘进行了格式化。其中格式化就是创建了两个文件,一个用来管理空闲块的位置图文件,一个是根目录文件。()中调用了free_map_init(),在free_map_init()中调用bitmap_create()创建了位图,大小依据磁盘大小。而且标记了0 1两个扇区为已经分配,作为free_map_file的disk_inode空间和

3、根目录文件的disk_inode空间。此时free_map只是在内存中。()中又调用了do_format()在do_format()中:调用 了free_map_create(),创建了free_map_file,即一个文件,其disk_inode已经在上面分配了,再分配文件大小即可,这是由调用inode_create函数来实现的。创建这个文件时显然需要分配磁盘空闲块,就从在内存中的free_map位图中分配就可以。文件创建好了之后,打开文件,把内存中的位图free_map写到磁盘上,这是调用bitmap_write()实现的,本质还是用file_write()实现的。File_write()

4、是通过inode_write_at()写磁盘的。在do_format()中还创建根目录文件,ROOT_DIR_SECTOR已经标记了,分配文件所需要的空间就行了。4. Filesys_init()调用了free_map_open()把free_map读入内存。其实就是打开上面创建的free_map文件,读数据入内存。直到系统关闭时才将free_map写回到磁盘上。 首先在内存中建立了磁盘的位图,标记了根目录和free_map本身的disk_inode结构扇区。 上面的内存free_map一建立就保证创建文件时可以分配磁盘空间了。而inode_create()中就需要调用free_map_all

5、ocate()来获取空闲物理块。如果不格式化,则以前必然格式化过,直接读入free_map就行。目录创建过程。Pintos原来已经实现了创建目录的功能,但是只创建根目录,而且根目录只能包含16个文件,即16个dir_entry结构。目录本质也是一个文件,根目录是特殊的文件,在中有宏定义:#define ROOT_DIR_SECTOR 1.在ROOT_DIR_SECTOR中,也就是第1个扇区中存放了根目录的disk_inode.上面已经提到了,在格式化时创建了根目录。文件打开过程。调用filesys_open().每个打开的文件在内在都维护了一个唯一的数据结构inode(为了与disk_inod

6、e区别,这个叫memory inode).以下是memory inode结构:Struct inode Struct list_elem elem; Block_sector_t sector;Int open_cnt;Bool removed;Int deny_write_cnt;Struct inode_disk data;打开一个文件显然就是在内存中创建一个inode结构,其中struct inode_disk data保存了该文件对应的磁盘中的inode. 如果此文件已经打开了,则只需要增加open_cnt的值,不用再创建一个inode. 这些inode通过一个链表链结到一起的,在fi

7、lesys_init()中初始化了这个链表。具体过程: 调用filesys_open(const char filename); 首先打开根目录,然后在根目录中依据filename查找文件。如果找到了,也就是找到了此文件对应的struct dir_entry结构,里面记录了文件disk_inode, disk_inode中记录文件数据起始位置和文件大小,这就可以读写文件了。当然,还需要建立文件对应的memory inode.其中 data就是此文件的disk_inode.通过filesys_open()只能得到文件的inode. 如果此文件是普通文件,则调用fileopen(inode)把in

8、ode包装成struct file结构;如果是目录就调用dir_open把inode包装成struct dir.Struct file结构如下:Struct file Struct inode *inode; Off_t pos; Bool deny_write;文件的创建过程.创建一个文件要有文件名和文件大小,每一个文件在磁盘中都有一个struct disk_inode结构,每个文件和目录都要在一个目录下,在目录文件中,struct dir_entry中记录了每个该目录下的文件的文件名,以及每个文件disk_inode所在扇区号。具体是通过调用filesys_create(const cha

9、r *name,off_t initial_size)实现的. 首先调用struct dir *dir =dir_open_root()打开根目录。以下struct dir结构。Struct dir Struct inode *inode; Off_t pos; 本质就是一个文件,读写目录与读写普通文件没有区别。然后调用free_map_allocate分配一个扇区sector作为新文件的disk_inode.再调用inode_create(sector,initial_size)分配文件所需要磁盘空间,分配的空间是连续的扇区。最后创建一个struct dir_entry结构,把文件名和其se

10、ctor填入其中,在目录中找一个位置放入就可以了。文件的读写。调用filesys_open()打开文件,这就得到了struct file结构,如下:些结构记录了当前文件指针位置pos。File_read() file_write()分配是通过inode_read_at()和inode_write_at()实现的。 对disk_inode的改进 当前pintos文件系统限制很大。文件需要连续存储,这会导致大量磁盘碎片。文件大小固定,不能动态增长文件,只有一个目录。这里主要把连续存储方式改为了linux中三级索引结构,而且可以动态增长文件,可以创建子目录。三级索引结构:01234567891011

11、121314011是直接块,存入文件512128512128512128数据块扇区号。 12是一级索引13是二级索引Data51212851212814 是三级索引data512128如果一个物理块是512字节每个物理块中用四字节data直接块:12*512=6K一级索引:128*512=64K二级索引:128*128*512=8M三级索引:128*128*128*512=1GB总大小1GB8M72K通过修改struct disk_inode结构来实现三级索引结构。修改过的disk_inodeStruct inode_disk Off_t length; 改变了disk_inode, 自然要从

12、inode_create开始入手。代码见附录。因为要区分目录和普通文件,所以对原来的inode_create进行了扩展,改为了bool inode_create_ex (block_sector_t sector, off_t length,uint32_t isdir);增加了isdir参数。重新定义了一个函数:bool inode_create(block_sector_t sector,off_t length) return inode_create_ex(sector,length,0);用这个来代替原来的inode_create。Inode_create执行时文件的disk_ino

13、de已经分配了,只需要分配文件数据空间,这里并不从free_map中分配空间,只是简单的把索引初始化为0。新创建的文件内容应为全0,所以调用了inode_write_at()来把文件内容写为全0;在写的过程中如果发现空间未分配,则会分配。读写文件 读写文件时会给出文件指针偏移offset和要读写的大小。需要根据offset来确定要读写的扇区,通过上面的公式可以计算出扇区号。计算代码见附录。定义如下结构:struct PosInfo uint16_t lev; ;根据offset可以计算出offset在几级索引中-lev最后的数据块中的偏移 -off举例:如果offset=215364 size

14、=865 buff=要从文件215364字节处读取865字节到buff中。经计算:Lev=2 Sn0=0 blocks15011121314Np0=13 Sn1=0Np1=2Sn2=0Np2=24由np0=13可以通过读取扇区blocksnp0到缓冲区arr512中去此时arr中就是一级索引块Arrnp1就是二级索引块的扇区号,由此又可以把二级索引块读入到arr中。 此时arr就是二级索引块,Arrnp2就是文件数据块的扇区号了,把数据块读入到arr中就可以对数据进行读写了。这个扇区读写完毕之后,offset也向后移动了x字节,这时又需要重新确定struct PosInfo结构。注意:写的时候

15、,如果最后offset已经大小了文件长度,则认为扩展了文件长度,修改disk_inode中的文件长度。这就实现了文件的动态增长。inode删除需要收回文件空间,显然有了struct PosInfo结构,收回空间不是难事儿。代码见附录。多级目录的建立 现有目录只是根目录,而如今要实现多级目录,而且像linux系统一样,有一个环境变量pwd来存放当前目录。新目录支持如: . ./ . ./ ././ /等操作,而且允许用户程序切换当前目录、打开目录、建立目录、读目录,都是通过系统调用system call实现的,以下列举了要实现的系统调用:Bool chdir(const char *dir)切换

16、当前目录。其中dir中可能有 /a/b/c/ ././c/d这样的字符串。需要字符串处理,最后打开目录,如果失败则切换失败,否则切换成功。Mkdir(const char *dir)创建目录,如:/a/b/c 在/a/b/目录下建立c目录。调用附录中的DirCreate()创建目录。readdir(int fd,char *name)将目录当作普通文件来读,但是不能写。这使得file_write中判断一下,如果是目录则写入失败。isdir(int fd)由文件句柄判断此文件是不是目录文件。可以根据disk_inode中的isdir变量来判断。inumber返回一个数来区分是目录还是文件,通过在

17、文件disk_inode变量区分,所以目录和文件可以统一分配空间。无论是切换目录还是创建目录,以及在目录下打开文件,创建文件,删除文件,都需要打开目录,要有一个目录字符串处理函数,于是char * MakePath(const char *from)应用而生。这个函数把pwd和from相结合,去掉其中./之类的符号,转化为标准的纯绝对路径,如:/a/b/c/d /a/b/c/d/。目录确定就能打开目录,struct dir *OpenDir(char *path,int *pos)函数来实现此功能。这又是一个字符串处理函数,可以用/作为区分。 无论是切换还是创建目录,都可以用打开目录来确定是否

18、给出的目录合法。创建目录时,要指定disk_inode中的isdir为true. 在struct thread中加入指针char *pwd;来保存当前目录,使用时,如果pwd为NULL,则认为是根目录/;如果需要改变当前目录,则需要申请空间,线程退出时会释放掉空间。 删除目录时要注意,目录是否为空,可以逐个验证每个struct dir_entry中的bool use;变量来判断该目录下是否有目录或文件。 目录是在磁盘上的,磁盘是多个进程所共享的,对目录的操作也需要同步。主要在打开目录,删除目录时需要获得相应的锁。最简间的办法是给整个磁盘加锁,事实上允许一个进程操作某个文件或目录时允许其他进程也

19、操作相同或者是不同的目录。所以打开目录后就释放锁。 buffer cache系统设计为了加快对磁盘的读写,在内存开辟出一定大小的空间作为磁盘缓冲区。于是需要设计一套缓冲系统。有的VM中的缓冲区设计的基础,设计这个就简单多了。分析pintos对块设备的读写可以发现,把有的外部块设备的读写都是通过中的block_read()函数和block_write()函数来实现的。在这两个函数中,在实际操作物理磁盘前,先在cache中查找要读写的块,如果在cache中,则直接从cache中读写,否则从磁盘调入cache再读写。这就有可能要从cache中淘汰出一个扇区。采用LRU算法可以有效的进行淘汰。具体实现

20、:在内存开辟了64个扇区的空间作为cache.struct BlockCache size_t SecNo; 需要淘汰扇区时,选择num最大的,即最久未使用的扇区淘汰出去。读写时就在ManArr中顺序查找要读写的块,找到就可以直接读写,否则需要从磁盘调入。同步问题。磁盘缓冲系统出多线程共享,所以在调入调出时都需要同步。共享的是每个内存扇区,所以可以给每个扇区加一把锁,这就是BlockCache 中的lock的作用。每隔一段时间需要把缓冲中的数据写回到磁盘上去,所以另创建了一个线程,这个线程每隔一定时间把cache中的块都写回到磁盘中去。附录中有cache的实现代码。Pintos 文件系统与外界

21、的交换方法pintos如果把虚拟机外的文件复制到文件系统中的,又如何把把文件系统中的东西复制到虚拟机外的这是由filesys/ 中的函数完成的。文件在pintos系统之外时被复制到了一个虚拟硬盘中,其格式是顺序结构。文件名等文件信息在一个扇区中,紧接着就是文件数据部分。其存储结构如下:上面一个方格代表一个扇区。Pintos启动前由外部程序把文件一个一个的按如上格式装入一个磁盘。Pintos启动后再从这个磁盘中读取文件,并在filesystem中建立相关的文件。文件1的文件头文件1的数据.文件2 的文件头数据.文件3附录:Inode create 代码:bool inode_create(blo

22、ck_sector_t sector,off_t length) return inode_create_ex(sector,length,0);boolinode_create_ex (block_sector_t sector, off_t length,uint32_t isdir) struct inode_disk *disk_inode = NULL; bool success = false; ASSERT (length = 0); /* If this assertion fails, the inode structure is not exactly one sector

23、 in size, and you should fix that. */ ASSERT (sizeof *disk_inode = BLOCK_SECTOR_SIZE); disk_inode = calloc (1, sizeof *disk_inode); if (disk_inode != NULL) size_t sectors = bytes_to_sectors (length); disk_inode-length = length; disk_inode-isdir=isdir; disk_inode-magic = INODE_MAGIC; int i; for(i=0;i

24、deny_write_cnt) return 0; struct PosInfo pi; uint32_t *arr=NULL; */ if (inode = NULL) return; /* Release resources if this was the last opener. */ if (-inode-open_cnt = 0) /* Remove from inode list and release lock. */ list_remove (&inode-elem); /* Deallocate blocks if removed. */ if (inode-removed)

25、 &pre=.) if(pos0)pos-; while(pos0&topos!=/) pos-; else if(fromi=/) if(topos!=/) to+pos=fromi; else if(fromi=.&pre=0); else if(pre=/&fromi=.); else to+pos=fromi; pre=fromi; to+pos=0; return to; 目录打开函数 打开一个目录,返回struct dir结构struct dir *OpenDir(char *path,int *pos) lock_acquire(&DirOpenLock); struct dir

26、 *dir=dir_open_root(); struct inode *inode=NULL; int cur=1,i,n; n=strlen(path); for(i=1;i!=1) goto end; dir=dir_open(inode); inode=NULL; cur=i+1; *pos=cur; lock_release(&DirOpenLock); return dir;end: lock_release(&DirOpenLock); return NULL;几个系统调用的实现:void IMkDir(struct intr_frame *f) if(!is_user_vadd

27、r(int *)f-esp)+2) ExitStatus(-1); char *DirName=*(int *)f-esp+1); int n=strlen(DirName); if(DirNamen-1=/) DirNamen-1=0; n-; if(neax=0; return; f-eax=DirCreate(DirName);void IChDir(struct intr_frame *f) if(!is_user_vaddr(int *)f-esp)+2) ExitStatus(-1); char *DirName=*(int *)f-esp+1); char *path=MakePath(DirName

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1