深度剖析 Linux cp 命令的秘密( 二 )


划重点:存的时候必须记录一些关键信息(记录ID、给身份牌),取的时候才能正确定位到 。
 
文件系统 
回到我们的文件系统,对比上面的行李存取行为,可以做个简单的类比;

  1. 登记名字就是在文件系统记录文件名;
  2. 生成的牌子就是元数据索引;
  3. 你的行李就是文件;
  4. 寄存室就是磁盘(容纳东西的物理空间);
  5. 管理员整套运行机制就是文件系统;
上面的对应并不是非常严谨,仅仅是帮助大家理解文件系统而已,让大家知道其实文件系统是非常朴实的一个东西,思想都来源于生活 。
划重点:文件系统的存储介质是磁盘,文件系统是软件层面的,是管理员,管理怎么使用磁盘空间的软件系统而已 。
 
空间管理 
现在思考文件系统是怎么管理空间的?
如果,一个连续的大磁盘空间给你使用,你会怎么使用这段空间呢?
直观的一个想法,我把进来的数据就完整的放进去 。
深度剖析 Linux cp 命令的秘密

文章插图
 
这种方式非常容易实现,属于眼前最简单,以后最麻烦的方式 。因为会造成很多空洞,明明还有很多空间位置,但是由于整个太大,形状不合适(数据大小),哪里都放不下 。因为你要放一个完整的空间 。
这种不能利用的空间我们称之为碎片,准确的说是外部碎片,这种碎片在内存池分配内存的时候最常见,产生的原理是一样的 。
怎么改进?有人会想,既然整个放不进去,那就剁碎了呗 。这里塞一点,那里塞一点,就塞进去了 。
对,思路完全正确 。改进的方式就是切分,把空间按照一定粒度切分 。每个小粒度的物理块命名为 Block,每个 Block 一般是 4K 大小,用户数据存到文件系统里来自然也是要切分,存储到每一个 Block。Block 粒度越小则外部碎片则会越少(注意:元数据量会越大),可以尽可能的利用到空间,并且完整的用户数据文件存储到磁盘上则不再连续,而是切成一个个 Block 大小的数据块存到磁盘的各个角落上 。
深度剖析 Linux cp 命令的秘密

文章插图
 
图示标号表示这个完整对象的 Block 的序号,用来复原对象用的 。
随之而来又有一个问题:你光会切成块还不行,取文件数据的时候,要给完整的用户数据出去,用户不管你内部怎么实现,他只想要的是最初的样子 。所以,要有一个表记录该文件对应所有 Block 的位置,要把每一个 Block 的位置记录好,取文件的时候,对照这表恢复出一个完整的块给到用户 。
所以,写流程再完善一下就是这样子:
  1. 先写数据:数据先按照 Block 粒度存储到磁盘的各个位置;
  2. 再写元数据:然后把 Block 所在的各个位置保存起来,这也就是元数据,文件系统里叫做 inode(我用一本书来表示);

深度剖析 Linux cp 命令的秘密

文章插图
 
文件读流程则是:
  1. 先读元数据,找到各个 Block 的位置;
  2. 然后读数据,构造一个完整的文件,给到用户;

深度剖析 Linux cp 命令的秘密

文章插图
 
inode/block 概念 
好,现在我们引出了两个概念:
  1. 磁盘空间是按照 Block 粒度来划分空间的,存储数据的区域全都是 Block,我们叫做数据区域;
  2. 文件存储不再连续存储在磁盘上,所以需要记录元数据,这个我们叫做 inode;
文件系统中,一个 inode 唯一对应一个文件,inode 的个数则是在文件系统格式化的时候就确定好了的,换言之,一个 local 文件系统支持的文件数是天然就有上限的 。
block 固定大小,每个 4k(大部分文件系统都是,这里不做纠结),block 意图存储打散的用户数据 。
无论是 inode 区,还是 block 区,本质上都是在线性的磁盘空间上 。文件系统的空间层次如下:
深度剖析 Linux cp 命令的秘密

文章插图
 


推荐阅读