图解 Linux 文件系统
扫描二维码
随时随地手机看文章
之前我写过有关 Linux 文件系统源码分析的文章,但从源码角度分析文件系统略显枯燥(对新手不友好),所以这次主要通过图文的方式来讲解 Linux 文件系统的原理,而不用陷入源代码的深渊之中。
一、硬盘简介 在介绍文件系统前,我们先来了解一下 硬盘
众所周知,内存在断电后数据就会丢失,所以现代计算机都通过 硬盘
来进行数据存储。也就是说,硬盘中的数据在断电后依然能够保存下来。
现在比较流行的硬盘分为:机械硬盘(HDD)
和 固态硬盘(SSD)
。由于本文重点介绍的对象是 文件系统
,所以对于硬盘的原理就不进行过多的介绍。下面是 机械硬盘 和 固态硬盘 的对照图:
我们可以把硬盘想象成一个巨大的数组,而数组的每个元素代表一个数据块,如下图:
在 Linux 内核中,每个数据块定义为 4KB
的大小,所以一个 128GB 的硬盘可以分为 33554432 个数据块,内核就是以数据块的编号来对硬盘进行读写操作的。
二、什么是文件系统 前面说过,内核是以数据块的形式来对硬盘进行读写的,但是这对人类来说是非常不直观的,因为我们不可能记住每一个数据块保存了什么数据。
为了让用户在使用上更方便和直观,Linux 内核抽象出两个概念来管理硬盘中的数据:文件(File)
和 目录(Directory)
。
-
文件:用于保存数据。
-
目录:用于保存文件列表,当然目录也可以保存目录。
由于数据是保存在硬盘数据块中,所以文件只需要记录哪些数据块属于当前文件即可。如下图所示:
从上图可以看出,目录中既可以保存文件,也可以保存目录。而文件中保存的是属于当前文件的数据块编号,所以当读写文件时,只需要找到文件对应的数据块进行读写即可。
三、MINIX 文件系统实现 现在,我们以 MINIX 文件系统来详细介绍文件系统的设计原理。由于 MINIX 文件系统非常简单,所以适合用于教学使用。
1. MINIX 文件与目录
在 MINIX 文件系统中,以 minix2_inode
对象来描述一个文件。我们来看看 minix2_inode
的定义:
struct minix2_inode { __u16 i_mode; // 模式 __u16 i_nlinks; // 链接数 __u16 i_uid; // 所属用户UID __u16 i_gid; // 所属组ID __u32 i_size; // 文件大小 __u32 i_atime; // 访问时间 __u32 i_mtime; // 修改时间 __u32 i_ctime; // 创建时间 __u32 i_zone[10]; // 文件数对应的数据块编号 }; 我们需要特别关注 minix2_inode
对象的 i_zone
字段,它就是用来记录属于当前文件的数据块编号。从定义来看,i_zone
是一个用于 10 个元素的整型数组,那么是否就说明 MINIX 的文件只能保存 40 KB 的数据呢?
答案是否定的,因为 MINIX 文件系统将 i_zone
数组分为 4 个部分:前 7 个元素直接指向保存数据的数据块编号,也就是数据会直接存储在这些数据块上,而第 8 个元素是一级间接指向,第 9 个元素是二级间接指向,第 10 个元素是三级间接指向。我们通过下图来说明这个关系:
通过这种多级指向的方式,一个 MINIX 文件就可以保存超过 40KB 的数据。
有描述文件的对象,那么也应该有描述目录的对象吧?在 MINIX 文件系统中,目录也是使用 minix2_inode
对象来描述的。那么怎么区分文件和目录呢?
在 minix2_inode
对象中有个 名为