4.3 F2FS

F2FS是三星专为NAND Flash存储设备设计的一个linux文件系统。

1. 基于LFS(Log-structured File System)类型,使用copy-on-write策略直接写到新的数据块(异地更新),避免等待block擦除的开销,解决了需要先擦后写的问题;

2. append-only的日志写策略,将随机写转化成顺序写,极大的提升了随机写的性能。同时也相当于在文件系统层天然做了磨损均衡,避免对某个块频繁擦除导致被“写穿”。

设备使用率较高场景下,寻找可用日志时间较长,转成threaded logging策略。

3. LFS维护一个大的日志区域,F2FS则根据冷热数据的访问差异,维护了6个日志区域,

  • NODE HOT 区域:目录的NODE结构,因为切换目录等操作都会频繁使用到。
  • NODE WARM区域:一般文件的NODE结构,需要对文件读写才会使用到,因此不像目录的NODE结构使用频繁。
  • NODE COLD区域:间接寻址的NODE,对于非常大的文件,会通过间接寻址才能找到数据所在的区域,但是一般而言很少有超级大的文件,因此访问最不频繁。
  • DATA HOT 区域:目录的DATA结构,因为切换目录等操作都会频繁使用到,需要从DATA读取文件名等信息。
  • DATA WARM 区域:一般文件数据,正常的IO产生的DATA都属于这一类型。
  • DATA COLD 区域:不频繁修改的数据。多媒体(多为只读文件),搬移数据块(如GC产生读写的数据,gc会挑热度最低的数据),或者用户指定的只读文件。

冷热数据分离同步写入,根据数据的“age”进行选择或者最小开销原则,提高回收效率;

4. 借鉴数据库Checkpoint的实现,前滚和后滚恢复保证一致性。

系统需要保证一致性时(例如:sync操作),则会触发一次写Checkpoint,会将当前的系统状态(主要是管理数据)完整写入到Checkpoint区域。在发生意外掉电时,f2fs会根据最新的Checkpoint内容来还原系统状态,这个流程就是后滚恢复。

前滚恢复,在写入普通文件时,很多时候只需要对特定文件进行一致性操作,而系统中的其他数据则不关注,如果每次都写入一次Checkpoint,未免太过耗时。所以在写入普通文件时,只需要确保该文件的管理数据落盘即可,并通过特殊的标记,记录其状态,在恢复流程中,根据写入的数据可以恢复到掉电前的状态。

分为为了互为备份,如果本次写入的是CP #0,那么下次写入的是CP #1。每次写CP的时候都带有一个版本号,表示第几次写CP。在后滚恢复流程中,首先判断哪个CP可用,如果两个都可用,则根据版本号选择最新的那个。

在写CP的时候,需要先写入f2fs_checkpoint结构体,然后写入其他内容,最后保证前面内容都写入后,再写入一个f2fs_checkpoint结构体,这样的目的是为了可以判断该CP是否可用。如果两个f2fs_checkpoint结构体内容对不上(主要是版本号),则表示该CP损坏,不能用来恢复数据。

5. 解决雪崩问题(LFS异地更新的引发直接或间接node以及inode和inode map的一系列修改)

由于使用直接地址为索引,A1 -> B1 -> C1 ->D1的索引树中,数据块D1被修改后,由于COW的策略,新数据会写入到新地址D2。C1中对应的地址改成D2也会形成C2。A1、B1、C1管理块递归修改。

f2fs -- NAT表负责做地址翻译,避免直接索引地址。A1中存的是B1的id号,同样B1索引的是C1的id号只有C1直接索引D1的地址,所以当D1被修改后,只需要额外修改C1的和NAT表中C1的地址索引(注:NAT表的修改是就地更新,也就是先擦除后写入),由于C1的id号保持不变,所以A1、B1的内容保持不变,这样就减少了因连锁反应引起的修改。

  

F2FS根据存储介质划分为6个区域,前5个区域称为元数据区域用来维持F2FS的一致性,而最后是保存数据的主要区域。

Node只支持OPU(outplace update,异地

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
f2fs文件系统调用主要涉及以下几个组件和函数: 1. 文件系统类型定义:在f2fs文件系统中,通过定义一个file_system_type结构体来表示文件系统类型。其中包括了文件系统的名称、挂载函数、卸载函数等信息。在f2fs中,文件系统类型定义如下: static struct file_system_type f2fs_fs_type = { .owner = THIS_MODULE, .name = "f2fs", .mount = f2fs_mount, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; 2. 挂载函数:f2fs_mount函数是用来将块设备挂载成f2fs文件系统的函数。它是通过调用mount_bdev函数来实现的。具体的挂载过程包括了填充f2fs super block信息等操作。在f2fs中,挂载函数定义如下: static struct dentry *f2fs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { return mount_bdev(fs_type, flags, dev_name, data, f2fs_fill_super); } 3. 填充super block信息:f2fs_fill_super函数用来填充f2fs文件系统的super block信息。它会读取块设备上的super block数据,并将其解析为内存中的数据结构。在f2fs中,填充super block信息的函数定义如下: static int f2fs_fill_super(struct super_block *sb, void *data, int silent) { // 填充super block信息的具体实现 } 通过以上组件和函数,f2fs文件系统可以被调用和使用。当用户在用户空间执行mount操作时,会回调到文件系统类型中定义的mount函数,即f2fs_mount函数。在f2fs_mount函数中,会调用mount_bdev函数来实现具体的挂载过程,包括填充super block信息等操作。最终,f2fs文件系统就可以被成功挂载和使用。 #### 引用[.reference_title] - *1* [f2fs学习笔记 - 4. f2fs文件系统组件说明](https://blog.csdn.net/jasonactions/article/details/122417105)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [f2fs学习四: f2fs文件系统挂载](https://blog.csdn.net/guozhidixian/article/details/115498708)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值