哈喽,我是子牙老师。这篇文章聊聊文件系统是怎么写出来的,看完,你就可以自己去写文件系统了。本文以Linux的EXT系列文件系统为例进行讲解,理解了,其他的文件系统你就可以自行研究了,差不多的东西
理解了本文,你就可以将持久化存储、机械硬盘、固态硬盘、PCIe、操作系统、文件系统、EXT、NTFS、FAT、文件IO、page cache……彻底吃透,在存储短赛道打下深厚的功底
什么是文件系统,这个不用我介绍了吧。具象的说,就是管理文件的一套系统。抽象的说,就是连接用户与持久化存储设备的桥梁。如下图
本文自下而上,会讲到:
- 一块主板最多能挂几块硬盘
- 如果要写代码操控硬盘,有几种方式,代码具体要怎么写
- 不同的文件系统,区别在哪里?同一种文件系统,是结构上有区别,还是算法上
- 如何理解磁盘分区结构
- 为什么第一个分区,都是从2048扇区开始
- EXT文件系统长啥样
- 磁盘分区、文件系统、块组之间是什么样的关系
- 文件、目录在文件系统中是如何存放的
- 一个分区最多支持多少个文件、目录
……
如果这些都是你想了解的,那太好了!如果有的是,有的不是,有的没想过,看看吧,技多不压身!
以下,enjoy
about硬盘
一块主板最多能挂几块硬盘呢?这个得看你的主板支持的硬盘接口类型。从古至今,硬盘接口类型有三种,现在主流的是PCIe接口,性能最高
如果我们想写代码操控硬盘,有哪些方式可用呢?对于操控硬件,一般有三种方式:BIOS中断、端口、内存映射。操控硬盘,可以用前两种方式:BIOS中断、端口,代码怎么写呢?
BIOS中断,代码这样写。如果写操作系统,这个只是在早期使用,当我们写的操作系统接管了中断,就不会去用BIOS中断了。而且BIOS中断功能也较弱,不能满足复杂的业务需求
主流的方式是用端口进行操作,代码这样写
至于代码为什么要这样写,我这里就不展开了。如果你想深入理解,可以去学习我的课程《手写64位多核操作系统》
我上面贴的代码都是同步机制操控硬盘,这个也是在操作系统内核早期,当操作系统内核接管了中断,实现了任务切换,就可以实现异步机制操控硬盘,这个也是当今科技世界操控硬件的主流方式
对了,硬盘的最小单位是扇区,sector,扇区的大小从512B、1K,到如今主流的4K,跟内存的物理页4K保持了一直。对于定位到某个扇区,硬盘提供了三种坐标方式:最早的是CHS,中间出现了一个过渡版本LBA28,如今主流的是LBA48
掌握了这些,你就可以去实现硬盘驱动了。实现文件系统的地基就有了,接着走
磁盘分区
拿到一块硬盘,一般会把它分成多个分区去使用
从古至今,磁盘分区结构有两种:MBR、GPT,现在主流的是GPT,我之前写文件系统用的是MBR,所以我就以MBR磁盘分区结构来讲了,大差不差,GPT只是在各个维度增强了而已,比如支持更多分区、每个分区能管理更大的磁盘空间
MBR磁盘分区结构的特点是:第一个扇区是MBR扇区,里面存放操作系统的boot代码+64B的磁盘分区信息;最多支持三个主分区+一个逻辑分区;逻辑分区中又可以支持主分区+逻辑分区,无限套娃
MBR磁盘分区信息在硬盘里长这样子,一般是在MBR扇区的末尾
是不是看不懂,没事,上c代码
分区信息里面有三个重要的东西:boot_ind告诉你这个分区是不是引导分区,就是是不是Windows的c盘,安装系统系统的盘。讲真,很多计算机方面的东西,Windows真的做的更人性化,比Linux
第二个就是start_sect,告诉你这个分区从哪个扇区开始。一般来说,第一个分区从2048开始,不是从2开始,为什么如此呢?
是不是看了等于没看,我当时看完也是这种感觉,于是我继续问,稍微好些
到这里,我们知道怎么去读写硬盘,知道MBR磁盘分区信息存储在哪,分区信息包含了我们写文件系统需要的信息,重要可以开始写文件系统了
EXT文件系统
操控硬盘、硬盘的第一个扇区为MBR扇区、磁盘分区信息,对于任何文件系统,都是一样的。那不同的文件系统,不一样的是什么呢?是文件系统结构
比如Windows的常用文件系统NTFS被设计成这样
比如Linux常用的EXT系列,被设计成这样。下面详细讲解EXT文件系统结构
硬盘的扇区大小从古至今经历了512B、1K,现在主流的4K。这张图描述的是1K年代,所以标注的引导块占1K,在4K为一个扇区的硬盘中,引导块占4K空间
块组是什么呢?块组是将分区进行分开管理,是EXT2引入的。其实块组针对以前的机械硬盘,效果显著,对于如今的固态硬盘,唯一的好处可能就是将大空间分块管理了
如何论证块组确实存在呢?通过命令查看
有没有注意到里面的数字:32767,而且每个块组好像都是32768个扇区,为什么这样呢?因为块位图只占一个扇区大小:4096*8=32768。言外之意就是一个块组最大只能管理32768个扇区
比如这个分区有327680个扇区,就会被分成10个块组进行关联。那块组信息如何存储呢?
10个ext4_group_desc存储在文件字体的块组描述符表中
超级块是干嘛的呢?是描述整个文件系统信息的,比如块组描述符表在哪个扇区、块位图在哪个扇区、数据从哪个扇区开始存、这个分区一共有多少扇区可用……其实挂载,就是将超级块读入内存,完成目录与分区的映射
inode是干嘛的,研究过文件系统的应该都知道吧,它记录了很多非常重要的信息,比如目录中所有的文件对应的信息,如果是文件,比如文件内存在哪些扇区中存储
一个块组支持多少inode呢?32768个,算法跟前面一样。那是不是一个块组最多只能创建32768个文件呢?不是。因为文件跟inode并不是一一对应的关系。比如硬链接, 多个文件指向同一个inode
EXT4文件系统中,inode描述的信息非常多,结构体占256B,贴一些让大家感受一下
那一个4K的扇区可以放多少inode呢?16个。那32768个inode需要多少4K扇区存储呢?2048个。记不记得前面提到过一个2048,跟这里可不是一个意思哦。
给大家留到题,检测你有没有看懂这篇文章:第一个分区的第一个块组的数据块,是从哪个扇区开始的?
后面准备做个课程《手写EXT4文件系统》,如果你感兴趣,可以持续关注文章动态。
到这里,基本就可以结束了。从上往下看,EXT4难不难?巨难!但从下往上看呢?好像也没那么难对吧!这就是学计算机的一个非常重要的学习思维,从下往上学!第一次透漏此精髓!你看到就是赚到了
大多数人,对于学底层,都是理论派、代码观战师,只有极少数的人,脚踏实地的去重复写轮子,证明、理解、开悟,你选择做哪种呢?纸上谈兵,还是真材实料