操作系统课程设计 indoec流程及代码分析.doc_第1页
操作系统课程设计 indoec流程及代码分析.doc_第2页
操作系统课程设计 indoec流程及代码分析.doc_第3页
操作系统课程设计 indoec流程及代码分析.doc_第4页
操作系统课程设计 indoec流程及代码分析.doc_第5页
免费预览已结束,剩余18页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

目 录1总体概述22模块整体功能介绍及主要目标221 模块整体功能222 主要目标33头文件的分析331 头文件kernel.h332 头文件sched.h433 头文件system.h434 头文件fs.h44数据结构的分析45函数的分析651 read_inode()函数分析652 write_inode()函数分析753 sleep_on()函数分析754 wait_on_inode()函数分析855 lock_inode()函数分析956 unlock_inode()函数分析957 invalidate_inodes()函数分析1058 sync_inodes(void)函数分析1159 _bmap()函数分析11510 bmap()函数分析15511 iput()函数分析15512 get_empty_inode()函数分析17513 get_pipe_inode()函数分析18514 create_block()函数分析18515 iget()函数分析196分析体会及自己所做亮点工作217参考文献23第23页1总体概述实验名称:Linux0.11文件系统源代码分析之I节点管理源代码分析;源代码在源程序中的具体位置:linux/fs/inode.c(电子书Linux内核0。11完全注释赵炯编著的451页)。实验要求:对该源代码进行分析的主要任务是对重要的头文件进行分析、结合代码对实现所用的主要数据结构进行分析、结合代码对主要函数功能进行分析,并画出函数间调用关系结构图或程序流程图。实验预期结果:从形式上来看,程序主要是头文件、数据结构和函数构成,从思路上来看,程序是由数据结构和算法构成,但是现在Linux操作系统源代码,已经给了我们,而且别人也分析的特别的详细了。作为初学者,没有什么经验,我想能把它看懂就不错了,所以最重要的是对程序的各个函数进行分析,画出流程图(主要是通过流程图来分析),在画流程图的过程中,仔细体会每行代码的作用和思路,从而最终看懂整个inode.c程序。2模块整体功能介绍及主要目标21模块整体功能inode.c程序主要涉及文件系统i节点信息的访问和管理。每个文件的创建都会有一个i节点,它包括该文件的所有信息,本程序就是对创建好的文件的i节点进行管理。该程序主要包括处理i节点的iget()、iput()、bmap(),以及其他一些辅助函数。iput()函数的功能与iget()函数正好相反,主要把i节点引用计数值递减1,要是在某一时刻进程不需要持续使用一个i节点时就应该调用iput()函数来使i节点引用值减1,好让内核执行其他一些处理。(详细过程见iput()函数的流程图(图14);iget()函数的功能是从设备上取指定节点号的i节点,处理过程是扫描整个i节点表,来找相应的i节点,当找到后再等待解锁,这时i节点表可能会发生变化,就要再重新扫描i节点表,还要把i节点的引用计数值增1,还要判断是否是安装点,要是的话,就在超级块表中找,找到后,再写盘,再重新扫描整个i节点表。最后返回找到的i节点指针。(详细过程见iget()函数的流程图(图18)。22主要目标 主要分析inode.c程序中的处理i节点的主要处理函数,包括iget()、iput()、bmap(),以及其他一些辅助函数。结合代码对主要函数功能进行分析,并画出函数间调用关系结构图或程序流程图。3头文件的分析31 头文件kernel.hpanic(const char*str);/标准打印(显示)函数printf();/内核专用的打印信息函数,功能与printf()相同printk();/往tty上写指定长度的字符串。32 头文件sched.hextern void sleep_on(struct tast_struct*p);/不可中断的等待睡眠extern void interruptible_sleep_on(struct tast_struct*p);/可中断的等待睡眠extern void wake_up(struct tast_struct*p);/明确唤醒睡眠的进程。33 头文件system.h sti();/开中断嵌入汇编宏函数 cli();/关中断34 头文件 fs.hextern struct m_inode inode_tableNR_INODE;/定义i节点表数组(32项)extern void truncate(struct m_inode*inode);/刷新i节点信息。extern voic sync_inodes(void);/等待指定的i节点。extern void brelse(struct buffer_head*buf);/读取指定的数据块。4数据结构的分析41 struct buffer_head;/缓冲块头数据结构,在程序中常用bh来表示buffer_head类型的缩写(极为重要)(结构见图1)图1 struct buffer_head结构体42 struct d_inode;/磁盘上的索引节点(i节点)数据结构。43 struct m_inode;/在内存中的i节点结构(结构见图2)图2 struct m_inode结构体44 struct super_block;/内存中磁盘超级块结构(结构见图3)图3 struct super_block结构体45 struct d_super_block;/磁盘上超级块结构46 struct m_inode inode_tableNR_INODE=0,;/内存中I节点表5函数的分析51 read_inode()函数分析511函数头:static void read_inode(struct m_inode*inode);512主要功能:读取指定I节点信息;从设备上读取含有指定I节点信息的I节点盘块,然后复制到指定的I节点结构中。为了确定I节点所在的设备逻辑块号(或缓冲块),必须首先读取相应设备上的超级块,以获取用于计算逻辑块号的每块I节点数信息INODES_PER_BLOCK.在计算出I节点所在的逻辑块号后,就把该逻辑块读入一缓冲块中。然后把缓冲块中相应位置处的I节点内容复制到参数指定的位置处。513流程图:(见图4)锁定该I节点从设备上取得超级块否?YN提示从其他地方读入计算设备逻辑块号复制到indoe指针所指位置处Brelse(bh)unlock_inode(inode)图4 read_inode()函数流程图52 write_inode()函数分析521函数头:static void write_inode(struct m_inode*inode);522功能分析:将i节点信息写入缓冲区中。该函数把参数指定的i节点写入缓冲区相应的缓冲块中,待缓冲区刷新时会写入盘中。523流程图:(见图5)锁定该I节点lock_inode(inode)修改过或设备号0否?YN退出计算设备逻辑块号复制到逻辑块对应该I节点项位置处置缓冲区已修改标志bh-b_dirt=1内容与缓冲区一致bh-b_dirt=0Brelse(bh);unlock_inode(inode)结束图5 write_inode()函数流程图53 sleep_on()函数分析531函数头:void sleep_on(struct tast_struct*p);532功能分析:把当前任务置为不可中断的等待状态,并让睡眠队列列头指针指向当前任务,只有明确地唤醒时才会返回。该函数提供了进程与中断处理程序之间的同步机制。函数参数p是等待任务队列列头指针。指针是含有一个变量地址的变量。这里参数p使用了指针的指针形式*p,这是因为C函数参数只能传值,没有直接的方式让被调用函数改变调用该函数程序中变量的值。但是指针*p指向的目标(这里是任务结构)会改变,因此为了能修改调用该函数程序中原来就是指针变量的值,就需要传递指针*p的指针,即*P。54 wait_on_inode()函数分析541函数头:static inline void wait_on_inode(struct m_inode*inode);542函数的功能:等待指定的i节点可用;如果i节点已被锁定,则将当前任务置为不可中断的等待状态,并添加到该I 节点的等待队列i_wait中,直到该i节点解锁并明确地唤醒本任务。543程序流程图:(见图6)关中断cli()开中断sti()I节点锁定否?NYsleep_on(&inode-i_wait)结束图6 wait_on_inode()函数流程图55 lock_inode()函数分析551函数头:static inline void lock_inode(struct m_inode*inode);552函数的功能:对指定的I节点上锁;如果I节点已被锁定(即当inode-i_lock=1),则将当前任务置为不可中断的等待状态,并添加到该I节点的等待队列i_wait中。直到该I节点解锁(inode-i_lock=0时)并明确地唤醒本任务。然后对其上锁(inode-i_lock=1)。553流程图:(见图7)关中断cli()I节点锁定否?YNsleep_on(&inode-i_wait)结束开中断sti()Inode-i_lock=1图7 lock_inode()函数流程图56 unlock_inode()函数分析561函数头:static inline void unlock_inode(struct m_inode*inode);562函数的功能:对指定的i节点解锁;首先使i节点的锁定标志为0(复位),并明确地唤醒(wake_up(&inode-i_wait))等待在此i节点等待队列i_wait上的所有进程。57 invalidate_inodes()函数分析571函数头:void invalidate_inodes(int dev);572函数的功能:释放设备dev在内存i节点表中的所有i节点;扫描内存中的i节点表数组,如果是指定设备使用的i节点就释放之。573流程图:(见图8)指向内存i节点表数组首项显示出错警告YNINR_INODE ?初始化i=0I节点解锁?YN是指定设备的i节点否?YI_count0?NY释放i节点(置设备号为0) I+,inode+指向下一节点N结束图8 invalidate_inodes()函数流程图58 sync_inodes(void)函数分析581函数头:void sync_inodes(voic);582函数的功能:同步所有i节点;把内存i节点表中所有i节点与设备上i节点作同步操作。583流程图:(见图9)指向内存i节点表数组首项YNIi_dirt=1;inode-i_ctime=CURRENT_TIMEi_zone7为0?Y创建时申请失败返回0退出读取设备上该i节点的一次间接块N读到否?Y取该间接块的第block项中盘块号i创建且i为 0?修改标志bh-b_dirt=1Y申请一磁盘块,并等于该新盘块号Nbrelse(bh);/释放且return I;图11 _bmap()函数中对一次间接块进行处理的流程图5933对二次间接块进行处理的过程:(见图12)YYYNYN申请一磁盘块用于存放间接信息块Inode-i_dirt=1;inode-i_ctime=CURRENT_TIMEi_zone8为0?创建时申请失败返回0退出读取设备上该i节点的一次间接块读到否?取该间接块的第block项中盘块号i创建且i为 0?修改标志bh-b_dirt=1申请一磁盘块,并等于该新盘块号brelse(bh);/释放且return I;创建且i_zone8为0?对二次间接块进行处理block-=512返回0N图12 _bmap()函数中对二次间接块进行处理510 bmap()函数分析5101函数头:int bmap(struct m_inode*inode,int block);5102函数的功能:取文件数据块block在设备上对应的逻辑块号;参数:inode-文件的内存i节点指针;block-文件中的数据块号;若操作成功则返回对应的逻辑块号,否则返回0。5103调用结构图:(见图13)调用bmap()函数_bmap()函数图13 bmap()函数调用结构图511 iput()函数分析5111函数头:void iput(struct m_inode*inode);5112功能分析:放回(放置)一个i节点(回写入设备)。该函数主要用于把i节点引用计数值递减1,并且若是管道i节点,则唤醒等待的进程。若是块设备文件i节点则刷新设备。并且若i节点的链接计数为0,则释放该i节点占用的所有磁盘逻辑块,并释放该i节点。5113流程图:(见图14)图14 iput()函数流程图512 get_empty_inode()函数分析5121函数头:struct m_inode*get_empty_inode(void);5122功能分析:从i节点表(inode_table)中获取一个空闲i节点项; 5123流程图:(见图15)last_inode指针指向i节点表第一项循环扫描整个i节点表找到空闲i节点否?N打印供调试用并停机等待解锁Yinode-i_dirt=1?Ywrite_inode(inode);wait_on_inode(inode)Ninode-i_count0?YN已找到符合要求的空闲i节点项该i节点项内容清0,引用计数为1返回i节点指针并结束图15 get_empty_inode()函数流程图513 get_pipe_inode()函数分析5131函数头:struct m_inode*get_pipe_inode(void);5132功能分析:获取管道节点。5133流程图:(见图16)扫描i节点表,寻找一个空闲i节点项引用计数置为2(读者和写者)复位管道头和尾指针YN返回NULL申请一页内存,并i_size指向该页面还有空闲内存否?N释放该i节点,并返回NULLY置节点为管道使用的标志i_pipe=1返回inode并结束get_empty_inode()找到否?图16 get_pipe_inode()函数流程图514 create_block()函数分析5141函数头:int create_block(struct m_inode*inode,int block);5142功能分析:取文件数据块block在设备上对应的逻辑块号;如果对应的逻辑块不存在就创建一块;返回设备上对应的已存在或新建的逻辑块号。参数:inode-文件的内存i节点指针;block-文件中的数据块号。5143调用结构图:(见图17)调用Create_block()函数_bmap()函数图17 create_block()函数调用结构图515 iget()函数分析5151函数头:struct m_inode*iget(int dev,int nr);5152功能分析:取得一个i节点。5153流程图:(见图18)图18 iget()函数流程图6分析体会及自己所做亮点工作经过自己几天的努力,Linux0.11文件系统源代码分析之I节点管理源代码分析inode.c,终于用自己的思路分析完了,理解透了。Inode.c程序总共有339行代码,乍一看,自己都会心烦,很难看下去,报告也无从着手来写,虽然注解非常的详细,看代码最忌讳的就是没有耐心,所以在看代码之前就必需使自己静下心来,然后根据熊老师的要求,报告的说明,想好自己的分析计划。先整体看一下程序,看它由哪些函数构成,第一遍看下来,就发现在inode.c程序中,定义了一些主要函数(如:read_inode(),write_inode(),iget(),get_pipe_inode(),get_empty_inode(),iput(),bam(),_bamp(),sync_inode(),invalidate_inodes(),unlock_inode(),lock_inode(),wait_inode())(看第一遍时,只看一下这些函数头),它在本程序中定义了,那么看懂这些是必需的,不过同时我也发现,在这些函数中,也调用了其他的一些函数(如:cli(),sti(),sleep_on(),wake_up(),printk(),panic(),bread()等等),而这些函数呢,在本程序中却没有定义,只是直接拿来调用它了,开始是用点糊涂,一下子间反应不过来是怎么回事,后来问了熊老师,他的讲解,让我顿间明白过来,也想起自己以前也编写过的像这种把所有的子程序,综合起来运行,那就是把一些需要共享的函数的函数头放到头文件中,当哪个子程序需要调用它们时,只需要加载相应的头文件即可。最终这些函数在头文件(第11章)都能够找到。(有注解,所以我能看的懂)。类似的道理,一些在此程序中没有定义的数据结构,在头文件中也都有定义。在最初不断地浏览整个程序的过程中,也遇到了一些问题,虽然有注解,但是注解中的有些词汇(名词),却不知道是什么意思,同时我注意到,inode.c程序只是文件系统源代码的一部分,而文件系统中的各个子程序也有交叉,所以我现在要明白,不能孤立地看这个程序,而是要是发现不懂的地方,可以到别的程序中找答案,例如:超级块:超级块中主要存放了有关整个文

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论