付费下载
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、execblock devnamei、任层操作函数Linux 0.11文件系统的源码阅读总结1. minix文件系统对于linux 0.11内核的文件系统的开发,Linus主要参考了 Andrew S.Tanenbaum所写的MINIX操作系统设计与实现,使用的是其中的1.0版本的MINIX文件系统。而高速缓冲区的工作原理参见M.J.Bach的UNIX操作系统设计第三章内容。通过对源代码的分析,我们可以将minix文件系统分为四个部分,如下如 1-1。高速缓冲区的管理程序。主要实现了对硬盘等块设备进行数据高速存取的函数。文件系统的底层通用函数。包括文件索引节点的管理、磁盘数据块的分配和释放 以
2、及文件名与i节点的转换算法。有关对文件中的数据进行读写操作的函数。包括字符设备、块设备、管道、常规文件的读写操作,由read_write.c函数进行总调度。涉及到文件的系统调用接口的实现,这里主要涉及文件的打开、关闭、创建以及文件目录等系统调用,分布在namei和inode等文件中。、高层函数 sfcntl 160cti T数据访问openread writeirunciLiebilm高速缓冲管理JbufferVEll nv block、,三zi图1-1文件系统四部分之间关系图1.1超级块首先我们了解一下 MINIX文件系统的组成,主要包括六部分。对于一个360K软盘,其各部分的分布如下图1-
3、2所示:型导块超线块图1-2建有MINIX文件系统的一个360K软盘中文件系统各部分的布局示意图注释1:硬盘的一个扇区是 512B,而文件系统的数据块正好是两个扇区。注释2:引导块是计算机自动加电启动时可由ROM BIOS自动读入得执行代码和数据。注释3:逻辑块一般是数据块的 2嘉次方倍数。MINIX文件系统的逻辑块和数据块同等大小对于硬盘块设备,通常会划分几个分区,每个分区所存放的不同的文件系统。硬盘 的第一个扇区是主引导扇区,其中存放着硬盘引导程序和分区表信息。分区表中得信 息指明了硬盘上每个分区的类型、在硬盘中其实位置参数和结束位置参数以及占用的 扇区总数。其结构如下图1-3所示。-L7
4、号星凶| FAT32系维NTFS文件系统MINIX文件獭m2文件系统; ! 1 1 7! , 1 : : | | ! 1 , ! J ! 1 : : | | | J | 1 1 : ! P ! ! r B | 1 1 B B ! ! 5 | J a图1-3硬盘设备上的分区和文件系统对于可以建立不同的多个文件系统的硬盘设备来说,minix文件系统引入超级块进行管理硬盘的文件系统结构信息。其结构如下图1-4所示。其中,s_ninodes表示设备上得i节点总数,s_nzones表示设备上的逻辑块为单位的总逻辑块数。s_imap_blocks和s_zmap_blocks分别表示i节点位图和逻辑块位图所
5、占用的磁盘块数。s_firstdatazone表示设备上数据区开始处占用的第一个逻辑块块号。s_log_zone_size是使用2为底的对数表示的每个逻辑块包含的磁盘块数。对于 MINIX1.0文件系统该值 为0,因此其逻辑块的大小就等于磁盘块大小。s_magic是文件系统魔幻数,用以指明文件系统的类型。对于 MINIX1.0文件系统,它的魔幻数是 0x137f o字段名称教据美玉脱一rsji inodesshorti节点数short逻盘城数域林田区块数)出现在盘上和 内存中的字段,s_iw_b locksshort节点面图所占块效locksshort逻辑域色图所占块数s_firsidataz
6、oneshort数据区士第一个逻辑块象号-short1 唯(薇蛾数国辑弁long庭大文件长度sjiagicshort文件系跷幻数g困 :s_imap8:buffecr.ed *i节点也留在高速缓冲块指针数里S_ZBBp8buffer_sead 黑逻辑族华图在高速缓冲块指计数组s_devsHort超级块所在设缶号仅在内存中 使目的字段s_isup(n._ i node *被安装文件系统根目荥1节点s._.i mountn_inoce *该文件系统被安装到的i节点imelone修改时间sjAait等待本超级块的进程指针sjockchar顿定标志s_rd_onlychar只读标重s_dirtchar
7、已被修葭(脏)标志图1-4 MINIX 超级块结构对于超级块来说有两个特殊之处:逻辑位图的最低比特位(位 0)闲置不用,并在创建文件系统时会预先置1。I节点位图的最低比特位(位 0)闲置不用,并在创建文件系统时会预先置1因此i节点位图只能表示8191个i节点的状况。1.2 i节点I节点则是用来存放文件的相关信息。对于每个文件或者目录名都有一个i节点,各自i节点结构中存放着对应文件的相关信息。其 i节点的结构(32个字节)如图1-6 所示。其中i_mode字段的是用来保存文件的类型和访问权限属性。其 15-12用于保存文 件类型,为11-9保存执行文件时设置的信息,位 8-0用于设置范文权限。如
8、图 1-5所 示。I节点有一个特殊之处:I节点0是闲置不用的,在文件系统创建时被置宿主 组负 其他人r01 -执行时设置用户ID Cmc-umf-DiL 02 -戌行时设置法1小Loi -时于目录.受混利谨有志.DOl - MH)文件(入道利八002 -字畤修篝文如Y 004 -目录文件:00c -抉设蕃文件】j。:。-常就文件.图1-5 i节点属性字段内容手一名可捐类工谎乐i_Lid囱*1 short文件河类至右二耳件一0位 文怦宿主的用产idiizcImg文华长至f字:汨1 JLtilUfi二口三F修改可闻X1M.LI出时期乩 抄)ndur文件行主或挺id:ChAT疑举殁有霎少人文仁目录以
9、指司诿:7:;i_ZOL划short文件所占用的至上逻辑块号数其必Z:. . -J .:. 是直立答号!zoneL?是一次可接承号:小、/上二次布勇,藤三号:注,gr怡是区内总区,玛泽或区城城法较块. 对于设各特殊文件名汽L恭点.再esKo中 存放沟是部立伴名所指设瞽%设备号.i_waittii*-,七:丁CL ,除他连i节点的道程上1 *:Lg最后访问升:Li_ct;uei节点自发啖愫改打匚i dev 一i_niini_CuUnTslior :三 hor 二 小口:1二i比百通:任.上过翁号,i节点号上 i节立校引用的;大灯,口表示空N0._ Ehri节点枝既定标志口chari道立已坟喙以(
10、里;除志.i.plpgeititri节点.用作登道中志上c*xari下点安装了其他文系统哧本,心,(char搜索标,志 士心,耍心了:,l_Lpdil:ELlari9点匚更新标志.在盘上和内存中 的手段,共32 字节仅在内存中使用 的字段图1-6 MINIX文件系统1.0版的i节点结构宜援京号一次间接块号二次可接余号i 2 one 3i_z(xw41,口口。.5,ZU:I43:Z0:lAME LEN: 文件名 n.I图1-9目录项结构体的定义注释1: 一个逻辑块能存储的目录项 1024/16=64注释2:对于i节点的i_zone0所对应的逻辑块来说,它在初始化时首先存储了 “.”(自己目录的i
11、节点号)和“.”(父目录的i节点号)两个目录,在代码中会有体现,对目录项进行遍历时,会从2开始。图1-10以文件名获取其数据块1.4 高速缓冲区高速缓冲区是文件系统访问块设备中数据的必经之道,它的主要作用如下:将磁盘块中的数据预读到缓冲区,减少对磁盘的频繁访问,提高系统性能。当需要将数据写入到块设备时,则先将数据转存在高速缓冲区中,然后由高速缓冲区通过设备数据同步来实现写入块设备。高速缓冲存放着最近使用过得各个块设备中的数据块。当需要从块设备中读取数据时,缓冲管理程序首先会再高速缓冲中寻找数据。如果在缓冲区,则直接返回数据块的指针,反之,则发出读设备的命令,将磁盘块中得数据读入高数缓冲区。如下
12、图 1-11所示,显示了高速缓冲区位于内核模块和主内存区之间。注释1: end是内核模块链接期间由链接程序ld设置的一个外部变量,内核代码中没有定义这个符号。当在连接生成system 模块时,ld程序设置了 end的地址,它等于 data_start+datasize+bss_size ,即bss段 结束后的第一个有效地址。注释2:高速缓冲区被划分为 1024字节大小的缓冲块,正好与块设备上的磁盘逻辑块大小相同高速缓冲区从物理角度看主要由缓冲块和指向缓冲块的缓冲头组成。其中缓冲头的 结构体为:struct buffer_head char * b_data;指向该缓冲块中数据区(1024字节)
13、的指针unsigned long b_blocknr; / 块号unsigned short b_dev; /数据块的设备号unsigned char b_uptodate; /更新标志,表示设备是否更新unsigned char b_dirt; /修改标志,0-未修改,1-已修改unsigned char b_count; /使用该块的用户数,用于清除数据块时。unsigned char b_lock; / 缓冲区上所标识,0-ok , 1-lockedstruct task_struct * b_wait; / 指向等待使用此缓冲块的进程struct buffer_head * b_pre
14、v; /hash队歹U上块struct buffer_head * b_next; /hash队列下一块struct buffer_head * b_prev_free; /空闲表上一块struct buffer_head * b_next_free; /空闲表下一块);注释1:字段b_dirt是脏标志,说明该缓冲块中得内容是否已修改而与块设备上得对应数据块内容不同 (延迟写)。B_uptodate是数据更新标志,说明缓冲块中数据是否有效。初始化或者释放块时这两个标 志设置为0,表示该缓冲块此时无效。注释2: b_dirt=1,b_uptodate=0 ,数据被写入缓冲块但是还没有被写入设备;
15、b_dirt=0 ,b_uptodate=1 ,数据被写入了设备块或者刚从设备快中读入缓冲块中变成有效;b_dirt=1,b_uptodate=1 ,表示缓冲块和设备快上得数据不同,但是数据还是有效的(更新的)。高速缓冲区采用hash表和空闲缓冲块队列进行操作管理,这也是高速缓冲区从逻 辑上的组成。在缓冲区初始化过程中,初始化程序从整个缓冲区的两端开始,分别同 时设置缓冲头块和划分对应的缓冲块,如图 1-12所示。缓冲头的结构体描述了对应缓 冲块的属性,并且用于把所有的缓冲头连接成一个双向链表结构。如图 1-13所示。注释1: free_list 指针是该链表的头指针,指向空闲块链表中第一个“
16、最为空闲的”缓冲块,即近期最 少使用的块。为了能够快速而有效地在缓冲区中寻找判断出请求的数据块是否已经被读入缓冲区中,buffer.c使用了具有307个buffer_head指针项的hash数组结构。Hash函数采用了设备号和逻辑块号作为参数,具体函数:(设备号人逻辑块号)Mod307。然后通过b_prev、p_next将hash表中散列在同一项上的多个缓冲块练成一个双向链表。通过hash数组实现管理缓冲块的好处是保证了同一设备号的块具有相同的散列值,加速对缓冲区中得块的查询。图1-14所示为某一时刻内核中缓冲块散列队列示意图。谩州头TTT-rTTTTTTTTT般歹.项2酸匕阳307唉产头图1
17、-14某一刻内核中缓冲块散列队列示意图2源码分析这一部分主要从源码fs/目录下的各个文件进行逐个分析,理清它们之间的调用关系,并通过流程图的形式展现其中关键代码的实现。本章可以划分为五大部分:1)高速缓冲管理;2)文件底层操作;3)文件数据访问;4)文件高层访问控制;5)文件 系统的初始化和define变量说明。2.1 高速缓冲管理高速缓冲管理在fs/buffer.c中得到实现。内核程序在使用高速缓冲区中的缓冲块时,是通过制定需要访问的设备号和数据逻辑块号来调用buffer.c的函数。本文件中主要实现这些接口函数:bread (int dev , int block ):快读取函数。bread
18、a (int dev , int block ):块提前预读函数。bread_page (unsigned long address,int dev,int b4): 页块读取函数,它一般可以读取四个缓冲块。所有这些缓冲块数据存取和管理函数的调用层次关系可以用图2-1所描述bread, 打电8, bread_pag(Retblk ) 加segei_hash_tablet find_buffer 等图2-1缓冲区管理函数之间的层次关系其中brelse (struct buffer_head * buf )用来释放指定的缓冲块; get_hash_table (int dev, int block
19、 ) 查询对应的 hash 表项。Find_buffer (int dev, int block )通过hash (dev, block )获取缓存头的地址来遍历缓冲头,找到需 要的目的缓冲头。2.1.1 getblk 函数getblk (int dev,int block )这个函数主要实现了取高速缓冲中得指定的缓冲 区。其实现的流程如下图2-2所示:等待解锁否设置该块的引用计数1, 复位有效和修改标志, 并从散列表和空闲队列 中移除此块getblk已在局速缓冲?置占用该块的设备号、等待解锁是又被人占用?块号返回缓冲头指针图2-2 getblk函数的实现流程Getblk函数的具体实现代码如下
20、:/这行是个宏定义,用于同时判断缓冲区的修改标志和锁定标志,并且定义修改 标志的权重要比锁定标志大(具体是大一倍)。#define BADNESS(bh) (bh)-b_dirtb_lock)struct buffer_head * getblk(int dev,int block) struct buffer_head * tmp, * bh;repeat:/首先判断是否在高速缓冲区中,如果在这直接返回缓冲区指针。if (bh = get_hash_table(dev,block)return bh;tmp = free_list;/通过while循环搜索空闲的缓冲块,选择比重最小的缓冲头指
21、针指向tmp缓冲区头,如果发现tmp既没有被修改有没有被锁定的情况下,则说明以为指定设备上的 块取得对应的高速缓冲区,退出循环。否则知道遍历完整个空闲缓冲块队列。do if (tmp-b_count) continue;if (!bh | BADNESS(tmp)b_next_free) != free_list);/如果没有找到空闲的(连比重最小的也没有),直接睡眠,等待有空闲的缓冲 区可用。if (!bh) sleep_on(&buffer_wait);goto repeat;/如果缓冲块加锁,则等待加锁。wait_on_buffer(bh);/如果缓冲块被人使用,则直接跳至标志repea
22、t重新执行一遍。if (bh-b_count)goto repeat;/通过while循环等待脏数据被完全同步至设备上。每同步完一次,检查一下是 否被人占用,如果占用了,直接返回值 repeat开始。while (bh-b_dirt) sync_dev(bh-b_dev);wait_on_buffer(bh);if (bh-b_count)goto repeat;)/* NOTE! While we slept waiting for this block, somebody else might */* already have added this block to the cache.
23、check it */在高速缓冲hash表中检查指定缓冲区是否已经被加入。如果是的话,就跳至 repeat处执行。if (find_buffer(dev,block)goto repeat;/* OK, FINALLY we know that this buffer is the only one of its kind,*/* and that its unused (b_count=0), unlocked (b_lock=0), and clean */ bh-b_count=1;bh-b_dirt=0;bh-b_uptodate=0;remove_from_queues(bh); /
24、conghash队列和空闲链表中移除该缓冲头,让该缓冲区用于指定设备和其上的指定块。bh-b_dev=dev;bh-b_blocknr=block;insert_into_queues(bh); /然后根据新的设备号和块号重新插入空闲链表和hash队列新位置处。并最终返回缓冲头指针。return bh;)2.1.2 bread 函数根据对getblk ()函数的分析,它最终可能返回了一个新的空闲块,也可能返回 的正好使我们需要数据的缓冲块。对于 bread ()函数来说,通过 getblk ()获取了 新的缓冲块,它就需要判断该缓冲块的更新标志,看看所含数据是够有效,如果有效 就可以直接将该数
25、据块返回给申请的程序,否则就需要调用设备的底层读写函数(ll_rw_block (),并同时让自己进入睡眠状态,等待数据被读入缓冲块。其具体 的流程图如下图2-3所示。图2-3 bread ()函数的实现流程图注释1: breada ()和bread_page ()函数与bread ()实现方式类型,就暂时不做流程图分析的bread ()函数的具体实现代码及分析如下:struct buffer_head * bread(int dev,int block)(struct buffer_head * bh;/ 判断getblk ()是否返回缓冲头指针,如果没有,则打印错误信息。if (!(bh=
26、getblk(dev,block)panic(bread: getblk returned NULLn);/ 判断数据的更新标志,数据有效则返回缓冲头指针if (bh-b_uptodate)return bh;/如果数据无效,则利用底层函数直接从设备上读取数据。ll_rw_block(READ,bh);/等待解锁wait_on_buffer(bh);/判断更新标志位。如果数据无效,释放 bh,返回NULL反之,则返回bhoif (bh-b_uptodate)return bh;brelse(bh);return NULL;2.1.3 remove_from_queues 、 insert_in
27、to_queues 、 find_buffer 和 get_hash_table 函数remove_from_queues和insert_into_queues实现了缓冲头的移出和插入的功能,其具体的实现代码在下面分别进行分析。remove_from_queues/这里是以内联函数实现的,可以加速代码执行速度,免去了函数调用的系统代价。static inline void remove_from_queues(struct buffer_head * bh)/* remove from hash-queue */if (bh-b_next)bh-b_next-b_prev = bh-b_pre
28、v;if (bh-b_prev)bh-b_prev-b_next = bh-b_next;/如果该缓冲区是该队列的头一块,则让hash表的对应项指向本队列中得下一个缓冲区。by chhif (hash(bh-b_dev,bh-b_blocknr) = bh) hash(bh-b_dev,bh-b_blocknr) = bh-b_next; /如果缓冲头是hash队列的链表头,则将hash项指向下一个缓冲头。/* remove from free list */if (!(bh-b_prev_free) | !(bh-b_next_free)panic(Free block list corru
29、pted);bh-b_prev_free-b_next_free = bh-b_next_free;bh-b_next_free-b_prev_free = bh-b_prev_free;if (free_list = bh)free_list = bh-b_next_free;insert_into_queuesstatic inline void insert_into_queues(struct buffer_head * bh)/* put at end of free list */bh-b_next_free = free_list;bh-b_prev_free = free_li
30、st-b_prev_free;free_list-b_prev_free-b_next_free = bh;free_list-b_prev_free = bh;/* put the buffer in new hash-queue if it has a device */bh-b_prev = NULL;bh-b_next = NULL;if (!bh-b_dev) return;/将缓冲头在链表头进行插入。bh-b_next = hash(bh-b_dev,bh-b_blocknr);hash(bh-b_dev,bh-b_blocknr) = bh;bh-b_next-b_prev =
31、bh;对于这两个函数进行分析后发现其插入规则如下:插入到空闲缓冲链表中时,是选择插入到free_list之前一个位置。插入hash队列中,是直接插入到dev对应的hash行所在的链表的头指针处。find_bufferstatic struct buffer_head * find_buffer(int dev, int block)(struct buffer_head * tmp;/首先通过hash (dev, block )所在的hash行链表中,然后对联表进行遍历,如果找到了 dev和block号都相同的缓冲头,指直接返回tmp指针,反之,则返回 NULLfor (tmp = hash(
32、dev,block) ; tmp != NULL ; tmp = tmp-b_next)if (tmp-b_dev=dev & tmp-b_blocknr=block)return tmp;return NULL;get_hash_tablestruct buffer_head * get_hash_table(int dev, int block)(struct buffer_head * bh;/进入一个循环,首先在高速缓冲区中寻找相应的数据块。如果没有找到,直接返回NULL否则对其引用递增1,等待此缓冲块的解锁。如for (;) if (!(bh=find_buffer(dev,block)return NULL;bh-b_count+;wait_on_buffer(bh);/由于经过了睡眠状态,因此有必要再验证一下该缓冲区的正确性,并 返回缓冲头的指针。这都是
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 室内装饰设计师9S考核试卷含答案
- 玻璃退火工复测强化考核试卷含答案
- 煤层气预处理值班员安全实操评优考核试卷含答案
- 农艺工操作水平测试考核试卷含答案
- 一次雷达机务员安全检查测试考核试卷含答案
- 工业炉燃料系统装配工安全理论强化考核试卷含答案
- 燃气轮机运行值班员安全实操竞赛考核试卷含答案
- 2025年东南大学辅导员考试笔试题库附答案
- 2024年涉县辅警招聘考试真题汇编附答案
- 2024年洛阳市税务系统遴选考试真题汇编附答案
- 十八项核心制度(终版)
- 存单质押合同2026年版本
- 实验室生物安全培训内容课件
- 2025-2026学年浙教版七年级科学上册期末模拟试卷
- 北京市怀柔区2026年国有企业管培生公开招聘21人备考题库及答案详解(易错题)
- 2025广东中山城市科创园投资发展有限公司招聘7人笔试参考题库附带答案详解(3卷)
- 火力发电厂机组A级检修监理大纲
- 井喷失控事故案例教育-井筒工程处
- 地源热泵施工方案
- GB/T 16947-2009螺旋弹簧疲劳试验规范
- 硒功能与作用-课件
评论
0/150
提交评论