3 F2FS文件系统的磁盘布局分析
F2FS 将整个卷切分成大量的 Segments,每个 Segment 的大小是固定的2 MB。连续的若干个Segments 构成 Section,连续的若干个 Sections 构成 Zone。默认情况下一个 Zone 大的大小是一个 Section,而一个 Section 的大小是一个 Segment。
F2FS 将整个卷切分成6个区域,除了超级块(Superblock,SB)外,其余每个区域都包含多个 Segments。
3.1 块(Blocks)、段(Segments)、区段(Sections)、存储区(Zone)
3.1.1 Blocks
(1) F2FS文件系统的所有块大小都是4KB,F2FS 代码隐式地将块大小链接到系统的页大小,因而F2FS不可能在更大的页的系统上运行,如 IA64 和 PowerPC。
(2) 块地址是32位的,最大文件系统是2^(32+12) Bytes,也就是16TB(完全大于当前的 NAND flash 设备的大小)。
3.1.2 Segments
(1) 连续的Blocks集合成Segments,一个Segment的大小是512个Blocks(也就是2MB);
(2) 每个Segment都有一个Segment Summary Block元数据结构,描述了Segment 中的每个Block的所有者(该块所属的文件及块在文件内的偏移)。Segment Summary主要用于在执行Cleaning操作时识别哪些Blocks中的数据需要转移到新的位置,以及在转移之后如何更新Blocks的索引信息。一个Block就可以完全存储512个Blocks的summary信息,每个blocks都有一个1 bit的额外空间用于其它目的。
(3) 2MB是最合适的Segment大小,太大不合适,太小又会造成存储summary信息的Block空间浪费;
3.1.3 Sections
(1) 连续的Segments集合成Section。Section中具有的segments个数是任意的,但是要满足是2的幂;默认情况下,一个Section大小等同于一个Segment(2^0 Segments);
(2) 一个Section对应log structuring的一个区域“region”,log在使用下一个Section之前,通常要从头到尾将当前的Section填满数据;
(3) 清理器Cleaner一次处理一个Section;
(4) 在F2FS中,任意时刻都有6个“打开的”Sections用于将各种不同种类的数据(元数据、数据)分别写入到各个Sections中,实现数据分离。这样便允许文件内容(数据)与其索引信息(节点,node)分离,允许F2FS文件系统根据各种启发式方法将Sections划分成三类:即“hot”、“warm”、“cold”。例如,目录数据被当做hot来对待,使其与文件数据分离,存放到“hot”Section中。Cold数据是指那些很长时间内都不会改变的数据,因而装满Cold数据的Section就不需要执行Clean操作。对于hot节点(索引信息节点),一般更新很快,一段时间之后,装满 hot 节点的Section中的有效数据(alive data)就会很少,因而选择这样的Section进行Clean操作开销就很小(因为要转移的数据很少)。
3.1.4 Zone
(1) 连续的Sections集合成Zone。一个Zone可以包含任意整数个Sections。默认是一个Zone中包含一个Section;
(2) 设置Zone的唯一目的是尽可能将6个打开的Sections位于Flash设备的不同的子设备中。理论上,Flash设备通常是由一组相互完全独立的子设备构成,每个子设备都可单独地处理I/O请求,不同子设备可并行处理I/O请求;如果Zone的大小与子设备大小对齐,6个打开的Sections可并行写入,充分利用设备的特性;
(3) Zone构成了F2FS的“主要(main)”区域。
3.1.5 Meta Area
F2FS有一个“meta”区域,包含了各种不同的元数据(如之前提到的segment summary),这一部分不是采用标准的log-structured流水线方式管理,因而更多的工作留给了FTL去做。有三种方法管理对“meta”区域的写操作:
a) 第一,有少量的只读数据(超级块)从来都不是不是在文件系统创建的时候立即写入;
b) 第二,对Segment Summary Block 简单采取本地更新的方法。这种本地更新可能导致文件系统奔溃后数据块“修正”内容的不确定性,但对segment summary来说这都不是问题,segment summary blocks中的数据在使用前要进行有效性验证,如果有任何信息丢失的可能,它都将会在恢复进程中从其他source中恢复。
c) 第三种方法,分配需求空间两倍大小的空间,使得每个block都有两个不同的位置:一个Primary,一个Secondary,任意时刻,两个位置的block仅有一个是live状态。因而LFS的Copy-On-Write需求就可以通过向non-live位置的block写入更新后的block内容并且更新记录哪个位置的block是live状态的方式简单实现。对于元数据来说,这种技术是实现快照功能的主要实现方法。当创建一个Checkpoint的时候,F2FS执行少量的Journaling更新到最后的组(last group),这在一定程度上减轻了FTL的工作。