51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

手写文件系统,纯干货!

这篇文章聊聊文件系统是怎么写出来的,看完,你就可以自己去写文件系统了。本文以Linux的EXT系列文件系统为例进行讲解,理解了,其他的文件系统你就可以自行研究了,差不多的东西

理解了本文,你就可以将持久化存储、机械硬盘、固态硬盘、PCIe、操作系统、文件系统、EXT、NTFS、FAT、文件IO、page cache......彻底吃透,在存储短赛道打下深厚的功底

什么是文件系统,这个不用我介绍了吧。具象的说,就是管理文件的一套系统。抽象的说,就是连接用户与持久化存储设备的桥梁。如下图

本文自下而上,会讲到:

  1. 一块主板最多能挂几块硬盘

  2. 如果要写代码操控硬盘,有几种方式,代码具体要怎么写

  3. 不同的文件系统,区别在哪里?同一种文件系统,是结构上有区别,还是算法上

  4. 如何理解磁盘分区结构

  5. 为什么第一个分区,都是从2048扇区开始

  6. EXT文件系统长啥样

  7. 磁盘分区、文件系统、块组之间是什么样的关系

  8. 文件、目录在文件系统中是如何存放的

  9. 一个分区最多支持多少个文件、目录

......

如果这些都是你想了解的,那太好了!如果有的是,有的不是,有的没想过,看看吧,技多不压身!

以下,enjoy



01


about硬盘

一块主板最多能挂几块硬盘呢?这个得看你的主板支持的硬盘接口类型。从古至今,硬盘接口类型有三种,现在主流的是PCIe接口,性能最高

如果我们想写代码操控硬盘,有哪些方式可用呢?对于操控硬件,一般有三种方式:BIOS中断、端口、内存映射。操控硬盘,可以用前两种方式:BIOS中断、端口,代码怎么写呢?

BIOS中断,代码这样写。如果写操作系统,这个只是在早期使用,当我们写的操作系统接管了中断,就不会去用BIOS中断了。而且BIOS中断功能也较弱,不能满足复杂的业务需求

主流的方式是用端口进行操作,代码这样写

至于代码为什么要这样写,我这里就不展开了。如果你想深入理解,可以去学习我的课程《手写64位多核操作系统》

我上面贴的代码都是同步机制操控硬盘,这个也是在操作系统内核早期,当操作系统内核接管了中断,实现了任务切换,就可以实现异步机制操控硬盘,这个也是当今科技世界操控硬件的主流方式

对了,硬盘的最小单位是扇区,sector,扇区的大小从512B、1K,到如今主流的4K,跟内存的物理页4K保持了一直。对于定位到某个扇区,硬盘提供了三种坐标方式:最早的是CHS,中间出现了一个过渡版本LBA28,如今主流的是LBA48

掌握了这些,你就可以去实现硬盘驱动了。实现文件系统的地基就有了,接着走



02


磁盘分区

拿到一块硬盘,一般会把它分成多个分区去使用

从古至今,磁盘分区结构有两种:MBR、GPT,现在主流的是GPT,我之前写文件系统用的是MBR,所以我就以MBR磁盘分区结构来讲了,大差不差,GPT只是在各个维度增强了而已,比如支持更多分区、每个分区能管理更大的磁盘空间

MBR磁盘分区结构的特点是:第一个扇区是MBR扇区,里面存放操作系统的boot代码+64B的磁盘分区信息;最多支持三个主分区+一个逻辑分区;逻辑分区中又可以支持主分区+逻辑分区,无限套娃

MBR磁盘分区信息在硬盘里长这样子,一般是在MBR扇区的末尾

是不是看不懂,没事,上c代码

分区信息里面有三个重要的东西:boot_ind告诉你这个分区是不是引导分区,就是是不是Windows的c盘,安装系统系统的盘。讲真,很多计算机方面的东西,Windows真的做的更人性化,比Linux

第二个就是start_sect,告诉你这个分区从哪个扇区开始。一般来说,第一个分区从2048开始,不是从2开始,为什么如此呢?

是不是看了等于没看,我当时看完也是这种感觉,于是我继续问,稍微好些

到这里,我们知道怎么去读写硬盘,知道MBR磁盘分区信息存储在哪,分区信息包含了我们写文件系统需要的信息,重要可以开始写文件系统了

03


EXT文件系统

操控硬盘、硬盘的第一个扇区为MBR扇区、磁盘分区信息,对于任何文件系统,都是一样的。那不同的文件系统,不一样的是什么呢?是文件系统结构

比如Windows的常用文件系统NTFS被设计成这样

比如Linux常用的EXT系列,被设计成这样。下面详细讲解EXT文件系统结构

硬盘的扇区大小从古至今经历了512B、1K,现在主流的4K。这张图描述的是1K年代,所以标注的引导块占1K,在4K为一个扇区的硬盘中,引导块占4K空间

块组是什么呢?块组是将分区进行分开管理,是EXT2引入的。其实块组针对以前的机械硬盘,效果显著,对于如今的固态硬盘,唯一的好处可能就是将大空间分块管理了

如何论证块组确实存在呢?通过命令查看

sudo dumpe2fs /dev/sda1 | less

有没有注意到里面的数字: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,跟这里可不是一个意思哦。

给大家留到题,检测你有没有看懂这篇文章:第一个分区的第一个块组的数据块,是从哪个扇区开始的?

赞(5)
未经允许不得转载:工具盒子 » 手写文件系统,纯干货!