- 最近在看ext4系统的extent相关内容
- 对于文件系统,每个文件会对应一系列磁盘块,通过在inode中有序的存放磁盘块号,也就保存下了<文件逻辑块号, 磁盘块号>的映射关系
- 一个文件的逻辑块号必然是连续的,而磁盘块号则不必连续
- 通常一个block大小为4KB,所以一个比较大的文件,就需要存相当多的块号——而这是一个十分笨拙的办法
- 对于很大的文件,有一种解决办法就是间接存放块号,也就是说inode中有部分块号指向的block不是存放这个file的数据,而是存放块号——即一种间接寻址的逻辑。通常会包括三级,一部分直接指向文件的数据块,一部分指向存有块号的块,一部分指向存有“存有块号的块的块号”的块,哈哈
- 而ext4采用的办法是使用extent来保存<文件逻辑块号, 磁盘块号>的映射关系:一个extent对应一系列连续的块号,故可以想到,一个extent最基本的几个域有——文件逻辑块号,起始磁盘块号,块数量
- ext4中一个inode可以直接存放4个extent
- 对于很大的文件,ext4采用extent_tree的方式,其本质同样是一种间接寻址的关系
- 那接下来就详细道来
术语简介
- 磁盘块:块设备对磁盘的一个抽象,对于文件系统而言,磁盘就是一个一个连续的块,每个块通常大小为4KB,并且磁盘块有序编码,每个块对应有一个磁盘块号
- 文件逻辑块号:从逻辑上讲,一个文件可以看做一系列连续的数据块,每个数据块的大小和磁盘块大小相同;
- 从物理上讲,一个文件可以对应磁盘上若干个磁盘块,这些磁盘块可以在物理上不连续。
- 逻辑快号和磁盘块号的对应关系,很像虚拟地址和物理地址的关系:文件给你的感觉就是连续的数据,也就是连续的逻辑块,但实际上文件对应的磁盘块是可以不连续的,也就是不连续的物理块
- inode:保存文件的元数据,元数据可以描述一个文件
- 很可惜inode里没有一下子就能想到的filename。关于filename下一节会讲到
- 一个inode最基本也最重要的信息就两个
- 用来标识inode的inode号,每个inode都不一样
- 用来指明这个文件对应着哪些磁盘块的信息——即逻辑块号和磁盘块号的对应关系
从文件名到磁盘块
- 前面有提到,inode存放文件元数据,但是并没有存放filename——那么ext4是如何把一个filename和一个inode绑定在一起呢?
- 也就是说存在一个filename和inode号之间的对应关系,而这个关系也是存放在一个文件里——目录文件。如根目录
/
就是一个文件,这个文件也对应一个inode,文件的数据就是根目录下的文件名和对应的inode号
简略的过程
- 基于文件系统,我们看到的就是一个个文件,比如我现在有一个文件
/home/niugen/testfile
$ pwd
/home/niugen
$ echo 'This is a test file for learning ext4' > testfile
$ cat testfile
This is a test file for learning ext4
- 当我们输入
cat testfile
时,cat命令接收到testfile
参数,进而根据当前工作目录计算出这个文件的绝对路径为/home/niugen/testfile
- 解析这个路径,首先是
/
即根目录,根目录这个文件对应的inode号固定为2,所以可以直接找到根目录的inode
- 根据根目录的inode中存放的磁盘块号信息,可以知道数据存放在哪些磁盘块中,于是从这些磁盘块里读出数据
- 目录文件的数据,简单的看来就是一个表,有两列,一列是文件名,一列是对应的inode号。对于根目录,文件名就是常见的
dev、usr、home
等等,于是找到了home
对应的inode号
- 于是读出了
/home
这个文件的inode,发现这也是一个目录文件,继续读出数据,找到niugen
对应的inode号
- 于是读出了
/home/niugen
这个文件的inode,发现这还是一个目录文件,继续读出数据,找到testfile
对应的inode号
- 于是读出了
/home/niugen/testfile
这个文件的inode,发现这是一个普通文件,可以使用cat命令,于是读出数据并打印在屏幕上
实际的过程