admin管理员组文章数量:1031308
从青铜到王者系列:深入浅出理解DeepSeek 3FS (2)从内核到用户态文件系统的设计之路
从青铜到王者系列:深入浅出理解DeepSeek 3FS (2)从内核到用户态文件系统的设计之路
大家好,我是小王同学,
本文希望帮你深入理解分布式存储系统3FS更进一步
- 昵称:20点下班就是一件很幸福事情
- 愿景:让小孩都可以听得懂我在讲什么。
- 我能提供什么:多问自己一次为什么这样用
- 不明白的留言:
- Wechat/GitHub:watchpoints
作业 实现 hello world 的文件系统 ,并说出IO流程
参考答案
- /
- .c
没有FUSE的IO流程示意图
带FUSE的IO流程示意图
一、导读
从青铜到王者系列:深入浅出理解 DeepSeek 3FS(1)
我整理 大模型训练
- 在checkpoint时候对大的文件读写,
- 在批量查询的时候对小文件读写
目前
- 谷歌的GFS 适合 大文件顺序读写,
- Ceph mds 元数据 存在瓶颈 8k作用
幻方为什么要搞3FS? AI训练与推理的业务需求,传统分布式文件系统已经难以满足:
- 海量数据顺序读(语料输入)
- 检查点(分步骤重算)
- 顺序写(模型参数保存);
- 随机读
因此重新实现一个新的文件系统
❝不考虑分布式,个人笔记或者购买云主机文件系统 如何支持大小文件读写,并且满足高效查询
提问:Linux 系统启动过程
划重点:重点是文件系统部分,扩展虚拟机(KVM)与内核部分。
电脑通电后,加载主板上的BIOS(basic input output system)程序
BIOS是电脑启动时加载的第一个软件。 它是一组固化到计算机内主板上一个ROM芯片上的程序
boot:
虚拟机(KVM)如何设置引导硬盘顺序
什么是 KVM? 基于内核的虚拟机(KVM)是 Linux® 操作系统的一种开源虚拟化技术。借助 KVM,Linux 可作为虚拟机监控程序运行多个独立的虚拟机(VM)
BIOS--》boot 第1引导顺序:hard drive 硬盘
第2引导顺序:cdrom 光驱 ----》安装系统
第3引导顺序:removable device 可移动设备--》u盘,移动硬盘 --》安装系统
第4引导顺序:Network --》从网络启动--》网络中安装服务器启动 --》安装
文件系统部分
启动流程:
- 内核加载完成
- 执行mount操作
挂载文件系统想要操作文件系统,
第一件事情就是挂载文件系统
- 读取超级块
- 定位inode 2
- 将其挂载为根目录
系统启动过程:
+----------------+ +---------------+ +------------------+
| 读取超级块 | --> | 定位inode 2 | --> | 挂载为根目录(/) |
+----------------+ +---------------+ +------------------+
在 Linux 启动过程中,加载 ext4 文件系统主要经历以下几个阶段:
- 内核加载与初始化
- 当系统通过 BIOS/UEFI 加载引导加载程序(如 GRUB)后,内核被加载到内存中。
- 内核初始化时,会建立 VFS(虚拟文件系统)核心数据结构,如 dentry 哈希表和 inode 哈希表,并加载必要的文件系统驱动(ext4 驱动可以是内置的或作为模块加载)。
- 挂载根文件系统
- 内核根据启动参数(例如 root=/dev/sda1)确定根文件系统所在的设备。
- 调用函数如 **vfs_kern_mount()**(进一步调用 ext4_mount())来挂载 ext4 文件系统。
- 在挂载过程中,ext4 驱动会读取设备上的超级块(superblock),验证 ext4 的魔数(magic number)和其它元数据,同时初始化 inode 表、日志(journal)等内部数据结构。
- ext4 文件系统的根目录在挂载时根据约定总是分配 inode 号 2。
- 切换根文件系统(pivot_root/switch_root)
- 如果系统使用了 initrd 或 initramfs 作为临时根文件系统,内核会在加载完真正的 ext4 文件系统后,通过 pivot_root 或 switch_root 将根目录切换到挂载的 ext4 文件系统上。
- 此时,init(或 systemd)进程启动,用户空间接管并继续后续的初始化工作。
这样,整个过程确保了 ext4 文件系统的元数据和数据块被正确加载,并最终成为系统的根文件系统,使用户和应用程序可以正常访问文件数据。
作业:为什么不同挂载点的inode号码都是2
代码语言:javascript代码运行次数:0运行复制[root@watchpoints ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 1G 0 loop /mnt/icfs
sr0 11:0 1 19M 0 rom
vda 253:0 0 50G 0 disk
└─vda1 253:1 0 50G 0 part /
[root@watchpoints ~]# ls -id /
2 /
[root@watchpoints ~]# ls -id /mnt/icfs
2 /mnt/icfs
同理
我们有3个不同的文件系统分别挂载到了3个不同的挂载点(目录)。
EXT4格式的文件系统我们分了3个,
分别挂载了/,
/boot,
/home。
那么这里的了/,/boot,/home就是3个不同的挂载点。
.h
代码语言:javascript代码运行次数:0运行复制/*
* Special inodes numbers
*/
#define EXT4_BAD_INO 1 /* Bad blocks inode */
#define EXT4_ROOT_INO 2 /* Root inode */
#define EXT4_USR_QUOTA_INO 3 /* User quota inode */
#define EXT4_GRP_QUOTA_INO 4 /* Group quota inode */
#define EXT4_BOOT_LOADER_INO 5 /* Boot loader inode */
#define EXT4_UNDEL_DIR_INO 6 /* Undelete directory inode */
#define EXT4_RESIZE_INO 7 /* Reserved group descriptors inode */
#define EXT4_JOURNAL_INO 8 /* Journal inode */
二、提问:Linux 文件系统是怎么工作的?
通过这张图,你可以看到,在 VFS 的下方,Linux 支持各种各样的文件系统,如 Ext4、XFS、NFS 等等。按照存储位置的不同,
这些文件系统可以分为三类。
- 类是基于磁盘的文件系统,也就是把数据直接存储在计算机本地挂载的磁盘中。 见的 Ext4、XFS、OverlayFS 等,都是这类文件系统。
- 类是基于内存的文件系统,也就是我们常说的虚拟文件系统。
- 类是网络文件系统,
也就是用来访问其他计算机数据的文件系统,比如 NFS、SMB、iSCSI 等。
网络文件系统 NFS:首次突破内核态
随着计算需求的增长,单台计算机的性能逐渐无法满足日益增长的计算和存储要求。
人们开始引入多台计算机,以分担负载并提高整体效率。
在这一场景下,一个应用程序往往需要访问分布在多台计算机上的数据。
为了解决这一问题,人们提出了在网络中引入虚拟存储层的概念,将远程计算机的文件系统(如某个目录)通过网络接口挂载到本地计算机的节点上。
这样做的目的是使本地计算机能够无缝地访问远程计算机的数据,就好像这些数据存储在本地一样。
linux分析利刃之sar命令详解
参考: .html sar -n DEV 1 1#统计网络信息 这个有用带宽统计
查看进行哪些线程
文件系统的格式
来源:
第四代扩展文件系统(英语:Fourth extended filesystem,缩写为ext4)是Linux系统下的日志文件系统
文件系统(六):一文看懂linux ext4文件系统工作原理
ext4它突出的特点有:数据分段管理、多块分配、延迟分配、持久预分配、日志校验、支持更大的文件系统和文件大小。
ext4文件系统的具体实现比较复杂,本文尝试用比较简单的方式用一篇文章的篇幅来简单地介绍一下它的工作原理。
命令:dumpe2fs /dev/loop0
从上面dumpe2fs的数据上我们可以看出,一个1GB大小的空间,ext4 文件系统将它分隔成了0~7的8个Group。
其中,每个Group中又有superblock、Group descriptors、bitmap、Inode table、usrer data、还有一些保留空间,细分之后的空间布局如下: ext4 的总体磁盘布局如下:
具体含义内: ext4文件系统信息表
从上面《1.1 ext4文件系统信息表》中可以知道Primary superblock在第0号block,每个block的大小为4096Byte
文件系统信息、块大小和块组信息、Inode 相关信息、文件系统大小和使用情况、日志相关信息、挂载信息、校验和和备份信息。
这里面我还需要重点说一下,超级块和块组描述符表都是全局信息,而且这些数据很重要。
如果这些数据丢失了,整个文件系统都打不开了,这比一个文件的一个块损坏更严重。所以,这两部分我们都需要备份,但是采取不同的策略。默认情况下,超级块和块组描述符表都有副本保存在每一个块组里面
其实使用dumpe2fs命令查看的ext4文件系统信息就是从superblock上的数据解析而来。
除了Primary superblock,还在不同的group中有备份superblock,其内容与Primary superblock原始数据相同,Primary superblock损坏的时候可以从备份区恢复回来
回顾:
在 Linux 内核挂载 ext4 文件系统时,挂载流程大致如下:
- 系统调用 mount() 启动挂载流程 当用户或内核启动参数(如 root=/dev/sda1)触发挂载时,会调用通用的 mount 系统调用,进而进入 VFS 层的挂载流程。
- 进入 ext4 挂载入口 ext4_mount() ext4 文件系统在内核中注册为一种文件系统类型,其挂载入口函数通常为 ext4_mount()(定义在 fs/ext4/super.c 中)。 在该函数中,会调用 ext4_fill_super(),用来读取磁盘上的超级块(superblock)并验证 ext4 文件系统的完整性。
- 解析超级块与加载根 inode ext4_fill_super() 会从设备上读取超级块数据,然后填充超级块结构体。在超级块中保存了文件系统全局信息,其中就包括 ext4 文件系统的根目录 inode 的固定编号(EXT4_ROOT_INO 定义为 2,见 fs/ext4/ext4.h)。 紧接着,内核通过 ext4_iget()(或相关函数)加载 inode 2,这个 inode 就代表了文件系统的根目录。
- 构造根目录 dentry 并完成挂载 加载根 inode 后,内核会创建相应的 dentry(目录项),并将该根 dentry 作为挂载点的根,最终将整个文件系统挂载为根目录(/)。
相关源码主要分布在内核源代码的 fs/ext4/ 目录下,具体可以查看 ext4_mount()、ext4_fill_super() 以及 ext4_iget() 等函数。
ext4 文件系统特点的
- 带着问题去 阅读:ext4文件系统单个文件存储大小是多少?4TB 还是16TB
❝Linux的ext4文件系统,为什么inode里只有12个指向数据块的直接指针?
- Ext4只有12个指向数据块的直接指针是沿用的Ext3的设计,为了保证前向兼容。对于Ext4文件系统来说,12个直接块可以解决大部分小文件的场景。如果文件太大,通过直接块的方式元数据将会占用太多空间。
- EXT3 适合中小规模存储,不适合超大文件(>2TB)
代码位置:
- .h#L771
struct ext4_inode {
__le32 i_block[EXT4_N_BLOCKS];/* Pointers to blocks */ n=15
};
/*
* Constants relative to the data blocks
*/
#define EXT4_NDIR_BLOCKS 12
#define EXT4_IND_BLOCK EXT4_NDIR_BLOCKS
#define EXT4_DIND_BLOCK (EXT4_IND_BLOCK + 1)
#define EXT4_N_BLOCKS (EXT4_TIND_BLOCK + 1) //14
具体如何保存的呢?
- EXT4_N_BLOCKS 有如下的定义,计算下来一共有 15 项。
- 在 ext2 和 ext3 中,其中前 12 项直接保存了块的位置,也 就是说,我们可以通过 i_block[0-11],直接得到保存文件内容的块。
- 如果一个文件比较大,12 块放不下 i_block[12]指向一个块,这个块里面不放数据块,而是放数据块的位置, 这个块我们称为间接块。
也就是说,我们在 i_block[12]里面放间接块的位置,通过 i_block[12]找到间接块后,间接块里面放数据块的位置,通过间接块可以找到数据块。
- 如果文件再大一些,i_block[13]会指向一个块,我们可以用二次间接块【指针的指针】
- 如果文件再大一些,i_block[14]会指向三次间接块
EXT4 文件系统采用 索引节点(inode)结构 来管理文件,其中 inode 结构中包含 15 个指针,用于定位文件数据块。
EXT4 Inode 结构中的 15 个指针
指针类型 | 数量 | 说明 |
---|---|---|
直接块指针(Direct Block) | 12 | 直接指向数据块,每个指针可寻址 1 个数据块。 |
一次间接指针(Singly Indirect) | 1 | 指向一个块,该块内存储多个直接块指针。 |
二次间接指针(Doubly Indirect) | 1 | 指向一个块,该块内的指针指向多个一次间接块。 |
三次间接指针(Triply Indirect) | 1 | 指向一个块,该块内的指针指向多个二次间接块。 |
单个文件最大支持大小计算
假设 块大小(block size)为 4KB(EXT4 常用设置),计算单个文件最大大小:
- 直接块存储数据:
- 12 个直接指针 × 4KB = 48KB
- 一次间接块存储数据:
- 1 个指针块存储 1024 个指针(4KB / 4B = 1024)
- 1024 × 4KB = 4MB
- 二次间接块存储数据:
- 1 个指针块存储 1024 个一次间接指针
- 1024 × 4MB = 4GB
- 三次间接块存储数据:
- 1 个指针块存储 1024 个二次间接指针
- 1024 × 4GB = 4TB
最终计算(最大单个文件大小)
- 直接块:48KB
- 一次间接块:4MB
- 二次间接块:4GB
- 三次间接块:4TB
- 总计 ≈ 4TB + 4GB + 4MB + 48KB ≈ 4TB
结论
- EXT4 单个文件最大可达 16TB(如果启用了 更大的 block size,比如 64KB)。
- 在 4KB 块大小下,单个文件最大 ≈ 4TB(由于索引结构限制)。
- 相比 EXT3(单文件最大 2TB),EXT4 更适合大文件存储。
如果需要存储超过 4TB 的单个文件,可以:
- 使用更大的块大小(如 64KB,最大 16TB)。
- 考虑使用其他文件系统(如 XFS、Btrfs、ZFS)。
对比:
❝带着问题去 阅读:ext4如何存储大文件的,遇得什么麻烦
❝对于大文件来讲,我们要多次读取硬盘才能找到相应的块,这样访问速度就会比较慢。
为了解决这个问题,ext4 做了一定的改变。 它引入了一个新的概念,叫做 Extents。
我们来解释一下 Extents。
比方说,一个文件大小为 128M,如果使用 4k 大小的块进行存储,需要 32k 个块。
如果按照 ext2 或者 ext3 那样散着放,数量太大了。
但是 Extents 可以用于存放连续的块,也就是说,我们可以把 128M 放在一个 Extents 里面。
这样的话,对大文件的读写性能提高了,文件碎片也减少了。
除了根节点,其他的节点都保存在一个块4k里面,4k扣除ext4_extent_header的12个byte,剩下的能够放340项,每个extent最大能表示128MB的数据,340个extent会使你的表示的文件达到42.5GB。
三、ext4文件系统为例子 cat /mnt/icfs/fileA 判断文件fileA是否存在
✅前置条件:
在 Linux 中,文件系统(如 ext4)通常只能在块设备(block device)上创建和操作,例如:
- 物理磁盘 (/dev/sda, /dev/nvme0n1)
- 磁盘分区 (/dev/sda1, /dev/nvme0n1p1)
- 虚拟块设备(如 LVM 逻辑卷 /dev/mapper/vg-lv)
如果 没有额外的磁盘,但你仍然需要:
从青铜到王者系列:深入浅出理解DeepSeek 3FS (2)从内核到用户态文件系统的设计之路
从青铜到王者系列:深入浅出理解DeepSeek 3FS (2)从内核到用户态文件系统的设计之路
大家好,我是小王同学,
本文希望帮你深入理解分布式存储系统3FS更进一步
- 昵称:20点下班就是一件很幸福事情
- 愿景:让小孩都可以听得懂我在讲什么。
- 我能提供什么:多问自己一次为什么这样用
- 不明白的留言:
- Wechat/GitHub:watchpoints
作业 实现 hello world 的文件系统 ,并说出IO流程
参考答案
- /
- .c
没有FUSE的IO流程示意图
带FUSE的IO流程示意图
一、导读
从青铜到王者系列:深入浅出理解 DeepSeek 3FS(1)
我整理 大模型训练
- 在checkpoint时候对大的文件读写,
- 在批量查询的时候对小文件读写
目前
- 谷歌的GFS 适合 大文件顺序读写,
- Ceph mds 元数据 存在瓶颈 8k作用
幻方为什么要搞3FS? AI训练与推理的业务需求,传统分布式文件系统已经难以满足:
- 海量数据顺序读(语料输入)
- 检查点(分步骤重算)
- 顺序写(模型参数保存);
- 随机读
因此重新实现一个新的文件系统
❝不考虑分布式,个人笔记或者购买云主机文件系统 如何支持大小文件读写,并且满足高效查询
提问:Linux 系统启动过程
划重点:重点是文件系统部分,扩展虚拟机(KVM)与内核部分。
电脑通电后,加载主板上的BIOS(basic input output system)程序
BIOS是电脑启动时加载的第一个软件。 它是一组固化到计算机内主板上一个ROM芯片上的程序
boot:
虚拟机(KVM)如何设置引导硬盘顺序
什么是 KVM? 基于内核的虚拟机(KVM)是 Linux® 操作系统的一种开源虚拟化技术。借助 KVM,Linux 可作为虚拟机监控程序运行多个独立的虚拟机(VM)
BIOS--》boot 第1引导顺序:hard drive 硬盘
第2引导顺序:cdrom 光驱 ----》安装系统
第3引导顺序:removable device 可移动设备--》u盘,移动硬盘 --》安装系统
第4引导顺序:Network --》从网络启动--》网络中安装服务器启动 --》安装
文件系统部分
启动流程:
- 内核加载完成
- 执行mount操作
挂载文件系统想要操作文件系统,
第一件事情就是挂载文件系统
- 读取超级块
- 定位inode 2
- 将其挂载为根目录
系统启动过程:
+----------------+ +---------------+ +------------------+
| 读取超级块 | --> | 定位inode 2 | --> | 挂载为根目录(/) |
+----------------+ +---------------+ +------------------+
在 Linux 启动过程中,加载 ext4 文件系统主要经历以下几个阶段:
- 内核加载与初始化
- 当系统通过 BIOS/UEFI 加载引导加载程序(如 GRUB)后,内核被加载到内存中。
- 内核初始化时,会建立 VFS(虚拟文件系统)核心数据结构,如 dentry 哈希表和 inode 哈希表,并加载必要的文件系统驱动(ext4 驱动可以是内置的或作为模块加载)。
- 挂载根文件系统
- 内核根据启动参数(例如 root=/dev/sda1)确定根文件系统所在的设备。
- 调用函数如 **vfs_kern_mount()**(进一步调用 ext4_mount())来挂载 ext4 文件系统。
- 在挂载过程中,ext4 驱动会读取设备上的超级块(superblock),验证 ext4 的魔数(magic number)和其它元数据,同时初始化 inode 表、日志(journal)等内部数据结构。
- ext4 文件系统的根目录在挂载时根据约定总是分配 inode 号 2。
- 切换根文件系统(pivot_root/switch_root)
- 如果系统使用了 initrd 或 initramfs 作为临时根文件系统,内核会在加载完真正的 ext4 文件系统后,通过 pivot_root 或 switch_root 将根目录切换到挂载的 ext4 文件系统上。
- 此时,init(或 systemd)进程启动,用户空间接管并继续后续的初始化工作。
这样,整个过程确保了 ext4 文件系统的元数据和数据块被正确加载,并最终成为系统的根文件系统,使用户和应用程序可以正常访问文件数据。
作业:为什么不同挂载点的inode号码都是2
代码语言:javascript代码运行次数:0运行复制[root@watchpoints ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 1G 0 loop /mnt/icfs
sr0 11:0 1 19M 0 rom
vda 253:0 0 50G 0 disk
└─vda1 253:1 0 50G 0 part /
[root@watchpoints ~]# ls -id /
2 /
[root@watchpoints ~]# ls -id /mnt/icfs
2 /mnt/icfs
同理
我们有3个不同的文件系统分别挂载到了3个不同的挂载点(目录)。
EXT4格式的文件系统我们分了3个,
分别挂载了/,
/boot,
/home。
那么这里的了/,/boot,/home就是3个不同的挂载点。
.h
代码语言:javascript代码运行次数:0运行复制/*
* Special inodes numbers
*/
#define EXT4_BAD_INO 1 /* Bad blocks inode */
#define EXT4_ROOT_INO 2 /* Root inode */
#define EXT4_USR_QUOTA_INO 3 /* User quota inode */
#define EXT4_GRP_QUOTA_INO 4 /* Group quota inode */
#define EXT4_BOOT_LOADER_INO 5 /* Boot loader inode */
#define EXT4_UNDEL_DIR_INO 6 /* Undelete directory inode */
#define EXT4_RESIZE_INO 7 /* Reserved group descriptors inode */
#define EXT4_JOURNAL_INO 8 /* Journal inode */
二、提问:Linux 文件系统是怎么工作的?
通过这张图,你可以看到,在 VFS 的下方,Linux 支持各种各样的文件系统,如 Ext4、XFS、NFS 等等。按照存储位置的不同,
这些文件系统可以分为三类。
- 类是基于磁盘的文件系统,也就是把数据直接存储在计算机本地挂载的磁盘中。 见的 Ext4、XFS、OverlayFS 等,都是这类文件系统。
- 类是基于内存的文件系统,也就是我们常说的虚拟文件系统。
- 类是网络文件系统,
也就是用来访问其他计算机数据的文件系统,比如 NFS、SMB、iSCSI 等。
网络文件系统 NFS:首次突破内核态
随着计算需求的增长,单台计算机的性能逐渐无法满足日益增长的计算和存储要求。
人们开始引入多台计算机,以分担负载并提高整体效率。
在这一场景下,一个应用程序往往需要访问分布在多台计算机上的数据。
为了解决这一问题,人们提出了在网络中引入虚拟存储层的概念,将远程计算机的文件系统(如某个目录)通过网络接口挂载到本地计算机的节点上。
这样做的目的是使本地计算机能够无缝地访问远程计算机的数据,就好像这些数据存储在本地一样。
linux分析利刃之sar命令详解
参考: .html sar -n DEV 1 1#统计网络信息 这个有用带宽统计
查看进行哪些线程
文件系统的格式
来源:
第四代扩展文件系统(英语:Fourth extended filesystem,缩写为ext4)是Linux系统下的日志文件系统
文件系统(六):一文看懂linux ext4文件系统工作原理
ext4它突出的特点有:数据分段管理、多块分配、延迟分配、持久预分配、日志校验、支持更大的文件系统和文件大小。
ext4文件系统的具体实现比较复杂,本文尝试用比较简单的方式用一篇文章的篇幅来简单地介绍一下它的工作原理。
命令:dumpe2fs /dev/loop0
从上面dumpe2fs的数据上我们可以看出,一个1GB大小的空间,ext4 文件系统将它分隔成了0~7的8个Group。
其中,每个Group中又有superblock、Group descriptors、bitmap、Inode table、usrer data、还有一些保留空间,细分之后的空间布局如下: ext4 的总体磁盘布局如下:
具体含义内: ext4文件系统信息表
从上面《1.1 ext4文件系统信息表》中可以知道Primary superblock在第0号block,每个block的大小为4096Byte
文件系统信息、块大小和块组信息、Inode 相关信息、文件系统大小和使用情况、日志相关信息、挂载信息、校验和和备份信息。
这里面我还需要重点说一下,超级块和块组描述符表都是全局信息,而且这些数据很重要。
如果这些数据丢失了,整个文件系统都打不开了,这比一个文件的一个块损坏更严重。所以,这两部分我们都需要备份,但是采取不同的策略。默认情况下,超级块和块组描述符表都有副本保存在每一个块组里面
其实使用dumpe2fs命令查看的ext4文件系统信息就是从superblock上的数据解析而来。
除了Primary superblock,还在不同的group中有备份superblock,其内容与Primary superblock原始数据相同,Primary superblock损坏的时候可以从备份区恢复回来
回顾:
在 Linux 内核挂载 ext4 文件系统时,挂载流程大致如下:
- 系统调用 mount() 启动挂载流程 当用户或内核启动参数(如 root=/dev/sda1)触发挂载时,会调用通用的 mount 系统调用,进而进入 VFS 层的挂载流程。
- 进入 ext4 挂载入口 ext4_mount() ext4 文件系统在内核中注册为一种文件系统类型,其挂载入口函数通常为 ext4_mount()(定义在 fs/ext4/super.c 中)。 在该函数中,会调用 ext4_fill_super(),用来读取磁盘上的超级块(superblock)并验证 ext4 文件系统的完整性。
- 解析超级块与加载根 inode ext4_fill_super() 会从设备上读取超级块数据,然后填充超级块结构体。在超级块中保存了文件系统全局信息,其中就包括 ext4 文件系统的根目录 inode 的固定编号(EXT4_ROOT_INO 定义为 2,见 fs/ext4/ext4.h)。 紧接着,内核通过 ext4_iget()(或相关函数)加载 inode 2,这个 inode 就代表了文件系统的根目录。
- 构造根目录 dentry 并完成挂载 加载根 inode 后,内核会创建相应的 dentry(目录项),并将该根 dentry 作为挂载点的根,最终将整个文件系统挂载为根目录(/)。
相关源码主要分布在内核源代码的 fs/ext4/ 目录下,具体可以查看 ext4_mount()、ext4_fill_super() 以及 ext4_iget() 等函数。
ext4 文件系统特点的
- 带着问题去 阅读:ext4文件系统单个文件存储大小是多少?4TB 还是16TB
❝Linux的ext4文件系统,为什么inode里只有12个指向数据块的直接指针?
- Ext4只有12个指向数据块的直接指针是沿用的Ext3的设计,为了保证前向兼容。对于Ext4文件系统来说,12个直接块可以解决大部分小文件的场景。如果文件太大,通过直接块的方式元数据将会占用太多空间。
- EXT3 适合中小规模存储,不适合超大文件(>2TB)
代码位置:
- .h#L771
struct ext4_inode {
__le32 i_block[EXT4_N_BLOCKS];/* Pointers to blocks */ n=15
};
/*
* Constants relative to the data blocks
*/
#define EXT4_NDIR_BLOCKS 12
#define EXT4_IND_BLOCK EXT4_NDIR_BLOCKS
#define EXT4_DIND_BLOCK (EXT4_IND_BLOCK + 1)
#define EXT4_N_BLOCKS (EXT4_TIND_BLOCK + 1) //14
具体如何保存的呢?
- EXT4_N_BLOCKS 有如下的定义,计算下来一共有 15 项。
- 在 ext2 和 ext3 中,其中前 12 项直接保存了块的位置,也 就是说,我们可以通过 i_block[0-11],直接得到保存文件内容的块。
- 如果一个文件比较大,12 块放不下 i_block[12]指向一个块,这个块里面不放数据块,而是放数据块的位置, 这个块我们称为间接块。
也就是说,我们在 i_block[12]里面放间接块的位置,通过 i_block[12]找到间接块后,间接块里面放数据块的位置,通过间接块可以找到数据块。
- 如果文件再大一些,i_block[13]会指向一个块,我们可以用二次间接块【指针的指针】
- 如果文件再大一些,i_block[14]会指向三次间接块
EXT4 文件系统采用 索引节点(inode)结构 来管理文件,其中 inode 结构中包含 15 个指针,用于定位文件数据块。
EXT4 Inode 结构中的 15 个指针
指针类型 | 数量 | 说明 |
---|---|---|
直接块指针(Direct Block) | 12 | 直接指向数据块,每个指针可寻址 1 个数据块。 |
一次间接指针(Singly Indirect) | 1 | 指向一个块,该块内存储多个直接块指针。 |
二次间接指针(Doubly Indirect) | 1 | 指向一个块,该块内的指针指向多个一次间接块。 |
三次间接指针(Triply Indirect) | 1 | 指向一个块,该块内的指针指向多个二次间接块。 |
单个文件最大支持大小计算
假设 块大小(block size)为 4KB(EXT4 常用设置),计算单个文件最大大小:
- 直接块存储数据:
- 12 个直接指针 × 4KB = 48KB
- 一次间接块存储数据:
- 1 个指针块存储 1024 个指针(4KB / 4B = 1024)
- 1024 × 4KB = 4MB
- 二次间接块存储数据:
- 1 个指针块存储 1024 个一次间接指针
- 1024 × 4MB = 4GB
- 三次间接块存储数据:
- 1 个指针块存储 1024 个二次间接指针
- 1024 × 4GB = 4TB
最终计算(最大单个文件大小)
- 直接块:48KB
- 一次间接块:4MB
- 二次间接块:4GB
- 三次间接块:4TB
- 总计 ≈ 4TB + 4GB + 4MB + 48KB ≈ 4TB
结论
- EXT4 单个文件最大可达 16TB(如果启用了 更大的 block size,比如 64KB)。
- 在 4KB 块大小下,单个文件最大 ≈ 4TB(由于索引结构限制)。
- 相比 EXT3(单文件最大 2TB),EXT4 更适合大文件存储。
如果需要存储超过 4TB 的单个文件,可以:
- 使用更大的块大小(如 64KB,最大 16TB)。
- 考虑使用其他文件系统(如 XFS、Btrfs、ZFS)。
对比:
❝带着问题去 阅读:ext4如何存储大文件的,遇得什么麻烦
❝对于大文件来讲,我们要多次读取硬盘才能找到相应的块,这样访问速度就会比较慢。
为了解决这个问题,ext4 做了一定的改变。 它引入了一个新的概念,叫做 Extents。
我们来解释一下 Extents。
比方说,一个文件大小为 128M,如果使用 4k 大小的块进行存储,需要 32k 个块。
如果按照 ext2 或者 ext3 那样散着放,数量太大了。
但是 Extents 可以用于存放连续的块,也就是说,我们可以把 128M 放在一个 Extents 里面。
这样的话,对大文件的读写性能提高了,文件碎片也减少了。
除了根节点,其他的节点都保存在一个块4k里面,4k扣除ext4_extent_header的12个byte,剩下的能够放340项,每个extent最大能表示128MB的数据,340个extent会使你的表示的文件达到42.5GB。
三、ext4文件系统为例子 cat /mnt/icfs/fileA 判断文件fileA是否存在
✅前置条件:
在 Linux 中,文件系统(如 ext4)通常只能在块设备(block device)上创建和操作,例如:
- 物理磁盘 (/dev/sda, /dev/nvme0n1)
- 磁盘分区 (/dev/sda1, /dev/nvme0n1p1)
- 虚拟块设备(如 LVM 逻辑卷 /dev/mapper/vg-lv)
如果 没有额外的磁盘,但你仍然需要:
本文标签: 从青铜到王者系列深入浅出理解DeepSeek 3FS (2)从内核到用户态文件系统的设计之路
版权声明:本文标题:从青铜到王者系列:深入浅出理解DeepSeek 3FS (2)从内核到用户态文件系统的设计之路 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/jiaocheng/1747735050a2210783.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论