请你将下面描述这个文件打开详细过程的卡片排成正确的顺序如何获得文件系统(fs)一般是操作系统(os)自带的参考资料电子书,practical-file-system-design.pdfO'Reilly.Understanding.the.Linux.Kernel.3rd.Edition.chmPr" />

fs-whatwhy

引子问题

先看下面这段php打开文件的代码

$handle = fopen ("/usr/jinwei/file.txt", "r");

……

?>

请你将下面描述这个文件打开详细过程的卡片排成正确的顺序

如何获得

文件系统(fs)一般是操作系统(os)自带的

参考资料

电子书,

practical-file-system-design.pdf

O'Reilly.Understanding.the.Linux.Kernel.3rd.Edition.chm

Prentice.Hall.Operating.Systems.Design.and.Implementation.3rd.Edition.Jan.2006.chm Prentice.Hall-Solaris.Internals.Solaris.10.and.OpenSolaris.Kernel.Architecture.Second.Edition. chm

The Design and Implementation of the FreeBSD Operating System.chm

fs_performance.pdf

网址,

谁是专家/可以问谁

朱岩

分机:5809

Email:zhuyan@https://www.360docs.net/doc/2317299251.html,

msn:twochars@https://www.360docs.net/doc/2317299251.html,

阅读前提条件

1.引子问题没能回答and

2.有os,数据结构基础,有指针的概念and

3.使用过linux下文件相关操作

注:以下讨论基于linux下的磁盘文件系统(disk-based filesystems)

第一个层次

解释的问题:什么是文件系统

先看个大图,

图1. 信息大树-文件系统-物理介质关系图

图解:

首先,图的左边把现实世界真实的文件,文件夹,及他们间的关系抽象理解为一棵倒挂的信息大树,树结点是包含了文件(夹)名及其内容的信息,这棵信息大树是逻辑的,真实存于我们心中的

其次,图的右边把真实的磁盘抽象理解为一个大的01串,这个理解将贯穿本文

于是,图的中间所指文件系统就是将信息大树及其操作正确映照到存储介质上的接口人。

承上理解,我们来看看用户的文件需求是怎样被文件系统实现的?

想想我们对信息大树的需求都有什么?也就是说我们都要对文件的做啥操作?

找个文件?看个文件有啥?找个目录?看个目录有啥文件?删个文件……..如此等等这里,我们可以把目录理解为包含文件名和位置信息的文件(文件系统实现也是这样理解的),于是上述的需求简单归成两个过程:

①在信息树上找个树节点(文件)–-〉②看内容/改内容/加新的点/去了它这个点…等

我们熟知的实现的这个需求的操作是什么?也就是我们都是怎样通过计算机操作文件的?

shell命令?php的文件操作接口?c语言的文件操作接口?…….如此等等

这些操作如何能够实现我们的需求,我们通过一个图来做详细说明,

图2. 从用户到真实文件系统之间

总结一下,

如果将上面提到的应用程序文件操作接口(如php),语言库(如c库),os的文件操作接口(系统调用)理解为文件系统对外延伸的接口,那么可以认为文件系统提供了一个对外的接口函数,以便实现我们对信息大树的需求

信息大树相关需求实现= fs (人可识别的路径名[根到节点的路](fd),对参数1的操作名)

发散提问:

?为什么文件系统是树状的

一个实例:

$ cp /floppy/TEST /tmp/test

插图1 shell命令cp的执行过程

拷贝两个文件是我们的需求

cp是shell的文件操作接口

(a)说明了VFS是真实文件系统对外的接口

(b)说明了真实的系统调用过程

最关键词

[信息大树]

第二个层次

解释的问题:文件系统怎样实现

承上所述,VFS 的角色是文件系统对外的接口人,我们来看操作系统运行时,用户-进程-系统调用-VFS-真实fs-磁盘-信息大树的内存表示等等参与文件相关操作的角色是怎样的关系,VFS又是怎样在此间扮演灵魂人物的

先看一个系统运行时的大图:

图3 操作系统运行时文件相关关系图

图解(图上已标号):

1.内存树(图中间偏上部分)

目录项(dentry),目录项是文件和目录信息在内存的抽象,指向索引节点,自带操作指针指

向对应文件系统dentry操作

?为什么要有目录项对象

索引节点(inode),inode是实际磁盘inode的内存抽象,实际inode是实际磁盘文件内容的描述者,索引者,内存inode自带操作指针指向对应文件系统inode操作,带文件操作指针指向应文件系统file操作,带有可直接寻到磁盘文件的指针,

小结,目录项,索引节点组成了一棵树,是外部的信息大树的内存表示,也是磁盘文件信息的内存表示,我们且叫为内存树,因为每个目录项,索引节点都带着实际文件系统的函数指针,这样,vfs在内存树查找文件完成后就可以把正确的文件操作指针安装到文件对象上, 对目录项,索引节点本身的操作也可以经此正确寻到方法

2.真实文件系统和vfs的关系(图右部)

超级块(super block)信息,sb是实际磁盘sb的内存抽象, 实际磁盘sb是实际文件系统的描述者,

ext3实际fs,在此代表实际fs的实现,对外的接口是超级块(super_block),索引节点(inode),目录项(dentry),文件对象的函数指针,这四者的函数操作指针认为是实际fs对外的总接口,也是vfs对所有实际fs实现的标准协议

mount节点,vfs和实际fs的接口人,真实文件系统地文件树被挂在mount点下,mount点作为实际fs在内存树的代言人,当vfs读写内存树时,负责告知vfs,在mount点以下的节点需要切换到一套对应的操作函数上

?为什么要有mount点

小结,以上三个保证了实际fs的操作能正确地被vfs,os中的内存树,进程获知,保证实际fs的信息能被vfs获知

2.进程如何能操作文件(图左部)

系统调用,进程与os的接口人,进程做文件操作唯一接口

进程,文件操作需求者,手持fd,指向文件对象

?为什么要有fd

文件对象,文件信息在进程里的描述,vfs给进程的接口人,指示对应的目录项位置,

指示对应文件操作函数指针位置

小结,进程拿着fd通过vfs操作文件,而vfs通过fd指向的文件对象找到文件的内存表示(目录项指针),找到实际文件系统操作该文件的函数(对应文件操作函数指针)

4.Vfs如果维护上述三者的关系,起到灵魂作用(图下部)

vfs,抽象的文件系统,维护进程(系统调用)/文件树内存表示/实际fs之间的关系进程一切文件操作通过vfs,vfs在文件打开时把操作指针和文件内存位置告诉进程(fd)实际fs的实现必须遵守vfs的协议(四种数据结构和操作方法),vfs通过超级块读fs信息,通过mount节点和mount操作将实际fs注册到内存树上,通过mount点和fs对外函数

指针将fs内部操作方法注册到内存树和进程文件对象上

内存树表示,是vfs的数据结构,是信息大树和磁盘文件的操作系统运行时内存表示,文件的寻路时,文件系统的注册,文件的磁盘信息内存表示,进程文件对象的注册,vfs都需要读写这颗树

小结以下,将Vfs理解为函数的话,则数据结构是内存树,调用的子函数是实际fs的操作函数指针

于是

系统调用实现= vfs(人可识别的路径名[根到节点的路](fd),对参数1的操作名)

{

读写内存树

调用实际fs的api(在树上注册了函数指针)

读写内存树(包括注册上那些函数指针)

}

?为什么要有vfs

最关键词

[内存树]

实际文件系统实现

承上所述,vfs维护了运行时文件内存关系,维护了和进程的关系,这样实际文件系统的实现,我们且理解为就是实现那4种数据结构和这些结构的操作函数,并以此维护磁盘上的数据结构

具体的以ext2文件系统为例,看它的磁盘数据结构是如何组织

先看一个大图:

图4 ext2文件系统磁盘组织图

简单图解:

super block 是文件系统的super block在这个组的拷贝,是文件系统整体信息的表示

group descriptors 描述改组的信息,比如第一个Inode bitmap数据块位置

data block bitmap 表明数据块使用情况,以bit位表示已用/未用

inode bitmap 表明inode的使用情况,以bit位表示已用/未用

inode table 存储inode信息,每个inode用唯一的inode号指示

data blocks 存储文件内容

除了inode table 和data blocks以外的块都是用于维护整个文件系统的,我们抛开这些信息,抛开磁盘分组的概念,看一下最本质的由inode和磁盘块组成的文件关系是如何的,

图5 文件系统在磁盘上真实的关系图

如图,我们从根inode出发,将目录文件的内容展开并指向目录下文件的inode的,我们发现在磁盘上也是一棵树,我们且称其为磁盘树

最关键词

[磁盘树]

附:信息大树-内存树-磁盘树的关系

图6 信息大树-内存树-磁盘树的关系图

如图,当操作系统运行时,所有文件的操作导致磁盘树被部分的拉起,成为内存树,如果我们想象把它全拉起来,就是我们心中的信息大树

第三个层次

解释的问题:文件打开操作细节

我们仍然以引子问题作例

$handle = fopen ("/usr/jinwei/file.txt", "r");

……

?>

开始,

↓Php解析器解析fopen函数 [参见php(图2)]

↓C语言库文件接口open函数[参见c(图2)]

↓Os系统调用接口open函数[参见系统调用(图2)]

↓Vfs的接口sys_open 函数[linux/fs/open.c 977行]

↓Vfs文件名-inode对应关系寻找开始open_namei函数[linux/fs/open.c 830行]

↓Vfs解析路径开始path_lookup函数[linux/fs/namei.c 1021行]

↓Vfs 找到根目录项[linux/fs/namei.c 1030行(内存树)]

↓Vfs在内存树上读取usr对应目录项[linux/fs/namei.c 731行(根文件系统)]

↓Vfs发现usr是一个mount点,切换文件系统操作函数[linux/fs/namei.c 731行(usr对应文件系统)]

↓Vfs 在usr目录项下找到jinwei目录项[linux/fs/namei.c 731行(内存树)] ↓Vfs 读取jinwei目录[linux/fs/namei.c 731行(usr对应文件系统函数)] ↓Vfs 在jinwei目录下找到file.txt文件[linux/fs/namei.c 731行(usr对应文件系统函数)] ↓Vfs 将file.txt对应的inode,dentry注册到内存树上[linux/fs/namei.c 731行]

↓Vfs 将对应的inode,dentry函数指针指向真实fs的函数指针[linux/fs/namei.c 731行]

↓Vfs路径解析完毕,该路上的inode已初始化在内存树上[linux/fs/namei.c 1021行]

↓Vfs文件名-inode对应关系寻找返回open_namei函数[linux/fs/open.c 830行]

↓Vfs文件对象注册dentry_open 函数[linux/fs/open.c 832行]

↓Vfs返回文件描述符fd [sys_open返回]

↓Os系统调用返回描述符fd

↓C语言库文件接口返回描述符fd

↓Php解析器存储fd并生成对应的操作符变量$handle

结束

?同一目录下的文件名-inode对应关系为什么用b-tree/b+tree实现

?open完了以后的read,write是怎样实现的

?为什么两个进程同时写一个文件会写花

常见问题解答(FAQ)

待补

相关主题
相关文档
最新文档