Linux 内核源码分析---Ext 文件系统

Ext 2 文件系统

Ext 2 物理结构

Ext2 第二代扩展文件系统(second extended filesystem,缩写为 ext2),是 LINUX 内核所用的文件系统。

Ext2文件系统特性:

1、磁盘块分为组;

2、支持快速符号链接:如果链接目标的路径足够短,则将其存储在inode自身中;

3、在启动时支持对文件系统的状态进行自动的一致性检查;

4、Ext2 的索引节点中引入新的字段(块片、删除逻辑、日志)。

与现代文件系统相比,Ext2文件系统的代码非常紧凑

必须建立各种结构 (在内核中定义为C语言数据类型),来存放文件系统的数据 ,包括文件内容、目录层次结构的表示、相关的管理数据(如访问权限或与用户和组的关联),以及用于管理文件系统内部信息的元数据。

这些对从块设备读取数据进行分析而言,都是必要的。这些结构的持久副本显然需要存储在硬盘上,这样数据在两次会话之间不会丢失。下一次启动重新激活内核时,数据仍然是可用的。因为硬盘和物理内存的需求不同,同一数据结构通常会有两个版本。一个用于在磁盘上的持久存储,另一个用于在内存中的处理。

Ext2文件系统是一种基于块的文件系统,它将硬盘划分为若干块,每个块的长度都相同,按块管理元数据和文件内容;
块组是 Ext2 文件系统的核心要素。块组是该文件系统的基本成分,容纳了文件系统的其他结构。

为什么Ext2文件系统允许这样浪费空间?有两个原因,可以证明提供额外空间的做法是正确的:

(1)如果系统崩溃破坏了超级块,有关文件系统结构和内容的所有信息都会丢失。如果有冗余的副本,该信息是可能恢复的(难度极高,大多数用户可能一点也恢复不了)。

(2)通过使文件和管理数据尽可能接近,减少了磁头寻道和旋转,这可以提高文件系统的性能。

Ext 2 数据结构

1.超级块

超级块是文件系统的核心结构,保存了文件系统所有的特征数据 。内核在装载文件系统时,最先 看到的就是超级块的内容。内核只使用第一个块组 的超级块读取文件系统的元信息。使用 ext2_super_block 结构定义超级:

s_magic 字段存储一个魔数,该数值确认装载的文件系统确实是 Ext 2 类型,s_minor_rev_level 用于区分文件系统的不同的版本。

2.组描述符

每个块组都一个组描述符的集合,紧随超级块之后。其中保存的信息反映了文件系统每个块组的内容 ,因此不仅关系到当前块组的数据块,还与其他块组的 数据块inode块 相关。用于定义单个组描述符的数据结构比超级块结构短得多:

3.inode

每个块组都包含一个inode位图 和一个本地的inode表 , inode表可能延续到几个块。位图的内容与本地块组相关,不会复制到文件系统中任何其他位置。inode 位图用于概述块组中已用和空闲的 inode

4.目录和文件

文件系统的拓朴结构,在经典的 UNIX 文件系统中,目录不过是一种特殊的文件,其中是inode 指针和对应的文件名列表,表示了当前目录下的文件和子目录。

对于Ext2文件系统,也是这样。每个目录表示为一个inode,会对其分配数据块。数据块中包含了用于描述目录项的结构。

Ext 2 文件系统操作

虚拟文件系统和具体实现之间的关联大体上由3个结构建立,结构中包含了一系列的函数指针。所有的文件系统都必须实现该关联。
(1)用于操作文件内容的操作保存在file_operations中。
(2)用于此类文件对象自身的操作保存在inode_operations中。
(3)用于一般地址空间的操作保存在address_space_operations中。

Ext 2 文件系统对不同的文件类型提供了不同的file_operations实例。很自然,最常用的变体是用于普通文件:

目录也有自身的file_operations实例:

目录有更多可用的inode操作:

文件系统和块层通过address_space_operations关联。在 Ext 2 文件系统中,这些源码操作初始化如下:

此结构( super_operations)用于与超级块交互(读、写、分配inode)。对于 Ext 2 文件系统的,具体源码初始化如下:

Ext 4 文件系统

使用 Ext 3 文件系统的 Linux 内核中实现三个级别的日志记录:日记 journal、顺序 ordered 和回写 writeback。

案例:Ext 3 文件系统,数据块分配器每次分配一个 4 kb 的块,如果我们要写一个100mb文件就需要调用 25600 次数据块分配器。

Ext 4 文件系统被分成一系列块组,为减少磁盘碎片产生的性能瓶颈,块分配器尽量保持每个文件的数据块都在同个块组中,从而减少寻道时间。以 4kb 数据块为准,一个块组可以包含 32768 个数据块,也就是 128 mb。

Ext 4 文件系统特性

EXT 4 是第四代扩展文件系统(Fourth extended filesystem,缩写为 ext4)是 Linux 系统下的日志文件系统,是 ext 3 文件系统的后继版本。内核2.6.28引入 Ext 4 文件系统成为稳定版。

当格式化磁盘成为 Ext4 文件系统时,mkfs 将在块组描述表后面分配预留 GDT 表数据块(主要作用用于将扩展文件系统)

GDT 表(Global Descriptor Table) 是 x86 架构中用于实现分段机制的数据结构之一。它是在保护模式下用于管理内存分段的重要组成部分。GDT 表定义了一组段描述符,每个段描述符描述了一个内存段的属性和位置。

更大的文件系统和更大的文件;更多的子目录数量;更多的块和i-节点数量;多块分配;

持久性预分配;延迟分配;盘区结构;日志校验功能;支持"无日志"模式;在线碎片整理;

支持快速fsck;支持纳秒级时间戳。

Ext 4 文件系统数据结构

1.超级块

专门用于描述文件系统的全部配置信息:比如 inode数量、数据块个数、管理信息等。

2.块组描述符(GDT)

块组描叙符用于保存元组的信息,其占用一个或者多个数据块,具体取决于文件系统的大小,它主要包含块位图,inode 位图和 inode 表位置等

数据块位图:用于描述该块组所管理的块的分配状态

inode 位图:用于描述该块组所管理的 inode 分配状态

3.节点表(Inode Table)

inode 存储了 inode 号、文件属性元数据、指向文件占用的 block 的指针,每一个 inode 占用 128 字节或 256 字节。

4.Extent 树

Ext4 中用 extent 树代替逻辑块映射 。用一个struct ext4_extent结构就可以映射多个数据块,减少元数据块的使用。

struct ext4_extent_idxextent 树的内部节点,也称为索引节点

Ext 4 日志 JBD2

Ext4日志,在文件系统中是一个文件,默认Inode号为8,大小为一个块组(128MiB),日志文件通常存储在文件系统分区的中部。

文件系统在磁盘上保留一段小的连续区域(默认128MB),作为尽可能需要快速写入磁盘的"重要"数据的存放地。

一旦该重要数据事务完全写到磁盘,将其从磁盘写缓存中刷出。被提交的数据一份记录也被写到日志。Ext4和Ocfs2都用JBD2。

Ext 4 支持三种日志模式

(1)ordered,日志中只记录元数据,数据写入磁盘后才会提交日志。这是默认模式。

(2)journal,日志中同时记录元数据及数据内容,最安全也是最慢的模式,同时会导致延迟分配及Direct-I/O失效。

(3)writeback,日志中只记录元数据,但是不保证元数据和数据的写入顺序。(言外之意:元数据提交了,数据可能还没有落盘)。

数据块头部结构 :日志中的每个数据块的开头都是一个12bytes的数据结构,struct journal_header_s

超级块 :日志的超级块比Ext4的超级块简单。保存在日志的超级块中是日志的关键数据。日志超级块使用数据结构struct journal_superblock_s表示,大小为1024 bytes

描述数据块 :它包含一个日志数据块 tags 的数组,这些 tags 描述日志中接下来的数据块的最终位置。

撤消块 :用于记录本事务中的数据块链表,取代任何潜在日志中的更陈旧的数据块,这样可以加速恢复,因为陈旧的数据块不必要写到磁盘。

提交块 :提交块表明了一个事务已完整写到日志.

事务最核心属性就是状态,当事务正在提交,它的生命周期经过如下阶段:running-->locked-->flush-->commit-->ok

kjournald 线程 与每个进行日志的设备关联,此线程保证运行中的事务会在一个特定间隔后被提交。事务提交分成阶段操作(日志的逻辑结构):

恢复(journal recover)
发现日志记录的尾部-->为日志记录准备一串被撤消的块-->未被撤消的块以确保磁盘一致性的顺序被重新写入(重放操作)

相关推荐
二十雨辰16 分钟前
[linux]docker基础
linux·运维·docker
饮浊酒1 小时前
Linux操作系统 ------(3.文本编译器Vim)
linux·vim
lihuhelihu1 小时前
第3章 CentOS系统管理
linux·运维·服务器·计算机网络·ubuntu·centos·云计算
矛取矛求1 小时前
Linux系统性能调优技巧
linux
One_Blanks2 小时前
渗透测试-Linux基础(1)
linux·运维·安全
Perishell2 小时前
无人机避障——大疆与Airsim中的角速度信息订阅获取
linux·动态规划·无人机
爱吃喵的鲤鱼2 小时前
linux进程的状态之环境变量
linux·运维·服务器·开发语言·c++
dessler2 小时前
Linux系统-ubuntu系统安装
linux·运维·云计算
荒Huang3 小时前
Linux挖矿病毒(kswapd0进程使cpu爆满)
linux·运维·服务器
hjjdebug4 小时前
linux 下 signal() 函数的用法,信号类型在哪里定义的?
linux·signal