Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 56 additions & 1 deletion Part1-3: 对实际的文件系统的探索.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,4 +206,59 @@ robocop@linuxbox:~$

不难看出,第二种方法更紧凑且高效。现在,我们能够仅用四个块存储相同的四个文件,而不是第一个方法中的六个块。我们甚至能够节省 1 KB 的文件系统空间。显然,为单个文件分配一个完整的文件系统块似乎是一种低效的空间管理方法,但实际上,这是必要的权宜之计。
![](image-21.png)
从第一眼看,第二种方法似乎好得多,但你看出设计缺陷了吗?如果文件系统采用这种方法,可能会遇到重大的问题。如果文件系统设计为在单一块中容纳多个文件,它们需要设计一种机制来跟踪单个块内每个文件的边界。这会大大增加设计的复杂性。此外,这还会导致严重的碎片化,从而降低文件系统的性能。如果文件的大小增加,新增的数据将不得不调整到一个单独的块中。文件将存储在随机块中,没有顺序访问。所有这些都会导致文件系统性能差,并使这种紧凑方法的任何优势都变得毫无意义。因此,每个文件都占据一个完整的块,即使它的大小小于文件系统块的大小。
从第一眼看,第二种方法似乎好得多,但你看出设计缺陷了吗?如果文件系统采用这种方法,可能会遇到重大的问题。如果文件系统设计为在单一块中容纳多个文件,它们需要设计一种机制来跟踪单个块内每个文件的边界。这会大大增加设计的复杂性。此外,这还会导致严重的碎片化,从而降低文件系统的性能。如果文件的大小增加,新增的数据将不得不调整到一个单独的块中。文件将存储在随机块中,没有顺序访问。所有这些都会导致文件系统性能差,并使这种紧凑方法的任何优势都变得毫无意义。因此,每个文件都占据一个完整的块,即使它的大小小于文件系统块的大小。


## ext4文件系统的布局

Ext4中的单个块被排列成另一个称为块组的单元。块组是连续块的集合。关于块组的组织,有两种情况。对于第一个块组,不使用前1,024字节。这些是为安装引导扇区保留的。对于第一个块组,布局如下:

![](image-21.png)

如果创建的文件系统块大小为1 KB,则超级块将保留在下一个块中。对于所有其他块组,布局如下:

![](image-22.png)

让我们来讨论Ext4块组的组成部分。

### super block

如第2章所述,超级块是VFS中的主要数据结构之一。文件系统必须实现包含文件系统元数据的超级块结构。Ext4超级块在fs/ext4/ext4.h中定义,如下图所示,它包含数十个定义文件系统不同属性的字段:

```
struct ext4_super_block {
__le32 s_inodes_count; /* Inodes count */
__le32 s_blocks_count_lo; /* Blocks count */
__le32 s_r_blocks_count_lo; /* Reserved blocks count */
__le32 s_free_blocks_count_lo; /* Free blocks count */
__le32 s_free_inodes_count; /* Free inodes count */
__le32 s_first_data_block; /* First Data Block */
__le32 s_log_block_size; /* Block size */
__le32 s_log_cluster_size; /* Allocation cluster size */
/*20*/ __le32 s_blocks_per_group; /* # Blocks per group */
__le32 s_clusters_per_group; /* # Clusters per group */
__le32 s_inodes_per_group; /* # Inodes per group */
__le32 s_mtime; /* Mount time */
/*30*/ __le32 s_wtime; /* Write time */
__le16 s_mnt_count; /* Mount count */
[……]
```

__Le32数据类型表明表示是小端顺序。从其在内核源中的定义中可以看出,Ext4超级块定义了许多属性来表征文件系统。这包含一些信息,例如文件系统中的块和块组总数、已使用和未使用的块总数、块大小、已使用和未使用的inode总数、文件系统状态等。超级块中包含的信息至关重要,因为它是安装文件系统时首先读取的信息。鉴于其关键性质,超级块的多个副本被保存在不同的位置。

超级块定义中的大多数字段都很容易理解。这里解释了一些有趣的领域:

- 块大小计算:Ext4文件系统的块大小使用此32位值计算。块大小计算如下:Ext4块大小=2 ^(10 + s_log_block_size)当s_log_block_size为零时,Ext4文件系统的最小块大小可以是1 KB。Ext4文件系统支持最大块大小为64 KB。

- 块集群:尽管在过去几年中磁盘驱动器的容量呈指数级增长,但Ext4文件系统的工作区块大小为几千字节。驱动器越大,区块的数量和开销就越大。作为变通办法,Ext4开发人员在Ext4中添加了块集群的功能。文件系统可以使用块组的概念在更大的组中分配块,而不是分配单个4 KB块。Ext4文件系统维护这些较大的块和4 KB块之间的映射。这个功能被称为bigalloc。块集群大小可以在文件系统创建时指定,并存储在s_log_cluster_size中。

- 文件系统状态和检查:文件系统一致性检查可以在三种情况下触发。S_mnt_count字段表示自上次运行一致性检查以来文件系统被装载的次数。S_max_mnt_count字段对挂载数量施加硬限制,超过该限制必须进行一致性检查。文件系统状态保存在s_state中。它可以是以下情况之一:‚干净地卸载 ‚检测到错误 ‚正在恢复孤儿 如果s_state中的文件系统状态不干净,则会自动强制执行检查。上次一致性检查的日期保存在s_lastcheck中。如果s_checkinterval字段中指定的时间自上次检查以来已过,则在文件系统上强制执行一致性检查。

- 魔术签名:不同的文件系统使用在一定偏移处出现的魔术数字的概念。不同的工具使用这个数字来识别特定文件系统类型。超级块中的s_magic字段包含这个魔术数字。对于Ext4,其值为0xEF53。S_rev_level和s_minor_rev_level字段用于区分文件系统版本。

- 块保留:这些是保留块的默认用户和组 ID。这些默认值为0(根用户)。Ext4文件系统为超级用户或根用户保留5%的文件系统块。这样做是为了让根用户进程继续运行,即使非根进程无法写入文件系统。第一个inode编号:这是可用于常规文件和目录的第一个inode编号。这个值通常为11,它属于Ext4文件系统上的丢失+发现目录。

- 文件系统UUID:这是一个128位值,用作Ext4文件系统的唯一卷标识符。在经常添加和删除驱动器的系统上,设备名称(如sda和sdb)经常会发生变化,导致混乱和安装点不正确。UUID是文件系统的唯一标识符,可以在/etc/fstab中用于挂载文件系统。

- 兼容功能:这两个值都是32位。S_feature_compat字段包含相容功能的32位位掩码。文件系统可以免费支持此字段中定义的功能。另一方面,如果内核不理解s_feature_incompat中定义的任何特征,文件系统挂载操作将无法成功。

Binary file added image-21.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-22.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.