1. Block and Inode Allocation Policy

ext4 认识到数据分配策略是文件系统关注的一种质量。在一个旋转的磁盘上,尽可能的让相关联的块连在一起,可以减少驱动器头移动和获取数据的次数,如此可以提高IO速度。在一个固态硬盘(SSD)上固然不存在移动,但分配策略可以增加每次传输请求的大小,从而减少请求的总次数。这种分配策略也会将写尽量浓缩到单个被擦除的块上,有意义的提高了重写速度。所以,它有利于尽可能的时候减少碎片。

ext4第一款克服碎片的工具是——多块分配器。当一个文件被创建,在空间会立即被写的假设下,块分配器推测性的分配8KB 磁盘空间给此文件。当文件关闭时,未用的推测的空间自然被释放,但如果推测正确(特别如许多小文件被充分写),文件数据就会被写到一个单独的多块扩展中。

ext4用到的第二个相关技巧是延迟分配。在这种模式下,当一个文件需要更多的块来供文件写,文件系统会推迟决定磁盘上的确定位置,直到有脏buffer全部写回磁盘。不答应某个替换直到它绝对需要(如提交时间已到,或sync()被调用,或内核内在溢出),通过这种方式希望文件系统能做出更好的分配决策。

ext4(和ext3)用到的第三个技巧是它尽量保证一个文件的结点下的数据块在相同的块组中。 这减少了寻找的功夫,当文件系统首次去读文件的结点以知道文件的数据块,和寻找数据块以开始IO。

ext4用到的第四个技巧是一个在可能的情况下将目录下的所有结点放在与目录相同的块组中。此时有用的假设是,一个目录下的所有文件都相关,所以把它们放在一起很有用。

ext4用到的第五个技巧是卷被分为一个个128M的块组(?这个128M怎么来的?%待答)。这些小小的容器维持数据分配的轮廓。然而,有一个故意的借口——当目录在根目录下创建,节点分配器扫描所有的块组,将目录放在负荷最小的块组下。这鼓励目录向整个磁盘扩散;当顶层目录或文件填满了一个块组,分配器简单移向下一个块组。

如果所有上述机制失效,总是可以使用e4defrag 来进行碎片整理。

2. Checksums(校验和)

2012很早的时候,元数据校验和开始加到主流的ext4和jbd2(日志块设备)数据结构,相关特色标志 metadata_csum。设计的校验和算法在超级块中指出来,尽管在2012年10月仅有的支持算法是crc32c。一些数据结构没有足够空间去适应32bit的校验和,所以只有低16位被存储了。开启64bit特性,增加数据结构大小以致能装下32bit校验和,然而,32位的文件系统不能扩展到64位模式。

现存的文件系统能通过 tune2fs -O metadata_csum 对潜在的设备进行校验和检验。如果这个命令遇到目录块缺乏足够的空间去添加校验和,你可以使用e2fsck -D 来使目录重建带着校验和。这样 额外的好处是从目录文件中移走了涣散的空间,使索引树重新平衡,如果你 _ignore_这步,你的目录将不会被校验和保护。

3. Bigalloc (大分配)

目前,块的默认大小为4k,也是支持MMU(内存管理单元)硬件上页的大小。这很幸运,因为ext4代码 还未准备好处理块大小超过页大小的情况。然而,对大多数大文件的文件系统来说,很希望能以多块的方式分配磁盘块以减少碎片和上面的元数据。大分配特性,正是提供这种能力。管理员可以设置块簇大小在mkfs的时候(super block 中的s_log_cluster_size);设置这个属性后,block bitmaps 是记录的块簇的,而不是一个个块的。这意味着块组可以是几个G的,而不只是128M;然而,最小分配单元变成了一个簇,而不是一个块,即使对于目录来说。TaoBao 有这么一个补丁集来扩展扩展树,“用簇单元代替块单元”,尽管不清楚这些补丁集用到哪儿去了。