EXT4文件组织 - EXT4文件系统详解2

EXT4 文件系统是从 EXT2 和 EXT3 上发展而来的,这里我们来分析它们是如何将一个文件的内容组织起来,从而在磁盘上“拼凑出一个文件”。

EXT2文件组织方式

出于对EXT4文件系统兼容性的考虑,我们尝试在先从EXT2文件系统的文件组织方式说起。

EXT2文件节点定义:http://lxr.free-electrons.com/source/fs/ext2/ext2.h?v=4.1#L297

EXT2 文件节点变量有点多,我们需要关注 i_block[] 这个成员,这个成员是解析 EXT2 文件组织方式的重要入手点。

__le32  i_block[EXT2_N_BLOCKS];     /* Pointers to blocks */

#define EXT2_NDIR_BLOCKS                12
#define EXT2_IND_BLOCK                  EXT2_NDIR_BLOCKS
#define EXT2_DIND_BLOCK                 (EXT2_IND_BLOCK + 1)
#define EXT2_TIND_BLOCK                 (EXT2_DIND_BLOCK + 1)
#define EXT2_N_BLOCKS                   (EXT2_TIND_BLOCK + 1)

在上面的代码中我们给出了后面五行宏定义的代码,用来解释 EXT2_N_BLOCKS 数值大小的由来,结合图1进行说明会更加清晰。

这里写图片描述
图 1 EXT2/EXT3文件组织索引结构

i_block[] 占用了60 Bytes 的固定空间,包含15个32位的无符号整形变量,每一个变量记录了一个块号(Block Number, http://lxr.free-electrons.com/source/fs/ext2/ext2.h?v=4.1#L25)用来指示磁盘上的一个Block。最前面[0 - 11]这12个块号都直接标示了一个数据块用来保存数据,因此可以用来记录 12 * 4KB = 48KB 的文件内容。这太小了,放不下多少东西!我们再来看后面的内容。

i_block[12] 表示一级索引,这个一级索引同样记录了一个块号,不过这个块号所指示的Block并不用来保存数据,而是保存了 4KB / 4B = 1024 个直接索引,这些直接索引在用来指示数据块的位置。因此,以及索引可以用来保存 4KB / 4B * 4KB = 4MB 的文件内容。

依此类推,i_block[13]i_block[14] 分别保存了二级索引和三级索引,分别可以用来保存 4GB 和 4TB 的文件内容。也就是说通过这种分级索引映射的方式,EXT2文件系统最大可以支持单个文件的大小是 4TB + 4GB + 4MB + 48KB

EXT4文件组织方式

分析完EXT2/3的文件组织方式,发现这种方法有不少缺陷:首先,文件存储会消耗很多额外的磁盘空间,每增加4MB的大小就需要额外的4KB来映射文件内容;另外,4TB的单个文件有点小,要知道现在数据库文件动辄就要几十甚至是上百TB。网上说EXT4文件系统支持最大的单个文件大小是64TB,我也没弄明白这是怎么计算出来的,不过从CentOS 7 开始改为默认采用XFS文件系统,能够支持更大的单个文件尺寸。

EXT4文件系统在组织文件时使用了 extents 方法来改进旧的分层索引映射的方式,所谓的extents方法简单地说就是构建extent树来组织文件,并且记录文件使用的某片区域的起始位置而非一一映射。extent树最重要的两个数据结构式 ext4_extent_idxext4_extent_header,先把代码贴出来吧。

http://lxr.free-electrons.com/source/fs/ext4/ext4_extents.h?v=4.1#L86

struct ext4_extent_idx {
    __le32  ei_block;   /* index covers logical blocks from 'block' */
    __le32  ei_leaf_lo; /* pointer to the physical block of the next *
                 * level. leaf or next index could be there */
    __le16  ei_leaf_hi; /* high 16 bits of physical block */
    __u16   ei_unused;
};
struct ext4_extent_header {
    __le16  eh_magic;   /* probably will support different formats */
    __le16  eh_entries; /* number of valid entries */
    __le16  eh_max;     /* capacity of store in entries */
    __le16  eh_depth;   /* has tree real underlying blocks? */
    __le32  eh_generation;  /* generation of the tree */
};
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值