一 文件系统缺陷导致的开机慢问题
文件系统做cp时,如果flush quota data不成功,就会在f2fs的cp区域设置了CP_QUOTA_NEED_FSCK_FLAG这个flag。
二:F2FS Fsync checkpoint 条件优化
1 问题来源:
f2fs 中,fsync 调用在满足特定条件时触发 checkpoint ,而checkpoint 会带来很大开销。
我们统计了 fsync 做 checkpoint 的原因,发现 sb need cp(CP_SB_NEED_CP)的次数占到总数的70%以上。
通过追踪代码,发现这是由于如下 change 导致的。
f2fs: fix lost xattrs of directories
This patch enhances the xattr consistency of dirs from suddern power-cuts.
Possible scenario would be:
1. dir->setxattr used by per-file encryption
2. file->setxattr goes into inline_xattr
3. file->fsync
In that case, we should do checkpoint for #1.
Otherwise we'd lose dir's key information for the file given #2.
该 change 保证了意外断电后目录 xattr 的一致性。在每次对目录设置 xattr 时,都会设置 SBI_NEED_CP flag。当 fsync 任意文件,is_sbi_flag_set(sbi, SBI_NEED_CP) 成立,从而做 checkpoint。
这样虽然保证了一致性,但某些情况下会给 fsync 带来了额外的开销,假设如下场景:
-
- 进程1:dir_a → setxattr
- 进程2:dir_b/file_b → fsync
根据 FSYNC(2),fsync 语义只保证 file_b 的所有数据被写入磁盘即可,考虑到xattr丢失的情况,也只应在 dir_b 被设置 xattr 时做 checkpoint 。但因为 dir_a 被设置了 xattr,fsync file_b 时会因为 SBI_NEED_CP flag 被设置而做 checkpoint 。
考虑到原 change 给出的场景只存在于 dir 为 file 的父目录时才会出现 xattr 丢失的现象,故可以只在父目录被设置 xattr 时做 checkpoint 。
2 解决方案
base:
在每次对目录设置 xattr 时,都会设置 SBI_NEED_CP flag。当 fsync 任意文件,is_sbi_flag_set(sbi, SBI_NEED_CP) 成立,从而做 checkpoint。
patch: f2fs: avoid needless checkpoint during fsync
在设置目录 xattr 时,将 inode 添加到链表中。取消原change里的设置 SBI_NEED_CP flag。在f2fs superblock 数据结构中添加一个链表。
-
- 若 fsync 时检测到文件所在目录的 inode 在链表中,则做 checkpoint 。
- checkpoint 完成后,所有 xattr 信息都被写入磁盘,链表被清空。
- 当删除目录时,若其 inode 在链表中,则从链表中删除。