英文原文网址:https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout
本文主要介绍ext4文件系统在磁盘上的格式。一些和ext2/3文件系统共同的特性也可以适用于ext2/3,只不过ext4的一些特性ext2无法支持。
1 相关术语
ext4文件系统把一个物理存储切分成物理快的数组,可以减少bookkeeping的开销,并且提升大数据量传输的吞吐量。通常块大小是4KB,计算公式为2 ^ (10 + sb.s_log_block_size
) bytes。在本文所有的磁盘地址都是基于这个逻辑块大小,而不是原始的 LBAs和1024byte的块。为了方便阅读,本文后面的块大小都用$block_size来表示,
当分析已经格式化好了的文本块的时候,sb指的是super block区域,inode指的是inode table区域。
2 概述
ext4文件系统被切分为多个块组。为了减少由于碎片化导致的性能下降,块分配器尽量让每个文件的块都在同一个块组内,这样可以减少seek的定位时间。块组的大小由sb.s_blocks_per_group决定,单位是块,默认情况下是8*block_size_in_bytes。在默认块大小为4KB时,每个块组会包含32768个块,总大小128M。块组的个数由设备总大小除以每个块组的大小。
所有ext4区域都是用小端存储方式。所有jbd2(日志) 都是用大端存储模式。
2.1 块
ext分配存储的单位是块,一个块是一组扇区组成,总大小在1K到64K,扇区数量必须是2的整数倍。多个连续块又组成块组。块大小在用命令mkfs创建文件系统的时候指定,一般是4KB。很多人可能都会经历过挂载问题,特别是当块大小比页大小还要大的时候(例如:64K的块,但是只有4K的内存页)。默认文件系统可以支持2^32Byte的块,如果64位系统特性使能,可以有2^64Byte的块。
注意:没用用extens的文件必须放在文件系统的前2^32个块里面,有extents的文件必须放在前2^48个块中,更大的文件会有什么问题目前还不确定。
2.2 布局
标准的块组布局如下:
块组0比较特殊,前1024个Bytes都没有用,为了兼容安装x86的启动扇区和其他特俗场景。超级快会在1024的偏移处开始,每一个块组都是这样(通常来说都是第0块组)。然而当块大小刚好等于1024,于是第0块被标记为已经在使用,超级快就被设置到第1块。对于所有其他块组,都没有padding的1024Byte。
ext4驱动主要操作超级快,和块组0中找到的组描述符。superblock和组描述符会重复的拷贝到一些块组中,防止磁盘起始位置被破坏,但是,并不是每一个块组都需要保存一份这种拷贝。如果一个块组没有这种备份,那么块组直接从data block bitmap开始。注意,当系统是刚刚格式化的,mkfs会在块组描述符后分配“保留的GDT 块”,用于后期的功能扩展。默认情况下文件系统允许在原来的文件系统大小基础上扩容,要求是1024的倍数。
inode table的地址由变量grp.bg_inode_table_*给出。inode table是一个连续的足够大的块,能包含sb.s_inodes_per_group*sb.s_inode_size bytes。