Linux VFS V

一个文件系统获得了内核的支持,仅仅是功能上的可能性,如果要使用,还需要将其mount到rootfs下,才能可见并进而被使用,本文主要讨论mount的实现过程。

bdev文件系统在其初始化时就已经挂载到内核。

Linux VFS IV

在Linux内核中,一个文件系统包括两部分,一部分是位于磁盘上的管理数据,即文件系统的本体,另一部分是位于内核中的代码,即对VFS中相应接口的实现,没有这部分实现,内核无法识别该文件系统,如此mount、读写等操作也就无从谈起了。

向内核中添加一个文件系统的支持,与其实例无关,即两个分区都是ext4文件系统,但内核对于ext4的支持的代码只需要执行一次,而且,此时也没有从磁盘读取任何数据,这是mount的工作。

本文主要整理内核对各个文件系统的初始化代码

devtmpfs

sysfs

proc

ext4

bdev

注意到bdev文件系统在初始化时已经挂载

Linux VFS III

open()的最终目的是:准备好file以及依赖的数据结构。为此,open()主要做了以下几方面工作:

  1. PathWalk找到目标文件
  2. 构造并初始化inode
  3. 构造并初始化file

其中,PathWalk已经讨论过,本文主要聚焦inode和file的构造和初始化

Linux VFS II

PathWalk,顾名思义,就是根据路径找到目标的文件或目录,作为每次open()或opendir()都要执行的过程,其重要性不言而喻。

PathWalk中的很重要的一个概念就是nameidata,这个对象可以看作是PathWalk过程的上下文的封装,记录当前查找所用的路径,如果查找结束,则记录最终的目标路径。作为”上下文”,其主要工作就是封装了在一个过程中各个子逻辑都需要的信息,并随着过程的进行贯穿于各个子过程供其在需要时使用。

在内核中,PathWalk的主要逻辑整理如下

这段逻辑使用上下文nameidata对象作为PathWalk过程中局部的全局变量,实现递归的目录搜索。

Linux VFS I

为了实现VFS的设计目的 – 抽象出文件系统的共性,作为抽象,VFS不但打通了上下的通道,还打通了文件系统之间的通道,就像当下流行的”云”,将各种设备(文件系统)和系统联系到一起。在VFS中,有6个关键类:inode,dentry,file,super_block,vfs_mount和file_system_type,整个VFS”大厦”的建造都是围绕这6个”支柱”的。

这几个数据结构的实现都**“include/linux/fs.h”**中,下面这张图简要的描述了本文介绍这几个对象及其关系

super_block

–1326–>s_blocksize_bits;当块大于256byte时,块大小是2的多少次幂,比如块大小是512时,就是9
–1327–>s_blocksize;块的大小,这两个域参见sb_set_blocksize()
–1328–>file_system_type对象指针,该super_block对象表示的具体的文件系统类型,内核使用指针链表管理所有的file_system_type对象,其中有将一个mount一个文件系统回调接口
–1330–>和inode,file,dentry等一样, super_block”类”也封装了自己的操作方法集
–1334–>这个文件系统挂载到根目录时的flag,比如MS_RDONLY表示只读挂载etc。同样定义在fs.h
–1336–>不同文件系统的魔幻数,比如ramfs的RAMFS_MAGIC,ext4的EXT4_SUPER_MAGIC,定义在“include/linux/magic.h”
–1337–>文件系统的根目录,即mount一个目录到目录树时,该文件系统的挂载点在目录树的dentry对象
–1348–>使用NFS时的导出dentry
–1350–>文件系统的block_device对象指针
–1351–>文件系统的backing_dev_info对象指针
–1352–>MTD设备的。。。
–1362–>文件系统私有数据
–1380–>
–1427–>文件系统stack的深度
–1431–>该super_block管理的所有的inode对象链表
–1434–>该super_block管理的所有的回写inode对象链表

实际磁盘的文件都是由文件系统管理的,文件系统挂载到VFS上之后,内核想要从磁盘上获取这个文件,就要按照事前的约定,从磁盘头读取相应文件系统的信息,比如类型,分区,校验码等,叫做文件系统的super block信息,可以看作是整个文件系统的元数据的容器,只有读取到super block,内核才能正确的进行接下来的操作。对于ext4文件系统,super block按照内核struct ext4_super_block的格式存储在相应分区,内核使用struct ext4_super_block描述该super block信息并进一步将其封装到VFS super_block中。

inode

Continue reading