




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第第10章章 Linux文件系统文件系统 10.1Linux文件系统的特点与文件类别10.1.1 特点特点 10.1.2文件类型文件类型 10.2Linux的虚拟文件系统 10.2.1 虚拟文件系统VFS框架VFSMINIXEXT2MSDOS进程管理、内存管理子系统VFS 是一种软件机制,也许称它为是一种软件机制,也许称它为 Linux 的文件系的文件系统管理者更确切点,与它相关的数据结构只存在统管理者更确切点,与它相关的数据结构只存在于物理内存当中。所以在每次系统初始化期间,于物理内存当中。所以在每次系统初始化期间,Linux 都首先要在内存当中构造一棵都首先要在内存当中构造一棵 VFS 的
2、目录的目录树树(在在 Linux 的源代码里称之为的源代码里称之为 namespace),实际,实际上便是在内存中建立相应的数据结构。上便是在内存中建立相应的数据结构。VFS 目录目录树在树在 Linux 的文件系统模块中是个很重要的概念,的文件系统模块中是个很重要的概念,希望读者不要将其与实际文件系统目录树混淆,希望读者不要将其与实际文件系统目录树混淆,VFS 中的各目录其主要用途是用来提供实际文件中的各目录其主要用途是用来提供实际文件系统的挂载点,当然在系统的挂载点,当然在 VFS 中也会涉及到文件级中也会涉及到文件级的操作,本文不阐述这种情况。一种可能的目录的操作,本文不阐述这种情况。一
3、种可能的目录树在内存中的影像:树在内存中的影像:10.2.2 Linux虚拟文件系统的数据结构 1. VFS的超级块 super_block2. 索引节点 inode3. 文件 file 4. 目录项目录项dentry 10.2.3VFS的系统调用 10.3文件系统的注册和挂装文件系统的注册和挂装 10.3.1文件系统注册文件系统注册 这里的文件系统是指可能会被挂载到目录树中的各个实际文件系统,所谓实际文件系统,即是指VFS 中的实际操作最终要通过它们来完成而已,并不意味着它们一定要存在于某种特定的存储设备上。比如在笔者的 Linux 机器下就注册有 “rootfs”、“proc”、“ext2
4、”、“sockfs” 等十几种文件系统。 数据结构 在 Linux 源代码中,每种实际的文件系统用以下的数据结构表示: 10.3.2已挂装文件系统描述符链表 10.3.3挂装根文件系统挂装根文件系统 注册注册 rootfs 文件系统文件系统 在众多的实际文件系统中,之所以单独介绍在众多的实际文件系统中,之所以单独介绍 rootfs 文件系文件系统的注册过程,实在是因为该文件系统统的注册过程,实在是因为该文件系统 VFS 的关系太过密的关系太过密切,如果说切,如果说 ext2/ext3 是是 Linux 的本土文件系统,那么的本土文件系统,那么 rootfs 文件系统则是文件系统则是 VFS 存
5、在的基础。一般文件系统的注存在的基础。一般文件系统的注册都是通过册都是通过 module_init 宏以及宏以及 do_initcalls() 函数来完成函数来完成(读者可通过阅读读者可通过阅读module_init 宏的声明及宏的声明及 archi386vmlinux.lds 文件来理解这一过程文件来理解这一过程),但是,但是 rootfs 的的注册却是通过注册却是通过 init_rootfs() 这一初始化函数来完成,这意味这一初始化函数来完成,这意味着着 rootfs 的注册过程是的注册过程是 Linux 内核初始化阶段不可分割的内核初始化阶段不可分割的一部分。一部分。 init_roo
6、tfs() 通过调用通过调用 register_filesystem(&rootfs_fs_type) 函数来完成函数来完成 rootfs 文件系统注册的,其中文件系统注册的,其中rootfs_fs_type 定定义如下:义如下:VFS 目录树的建立目录树的建立 既然是树,所以根是其赖以存在的基础,本节阐述既然是树,所以根是其赖以存在的基础,本节阐述 Linux 在初始化阶段是如何建立根结点的,即在初始化阶段是如何建立根结点的,即 /目录。目录。这其中会包括挂载这其中会包括挂载 rootfs 文件系统到根目录文件系统到根目录 / 的具体的具体过程。构造根目录的代码是在过程。构造根目录的
7、代码是在 init_mount_tree()() 函函数数 (fsnamespace.c) 中。中。 首先,首先,init_mount_tree() 函数会调用函数会调用 do_kern_mount(rootfs, 0, rootfs, NULL) 来挂载前来挂载前面已经注册了的面已经注册了的 rootfs 文件系统。这看起来似乎有点奇文件系统。这看起来似乎有点奇怪,因为根据前面的说法,似乎是应该先有挂载目录,怪,因为根据前面的说法,似乎是应该先有挂载目录,然后再在其上挂载相应的文件系统,然而此时然后再在其上挂载相应的文件系统,然而此时 VFS 似似乎并没有建立其根目录。没关系,这是因为这里我
8、们调乎并没有建立其根目录。没关系,这是因为这里我们调用的是用的是 do_kern_mount(),这个函数内部自然会创建我,这个函数内部自然会创建我们最关心也是最关键的根目录们最关心也是最关键的根目录(在在 Linux 中,目录对应中,目录对应的数据结构是的数据结构是 struct dentry)。 在这个场景里,在这个场景里,do_kern_mount() 做的工作主要是:做的工作主要是: 1)调用)调用 alloc_vfsmnt() 函数在内存里申请了一块该类型函数在内存里申请了一块该类型的内存空间(的内存空间(struct vfsmount *mnt),并初始化其部分),并初始化其部分成
9、员变量。成员变量。 2) 调用调用 get_sb_nodev()() 函数在内存中分配一个超级块函数在内存中分配一个超级块结构结构 (struct super_block) sb,并初始化其部分成员变量,并初始化其部分成员变量,将成员将成员 s_instances 插入到插入到 rootfs 文件系统类型结构中的文件系统类型结构中的 fs_supers 指向的双向链表中。指向的双向链表中。 3) 通过通过 rootfs 文件系统中的文件系统中的 read_super 函数指针调用函数指针调用 ramfs_read_super() 函数。还记得当初注册函数。还记得当初注册rootfs 文件文件系
10、统时,其成员系统时,其成员 read_super 指针指向了指针指向了 ramfs_read_super() 函数,参见图函数,参见图2. 4) ramfs_read_super() 函数调用函数调用 ramfs_get_inode() 在内在内存中分配了一个存中分配了一个 inode 结构结构 (struct inode) inode,并初,并初始化其部分成员变量,其中比较重要的有始化其部分成员变量,其中比较重要的有 i_op、i_fop 和和 i_sb: 5) ramfs_read_super() 函数在分配和初始化了函数在分配和初始化了 inode 结构之结构之后,会调用后,会调用 d_
11、alloc_root() 函数来为函数来为 VFS的目录树建立起关的目录树建立起关键的根目录键的根目录 (struct dentry)dentry,并将,并将 dentry 中的中的 d_sb 指指针指向针指向 sb,d_inode 指针指向指针指向 inode。 6) 将将 mnt 中的中的 mnt_sb 指针指向指针指向 sb,mnt_root 和和 mnt_mountpoint 指针指向指针指向 dentry,而,而 mnt_parent指针则指指针则指向自身。向自身。 这样,当这样,当 do_kern_mount() 函数返回时,以上分配出来的各函数返回时,以上分配出来的各数据结构和数
12、据结构和 rootfs 文件系统的关系将如上图文件系统的关系将如上图 3 所示。所示。VFS 下目录的建立下目录的建立 为了更好地理解为了更好地理解 VFS,下面我们用一个实际例子来看看,下面我们用一个实际例子来看看 Linux 是如何在是如何在 VFS 的根目录下建立一个新的目录的根目录下建立一个新的目录 /dev 的。的。 要在要在 VFS 中建立一个新的目录,首先我们得对该目录进行搜中建立一个新的目录,首先我们得对该目录进行搜索,搜索的目的是找到将要建立的目录其父目录的相关信息,索,搜索的目的是找到将要建立的目录其父目录的相关信息,因为因为皮之不存,毛将焉附皮之不存,毛将焉附。比如要建立
13、目录。比如要建立目录 /home/ricard,那么首先必须沿目录路径进行逐层搜索,本例中先从根目录找那么首先必须沿目录路径进行逐层搜索,本例中先从根目录找起,然后在根目录下找到目录起,然后在根目录下找到目录 home,然后再往下,便是要新,然后再往下,便是要新建的目录名建的目录名 ricard,那么前面讲得要先对目录搜索,在该例中,那么前面讲得要先对目录搜索,在该例中便是要找到便是要找到 ricard 这个新目录的父目录,也就是这个新目录的父目录,也就是 home 目录所目录所对应的信息。对应的信息。 当然,如果搜索的过程中发现错误,比如要建目录的父目录并当然,如果搜索的过程中发现错误,比如
14、要建目录的父目录并不存在,或者当前进程并无相应的权限等等,这种情况系统必不存在,或者当前进程并无相应的权限等等,这种情况系统必然会调用相关过程进行处理,对于此种情况,本文略过不提。然会调用相关过程进行处理,对于此种情况,本文略过不提。这里的大体过程是:新分配了一个这里的大体过程是:新分配了一个 struct dentry 结构的内存空间,用于记录结构的内存空间,用于记录 dev 目录所对应目录所对应的信息,该的信息,该dentry 结构将会挂接到其父目录中,也结构将会挂接到其父目录中,也就是图就是图 3 中中 / 目录对应的目录对应的 dentry 结构中,由链结构中,由链表实现这一关系。接下
15、来会再分配一个表实现这一关系。接下来会再分配一个 struct inode 结构。结构。Inode 中的中的 i_sb 和和 dentry 中的中的 d_sb 分别都指向图分别都指向图 3 中的中的 sb,这样看来,在同一文件,这样看来,在同一文件系统下建立新的目录时并不需要重新分配一个超级系统下建立新的目录时并不需要重新分配一个超级块结构,因为毕竟它们都属于同一文件系统,因此块结构,因为毕竟它们都属于同一文件系统,因此一个文件系统只对应一个超级块。一个文件系统只对应一个超级块。 这样,当调用这样,当调用 sys_mkdir 成功地在成功地在 VFS 的目录树中新建立的目录树中新建立一个目录一
16、个目录 /dev 之后,在图之后,在图 3 的基础上,新的数据结构之的基础上,新的数据结构之间的关系便如图间的关系便如图 4 所示。图所示。图 4 中颜色较深的两个矩形块中颜色较深的两个矩形块 new_inode 和和 new_entry 便是在便是在sys_mkdir() 函数中新分配函数中新分配的内存结构,至于图中的的内存结构,至于图中的 mnt,sb,dentry,inode 等结构,仍等结构,仍为图为图 3 中相应的数据结构,其相互之间的链接关系不变中相应的数据结构,其相互之间的链接关系不变(图图中为避免过多的链接曲线,忽略了一些链接关系,如中为避免过多的链接曲线,忽略了一些链接关系,
17、如 mnt 和和 sb,dentry之间的链接,读者可在图之间的链接,读者可在图 3 的基础上参看图的基础上参看图 4)。 需要强调一点的是,既然需要强调一点的是,既然 rootfs 文件系统被文件系统被 mount 到了到了 VFS 树上,那么它在树上,那么它在 sys_mkdir 的过程中必然会参与进来,的过程中必然会参与进来,事实上在整个过程中,事实上在整个过程中,rootfs 文件系统中的文件系统中的 ramfs_mkdir、ramfs_lookup 等函数都曾被调用过。等函数都曾被调用过。10.3.4挂装一般文件系统挂装一般文件系统 挂载时使用挂载时使用mount命令:命令:格式:格
18、式:mount -参数参数 设备名称设备名称 挂载点挂载点例子:例子:windows98装在装在hda1分区,同时计算机上还分区,同时计算机上还有软盘和光盘需要挂载。有软盘和光盘需要挂载。# mk /mnt/winc# mk /mnt/floppy# mk /mnt/cdrom# mount -t vfat /dev/hda1 /mnt/winc# mount -t msdos /dev/fd0 /mnt/floppy# mount -t iso9660 /dev/cdrom /mnt/cdrom现在就可以进入现在就可以进入/mnt/winc等目录读写这些文件系统等目录读写这些文件系统了。了。
19、 描述在描述在 VFS 的目录树中向其中某个目录的目录树中向其中某个目录(安装点安装点 mount point)上挂载上挂载(mount)一个文件系统的过一个文件系统的过程。程。 这一过程可简单描述为:将某一设备这一过程可简单描述为:将某一设备(dev_name)上某一文件系统上某一文件系统(file_system_type)安装到安装到VFS目目录树上的某一安装点录树上的某一安装点(dir_name)。它要解决的问。它要解决的问题是:将对题是:将对 VFS 目录树中某一目录的操作转化目录树中某一目录的操作转化为具体安装到其上的实际文件系统的对应操作。为具体安装到其上的实际文件系统的对应操作。
20、 比如说,如果将比如说,如果将 hda2 上的根文件系统上的根文件系统(假设文件系统类型为假设文件系统类型为 ext2)安装到了前一节中新建立的安装到了前一节中新建立的 /dev 目录上目录上(此时,此时,/dev 目录就目录就成为了安装点成为了安装点),那么安装成功之后应达到这样的目的,即:对,那么安装成功之后应达到这样的目的,即:对 VFS 文件系统的文件系统的 /dev 目录执行目录执行 ls 指令,该条指令应能列出指令,该条指令应能列出 hda2 上上 ext2 文件系统的根目录下所有的目录和文件。很显然,文件系统的根目录下所有的目录和文件。很显然,这里的关键是如何将对这里的关键是如何
21、将对 VFS 树中树中 /dev 的目录操作指令转化为的目录操作指令转化为安装在其上的安装在其上的 ext2 这一实际文件系统中的相应指令。所以,接下这一实际文件系统中的相应指令。所以,接下来的叙述将抓住如何转化这一核心问题。在叙述之前,读者不妨来的叙述将抓住如何转化这一核心问题。在叙述之前,读者不妨自己设想一下自己设想一下 Linux 系统会如何解决这一问题。记住:对目录或系统会如何解决这一问题。记住:对目录或文件的操作将最终由目录或文件所对应的文件的操作将最终由目录或文件所对应的 inode 结构中的结构中的 i_op 和和 i_fop 所指向的函数表中对应的函数来执行。所以,不管最终解所
22、指向的函数表中对应的函数来执行。所以,不管最终解决方案如何,都可以设想必然要通过将对决方案如何,都可以设想必然要通过将对 /dev 目录所对应的目录所对应的 inode 中中 i_op 和和 i_fop 的调用转换到的调用转换到 hda2 上根文件系统上根文件系统 ext2 中中根目录所对应的根目录所对应的 inode 中中 i_op 和和 i_fop 的操作。的操作。 为了帮助读者更好地理解这一过程,笔者用一个具体的例为了帮助读者更好地理解这一过程,笔者用一个具体的例子来说明:我们准备将来自主硬盘第子来说明:我们准备将来自主硬盘第 2 分区分区(hda2)上的上的 ext2 文件系统安装到前
23、面创建的文件系统安装到前面创建的 /dev 目录中。那么对于目录中。那么对于 sys_mount() 函数的调用便具体为:函数的调用便具体为: sys_mount(“hda2”,“/dev ”,“ext2”,); 在我们当前的例子中,系统会调用在我们当前的例子中,系统会调用 do_add_mount() 函数来函数来向向 VFS 树中安装点树中安装点 /dev 安装一个实际的文件系统。在安装一个实际的文件系统。在 do_add_mount() 中,主要完成了两件重要事情:一是获得中,主要完成了两件重要事情:一是获得一个新的安装区域块,二是将该新的安装区域块加入了安一个新的安装区域块,二是将该新
24、的安装区域块加入了安装系统链表。它们分别是调用装系统链表。它们分别是调用 do_kern_mount() 函数和函数和 graft_tree() 函数来完成的。这样,当函数来完成的。这样,当 do_kern_mount() 函函数返回时,在图数返回时,在图 4 的基础上,新的数据结构间的关系将如的基础上,新的数据结构间的关系将如图图 5 所示。其中,红圈区域里面的数据结构便是被称做安所示。其中,红圈区域里面的数据结构便是被称做安装区域块的东西,其中不妨称装区域块的东西,其中不妨称 e2_mnt 为安装区域块的指针,为安装区域块的指针,蓝色箭头曲线即构成了所谓的安装系统链表。蓝色箭头曲线即构成了
25、所谓的安装系统链表。 在把这些函数调用后形成的数据结构关系理清楚之在把这些函数调用后形成的数据结构关系理清楚之后,让我们回到本章节开始提到的问题,即将后,让我们回到本章节开始提到的问题,即将 ext2 文件系统安装到了文件系统安装到了 /dev 上之后,对该目录上的上之后,对该目录上的操作如何转化为对操作如何转化为对 ext2 文件系统相应的操作。从图文件系统相应的操作。从图 5上看到,对上看到,对 sys_mount() 函数的调用并没有直接改函数的调用并没有直接改变变 /dev 目录所对应的目录所对应的 inode (即图中的即图中的 new_inode变量变量)结构中的结构中的 i_op
26、 和和 i_fop 指针,而且指针,而且 /dev 所所对应的对应的 dentry(即图中的即图中的 new_dentry 变量变量)结构仍然结构仍然在在 VFS 的目录树中,并没有被从其中隐藏起来,相的目录树中,并没有被从其中隐藏起来,相应地,来自应地,来自 hda2 上的上的 ext2 文件系统的根目录所对文件系统的根目录所对应的应的 e2_entry 也不是如当初笔者所想象地那样将也不是如当初笔者所想象地那样将 VFS 目录树中的目录树中的 new_dentry 取而代之,那么这之取而代之,那么这之间的转化到底是如何实现的呢?间的转化到底是如何实现的呢? 10.3.5卸载文件系统卸载文件
27、系统10.4进程与文件系统的联系进程与文件系统的联系 10.4.1系统打开文件表系统打开文件表 10.4.2用户打开文件表用户打开文件表 10.4.3进程的当前目录和根目录进程的当前目录和根目录 在2.4中,单独定义在include/linux/fs_struct.h中: struct fs_struct atomic_t count; rwlock_t lock; int umask; struct dentry * root, * pwd, * altroot; struct vfsmount * rootmnt, * pwdmnt, * altrootmnt; ;10.5ext2文件系统
28、文件系统 10.5.1ext2文件系统的存储结构文件系统的存储结构 图10.1Ext2逻辑磁盘结构 10.5.2ext2文件系统主要的磁盘数据结构文件系统主要的磁盘数据结构 2. ext2的块组描述符的块组描述符 3. 块位图和索引节点位图 4. ext2文件系统的磁盘索引节点文件系统的磁盘索引节点 ext2_inode 10.5.3ext2文件系统的内存数据结构 1. ext2的内存超级块 2. ext2的内存索引节点的内存索引节点 10.5.4数据块寻址 10.6.1设备配置 mknod /dev/tty1 c 4 1 我们再来看下什么是主次设备号。我们再来看下什么是主次设备号。 我们在使
29、用设备是是通过我们在使用设备是是通过/dev下的设备文下的设备文件来使用文件,例如,我们要从第一个硬盘中件来使用文件,例如,我们要从第一个硬盘中读取一个扇区的字节,我们首先就会调用读取一个扇区的字节,我们首先就会调用open打开打开/dev/hda,然后用,然后用read来读取,但我们的系来读取,但我们的系统可不是通过设备名来操做的,我们的系统是统可不是通过设备名来操做的,我们的系统是通过主次设备号来认识和操作我们的设备的。通过主次设备号来认识和操作我们的设备的。10.6块设备驱动块设备驱动 系统有两个系统有两个sata的硬盘和两个的硬盘和两个sata的的usb移动硬移动硬盘,在盘,在/dev/目录下,运行目录下,运行 ls -l来查看我们的设备来查看我们的设备 大家可以看到我的大家可以看到我的sda的主设备号是的主设备号是8,次设备号是,次设备号是0,而,而sdb、sdc和和sdd的硬盘的主次设备号分别是的硬盘的主次设备号分别是8:16,8:32和和8:48,而而sda1是分区,主次设备号是是分区,主次设备号是8:1。为什么会有这样的主次设。为什么会有这样的主次设备号呢,这又是怎么定义的呢。各种设备的主次设备号,应该备号呢,这又是
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年智能用电系统产品合作协议书
- 合伙经营铲车合同范本
- 土壤改良工程填土施工合同范本
- 剧组法律顾问合同范本
- 合伙运输协议合同范本
- 商品陈列协议合同范本
- 各类广告合同范本
- 厂房喷漆合同范本
- 俱乐部管理合同范本
- 厨师和饭店合同范本
- 排水管道施工组织设计排水管道施工组织设计排水施工排水管道施工施工设计
- 人工智能科普教育活动方案设计
- 2024未来会议:AI与协作前沿趋势白皮书
- 2024年广东普通专升本《公共英语》完整版真题
- 国家中长期科技发展规划(2021-2035)
- 中国民族音乐的宫庭音乐
- 单原子催化剂的合成与应用
- 水利工程施工验收规范对工程监理单位的要求
- 五年级上册小数乘除练习300道及答案
- 《新概念英语第二册》电子书、单词、笔记、练习册(附答案)汇编
- Midea美的F50-22DE5(HEY)电热水器说明书
评论
0/150
提交评论