背景
由于磁盘的机械特征,导致要想提升它的读写速度是非常困难的。因此SSD应运而生,它的读写速度,因为没有磁头,导致其寻道时间几乎为0。
SSD的分类
- 基于闪存类:采用FLASH芯片作为存储介质,擦写次数有限制
- 基于DRAM的固态硬盘:采用DRAM作为存储介质,它是一种高性能的存储器,而且使用寿命很长,美中不足的是需要独立电源来保护数据安全
针对闪存ssd的特性,虽然其速度快,我们知道大部分的I/O操作都是随机写,如果不仔细的处理,会严重增加I/O的延迟和缩短SSD的寿命。虽然LFS和BTRFS有效的降低了随机写的影响,但是没有完全考虑到SSD的特性(性能和寿命)
F2FS出现了,它是专门为基于 NAND 的存储设备设计的新型文件系统,F2FS是第一个公开提出以优化性能和寿命并且广泛使用的文件系统,下面我们了解F2FS的设计原理
F2FS设计
F2FS磁盘布局示意图
-
F2FS将磁盘分为三块,super block和随机写区域和顺序写区域,和LFS一样,F2FS也是采用segment来管理磁盘,不过和LFS不同的是,F2FS在段上又加了两层概念,连续的多个segment组成Section,连续多个Section又组成一个Zone
-
Super Block(SB):超级块,存放F2FS的参数,格式化时写入,不可变
-
Check Point(CP):存放文件系统状态,比如空闲空间总量,当前激活segment的摘要信息,CP占用两个segment,但是只有一个是有效的,其存有版本号,只有版本号最高的才是有效的
-
Segment Information Table(SIT):记录每个segment的的信息,比如有效块的总数、数据块有效性bitmap,当该segment无有效块时,可以回收
-
Node Address Table(NAT):一个记录排序在Main区域的node blocks的块地址表,用于定位所有主区域的索引节点块
-
Segment Summary Area(SSA):存储了很多summary项,summary项记录了Main area中块的所有者信息
-
Main area:包含两种类型的块,一种是node类型,一种是data类型,node类型存放inode和数据块的索引;data存放目录或文件。注意一个Section中不会存在两种类型的块
一个查找文件的过程
-
查找过程示意图
-
查找过程
- 根据根目录的inode号从NAT中找到inode的块地址
- 在根目录的inode块的数据块中按目录名字查获得目录对应的inode号
- 用目录对应的inode号从NAT中获取真实物理位置
- 然后在目录对应的inode的数据块中找到对应的目录或者文件的inode
- 重复上边第3-4步骤,直到找到对应的文件
文件结构
-
F2FS文件结构示意图,和前边的LFS和ext结果差不多,F2FS没有ext文件系统的extend树
-
F2FS解决LFS的“wandering tree”
- LFS存在的问题:如果文件的数据块修改之后,间接地址指针块会递归修改
- F2FS解决方案:引入了NAT结构,当数据块修改时,只有直接地址指针块会修改,间接地址块不会修改,因为间接地址块中存放的不是直接地址块的地址,而是存放的NAT项,修改后的直接地址块地址会存入NAT项中,项的索引并不会变。
- F2FS inode可以内联小数据和扩展属性。默认的配置可以存放3,692 bytes,保留200 bytes用于扩展属性。内联可以减小空间开销和提升I/O性能
目录结构
-
目录块的结构,一个目录块分了bitmap、Reserved、dentries、filename四个区域。dentries中有214个dentry,每个占11byte,最多存储214个取决于文件名字长度;filename区域有214个slot,每个slot8byte,最多存储214个,但是如果有文件名超过8byte,那就需要多个slot存储,那么一个块将不能存储214个目录项
-
dentry结构如上图,包括hash、ino、len(文件名长度)、type
-
大目录处理,和所有文件系统一样,一个目录如果含有太多的目录项,那么查询就会变慢。ext采用的hash B-tree,F2FS采用的是多级hash表,示意图如下
关于每个level的桶里有多少block,有如下公式
l e v e l N _ b l o c k n u m = { 2 , N < M A X _ D I R _ H A S H _ D E P T H 2 4 , N ≥ M A X _ D I R _ H A S H _ D E P T H 2