引言:诚意,毋自欺也。——传习录
一、背景
笔者一直对Linux的文件是怎样存储到磁盘里很感兴趣,最近读了相关的文章,感觉略有理解,现记录如下。
二、概述
其实从Linux中使用ls命令所见的文件最终都是存储到磁盘的最小单位——扇区,这中间经历了多层的抽象,为了提升磁盘的访问效率,设计了各种各样的数据结构和算法。下图是笔者画的一个草图,这个图大概画出了基本的一个抽象。
首先Linux把所有文件都抽象为字符流,不管这个文件多大,都是这种形式,当你增删改查的时候,都是在这个流上进行修改。
我们知道老式磁盘的最小单位是扇区,每个扇区大小是512Byte,这个相当于是磁盘制造时候的物理单元,无法更改。
那一个多大几个G,几个TB的文件,怎么样最终存储到这么一个个小小的扇区上的呢?
传统磁盘的概念还有磁道Cylinder,磁头Head,而扇区就是Sector,通过(C, H, S) 这个三维坐标,就可以唯一定位一个扇区,这一部分由硬盘制造商提供的驱动程序来实现,Linux只需要传输这三个参数就行了。
但是一个扇区仅仅有512B,这也太小了,会对管理带来很多麻烦,就类似于中国人口那么多,不好管理,得分出各个省市等。因此在这个基础上,抽象了一个block(块)的概念。
一个block,下面有多个连续的扇区,也就是文件的基本组成单位。这是一个脱离底层硬件的一个抽象,我们且不管底层是磁盘还是U盘还是光盘,只使用Block进行管理,那就脱离了底层的扇区,我们可以把精力放在Block上。
一个文件由多个block组成,block可以设置为多种大小,比如4KB,8KB,这是可以设置的。

Block一个是4KB,那怎么对应到扇区,答案是:算出来的!你没有看错,这里没有地址表,没有bitmap,而是通过起始扇区号 + n * 8 然后就计算出来了Block的扇区地址。
这就解决了最下一层,那文件到block是怎样对应的呢?能不能也算出来?
显然,不能。因为文件变化多端,是我们OS增删改查的主要对象,如果是固定的首地址+长度的计算方法,会导致灵活性不够。
这时候就使用一种数据结构来组成文件,这就是非常著名的inode——索引节点。每个文件都会有一个索引节点,索引节点下辖6个直接节点,和多个二级索引和三级索引,到了这里,实际上就完成了从文件到block的关联。