哈喽,我是子牙老师,一个手写过操作系统、编程语言、Java虚拟机、docker、Ubuntu系统,玩透Windows内核、Linux内核...的硬核男人
要想玩明白文件系统,得先玩明白磁盘分区结构。从硬盘诞生至今,有两种磁盘分区结构:MBR、GPT,对此,前面已经写文章非常详细的剖析了,不了解的小伙伴可以去看看《MBR VS GPT》
有了前面的基础,就可以来玩文件系统了。Linux系统诞生至今了,诞生了哪些文件系统呢?这些

PC或服务器端,目前主流用的文件系统是ext4、Btrfs、XFS

来看看它们的对比

本篇文章主要分享ext文件系统相关知识,主要探讨ext文件系统的发展史、ext文件系统结构的变化及其原因。XFS、Btrfs,后面写文章分享。感兴趣的小伙伴可以关注公众号【硬核子牙】,看更多计算机底层硬核文章
本篇文章,enjoy
EXT1
废话不多说,直接上图,EXT1文件系统结构,长这样

EXT1并不是一个正式发布的文件系统,所以关于它的资料非常少,它的结构,也是后来人根据EXT2的结构推理出来的,所以这张图,只做对比用,帮助你理解EXT2文件系统结构
EXT2
EXT2文件系统的结构,长这样

EXT2文件系统的结构,为后来的文件系统结构的诞生奠定了基础,是理解后面文件系统结构的基础,咱们来深入探讨
EXT2最大的特色就是引入了块组,为什么要引入块组呢?看ChatGPT给的理由


综合来说,ChatGPT答案想告诉我们的是,EXT2引入块组,其一是解决EXT1文件系统存在的缺陷,其二是为未来即将到来的多核多线程时代打下架构基础
科技进化的节奏一般是:需求发生变化,就有人去研究如何解决,就出现了理论,搞基础设施的软件商与硬件商就基于理论一同去实现,解决这个需求。未来,科技一定还会进步,一定有人研究理论,一定有人搞基础设施。所以ChatGPT预测:AI时代,写业务代码的coder需求会减少,写基础设施代码的coder需求会增加
接下来我们实战一下,然后再抛出问题,引出答案

我创建了一个20M的盘,把它当成一个分区来用,给它打上EXT2文件系统,查看

看红色序号1与2的位置,当块大小是1024B的时候,first block=1,与我们前面说的一致,block=0的位置是boot block。那如果block size改成2048B、4096B呢?看结果

如果把block size改为2048B,4096B,first block=0,你是不是想问:那boot block就不要了吗?非也!2048B、4096B不是包含了1024B吗,所以如果是2048B,虽然first block=0,但是是从第1024B开始用,相当于空出来了1024B

为什么要从1024B开始用呢?因为EXT2的设计规定:超级块必须从1024B开始,grub也会去这个地方读超级块信息

再看一个问题:这20M的盘,被划分成了几个块组呢?我先不贴答案,咱们来算一算:一个块组占多大空间
红色序号3,每个块组有8192个block,每个block的size是1024K,两个相乘,结果是8M,所以20M硬盘,被分成了3个块组

8192这个数字又是怎么来的呢?因为block bitmap占一个block,一个block占1024B,每个位映射一个block,1024*8=8192
理论上来说,每个块组中的inode数量应该也是8192,因为inode bitmap也占一个block,不知道底层是怎么算出来是1712的,为了ChatGPT,没给出正确的答案
就以每个块组可以使用1712个inode来算,每个inode占128B,两个相乘,就得到存放所有inode需要214个block
一个块组,可以确定的block使用情况如图

这也只是用了297个block,group 0可用块数是从312开始的,中间的14个block是怎么用掉的,问ChatGPT


至此,我能想到的关于EXT2文件系统的全部问题及答案,就全部分享给你了
对了ext2的inode长这样,刚好128B

EXT3
ext3相比于ext2,改变了这些

其实核心的改变就是增加了日志,分区结构是没有变化的,即也是分成很多块组,块组中的结构也包含那些如超级块、两个位图、数据块...
关于ext3的日志功能介绍

ext3的日志是隐藏的,普通用户在Linux系统中是看不到的,只允许root用户通过debugfs命令才能看到,它所有的信息都存储在inode 8中,实战

就能看到了

要看懂这里面的信息,需要补一个知识:inode中是如何存储数据库的

有了这个基础,再去看ChatGPT的答案,就能看懂了

日志总共占用1M空间,一个block是1024B,相除,结果是1024个block,但是总共用了1029个block,多出来的5个block是怎么回事呢?间接块用的

画成图是这样

你是否想问,为什么一个block只能存储256个block的值,因为一个block的值是4B,1024除以4等于256

ext4与ext3最大的差异就是在这里,使用extent取代了直接块间接块算法
EXT4
来看看ext4与ext3的差异

其实有点像把整块分区分成块组进行管理,ext4再将块组分成一个个的extent进行管理。接下来看看extent具体是怎么玩的,先看使用数据吧
bash
dd if=/dev/zero of=fs20M.img bs=1M count=20
mkfs.ext4 fs20M.img
sudo debugfs fs20M.img进入交互界面
stat <8>

就直接分配了一段连续块,没有多余的废话,没有复杂的算法,效率肯定高,底层是怎么做到的呢?如图

再看ext4的源码,你会发现没有一个属性与extent有关,实际上也存储在这里
当你启用了extent,这个位置就用来存储extent信息。这个位置有多大呢?4*15=60B,可以存储一个header+4个extent,刚好60B

通过这个命令去查看是否启用了extent
perl
dumpe2fs fs20M.img | grep extent
一个extent能关联多大磁盘空间呢?32768*1024B=32M

一个inode最多只能关联4个extent,一个extent最大支持32M磁盘空间,那一个inode最多支持128M磁盘空间,那超过128M的文件怎么存呢?这里就会升级成一棵树

图就变成了这样

如果空间还不够,还会继续分裂成depth更深的树。理论上来说extent支持无限大的磁盘空间,即一个文件支持无限大的大小,但是ext4文件系统做了限制,树的最大depth是5

支持,ext4的extent就全部讲完了
有了本篇文章的基础,ext2、ext3、ext4的源码,你看起来应该就不会很费力了!
如果你想更多了解我,欢迎去我公众号【硬核子牙】看我之前的文章及我的奋斗历程。白手起家程序员的职场心得,应该会对你有很大启发
若有收获,就点个赞吧