F2FS
F2FS(Flash-Friendly File System)是一种专为配备闪存转换层(Flash Translation Layer)的基于 NAND 的闪存设计的 文件系统。与 JFFS 或 UBIFS 不同,它依赖于 闪存转换层(FTL) 来处理写分布。它从内核 3.8 开始支持。
所有带有 SCSI/SATA/PCIe/NVMe 接口的闪存都具备 FTL [1],而裸 NAND Flash 和 SmartMediaCards 则没有 [2]。
已知问题
fsck 失败
F2FS 的 fsck 功能较弱,在突然断电的情况下可能导致数据丢失 [3][4]。
如果断电频繁,请考虑使用替代的 文件系统。
长时间运行 fsck 延迟启动
如果在启动之间内核版本发生变化,`fsck.f2fs` 工具将执行完整的文件系统检查,完成时间会更长 [5]。
由于最近的提交 [6],未来可能会缓解此问题。
GRUB 支持
虽然 GRUB 从 2.0.4 版本开始支持 F2FS,但它无法正确读取启用了 `extra_attr` 标志的 F2FS 分区上的启动文件(有关更多详细信息,请参阅 GRUB#不支持的文件系统)。
无法为“/var/log/journal”设置文件属性
如果您的 日志 中出现此错误
Cannot set file attributes for '/var/log/journal', maybe due to incompatibility in specified attributes, previous=0x10001000, current=0x10001000, expected=0x10801000, ignoring.
则可以 安全地忽略:这是由于 systemd-tmpfiles 尝试使用 F2FS 不支持的文件系统功能。
创建 F2FS 文件系统
本文档假设设备已设置好 分区。请 安装 `f2fs-tools`。使用 `mkfs.f2fs` 来格式化目标分区,假定目标分区为 `/dev/sdxY`。
# mkfs.f2fs -l mylabel -i -O extra_attr,inode_checksum,sb_checksum /dev/sdxY
- `-i` 选项用于允许 为 inode 分配更多空间。
- `extra_attr`、`inode_checksum` 和 `sb_checksum` 是选项,它们有助于 `fsck.f2fs` 检测和修复某些类型的文件系统损坏。有关所有可用选项,请参阅 mkfs.f2fs(8)。
压缩
要使用压缩,请包含 `compression` 选项。例如:
# mkfs.f2fs -l mylabel -O extra_attr,inode_checksum,sb_checksum,compression /dev/sdxY
挂载文件系统时,指定 `compress_algorithm=(lzo|lz4|zstd|lzo-rle)`。使用 `compress_extension=txt` 会导致所有 txt 文件默认被压缩。
为了指示 F2FS 压缩文件或目录,请使用:
$ chattr -R +c [FOLDER]
基于文件的加密支持
自 Linux 4.2 起,F2FS 原生支持文件加密。加密应用于目录级别,不同的目录可以使用不同的加密密钥。这与块设备级别的 dm-crypt 以及堆叠式加密文件系统 eCryptfs 不同。要使用 F2FS 的原生加密支持,请参阅 fscrypt 文章。使用以下命令创建文件系统:
# mkfs.f2fs -l mylabel -O extra_attr,inode_checksum,sb_checksum,encrypt /dev/sdxY
或者稍后使用 `fsck.f2fs -O encrypt /dev/sdxY` 添加加密功能。
挂载 F2FS 文件系统
然后可以手动或通过其他机制挂载文件系统:
# mount /dev/sdxY /mnt/foo
推荐的挂载选项
由于 F2FS 是为闪存设备设计的,因此压缩是一个好主意。您必须在 `mkfs.f2fs` 时启用它。一些挂载选项可以略微改进性能。
# mount -o compress_algorithm=zstd:6,compress_chksum,atgc,gc_merge,lazytime /dev/sdxY /mnt/mountpoint
- `compress_algorithm=zstd:6` 告诉 F2FS 使用 zstd 进行压缩,级别为 6,这应该能提供相当不错的压缩率。
- `compress_chksum` 告诉文件系统通过校验和验证压缩块(以避免损坏)。
- `atgc,gc_merge` 启用更好的垃圾收集器,并使某些前台垃圾收集异步进行。
- 注意 请参阅 #使用某些选项无法重新挂载。
- `lazytime` 不要同步更新访问或修改时间。提高 IO 性能和闪存耐用性。
Discard 的实现
默认情况下,F2FS 使用混合 TRIM 模式挂载,其行为类似于 连续 TRIM。此实现创建异步 discard 线程,以减轻 RW IO 期间的长 discard 延迟。它将候选块保留在内存中,然后在空闲时由线程发出 [7]。因此,希望使用 定期 TRIM 的用户需要在 `/etc/fstab` 中隐式设置 `nodiscard` 挂载选项,或者在手动挂载时将其传递给 `mount`。
检查和修复
对 F2FS 文件系统的检查和修复通过 `f2fs-tools` 包提供的 `fsck.f2fs` 完成。要检查文件系统,请执行:
# fsck.f2fs /dev/sdxY
根据结果,请参阅 fsck.f2fs(8) 中可用的修复不一致性的开关。例如:
# fsck.f2fs -f /dev/sdxY
扩展 F2FS 文件系统
文件系统卸载后,如果分区被扩展,则可以扩展文件系统。 目前不支持缩小。
首先使用 分区工具 调整分区大小:例如,假设 `parted` 控制台的 `print` 命令输出如下:
Number Start End Size File system Name Flag 1 1049kB 106MB 105MB fat32 EFI system partition boot, esp 2 106MB 11,0GB 10,9GB ext4 3 11,0GB 12,3GB 1322MB f2fs 4 31,0GB 31,3GB 261MB ext4
要将 `f2fs` 分区大小调整为占用直到第四个分区的全部空间,只需输入 `resizepart 3 31GB` 然后 `exit`。现在使用以下命令将文件系统扩展到填满新分区:
# resize.f2fs /dev/sdxY
其中 `/dev/sdxY` 是目标 F2FS 卷。有关支持的选项,请参阅 resize.f2fs(8)。
故障排除
使用某些选项无法重新挂载
如 Fsck#启动时检查 中所述,内核默认将文件系统保持为只读状态,并且需要显式传递 `rw` 内核参数,或者让 systemd 使用 `systemd-remount-fs.service` 将文件系统重新挂载为读写状态。
当将文件系统从只读状态重新挂载为读写状态时,`mount -o remount,... /` 命令可能会因为多种原因失败,这可能导致根文件系统保持只读状态,或者系统无法启动,并出现错误消息:
Failed to start Remount Root and Kernel File Systems.
如果在 fstab 文件中指定了 `atgc` 选项但未作为内核参数传递,F2FS 内核模块将不允许重新挂载以添加或清除 `atgc` 选项 [8][9],请执行以下操作之一:
自 `linux` 6.2 版本以来,内核中会进行 检查 以在文件系统只读时禁用 `flush_merge`,但检查的是重新挂载之前的文件系统状态。正如 FS#77596 中所述,执行以下操作之一:
- 将 内核参数 `rw` 添加到您的引导加载程序配置中。
- 从 fstab 中删除 `flush_merge` 挂载选项。
每个功能的最低版本要求
| 功能名称 | 描述 | 内核版本 | F2FS 工具版本 | 内核提交 | F2FS 工具提交 |
|---|---|---|---|---|---|
| 丢失父 inode 号(pino)位 | 如果一个文件被链接,F2FS 可能会丢失其父 inode 号,导致对链接文件的 fsync 调用每次都需要执行检查点。但是,如果 pino 可以在检查点后恢复,则可以调整后续 fsync 调用的前滚机制,从而显著提高 fsync 性能。 | 3.11 | N/A | 354a3399dc6f ("f2fs: recover wrong pino after checkpoint during fsync") | N/A |
| 内联扩展属性 | 添加一个挂载选项 `inline_xattr`,在设置 `xattr` 时启用。如果启用此挂载选项,所有文件都将标记有 `inline_xattrs` 标志。 | 3.12 | 1.2.0 | 444c580f7e9a ("f2fs: add flags for inline xattrs") | cd1e470 ("fsck, lib: support inline xattr") |
| 内联数据 | 通过 `inline_data` 挂载选项支持常规/符号链接 inode 中的内联数据。 | 3.14 | 1.3.0 | 1001b3479ce9 ("f2fs: add flags and helpers to support inline data") | 061ee67 ("f2fs-tools: add inline data check") |
| 大型目录 | 添加一个参数来调整大型目录的结构,以优化查找性能。 | 3.15 | 1.4.0 | 3843154598a0 ("f2fs: introduce large directory support") | 99250ec ("mkfs: support large directory") |
| 大型卷 | 支持超过约 3TB 的大型卷。 | 3.16 | 1.4.0 | 1dbe4152168d ("f2fs: large volume support") | 092e3d9 ("mkfs.f2fs: large volume support") |
| Fsck 标志 | 在超级块中添加“需要 fsck”标志,以便稍后进行 fsck.f2fs,此标志只能由 fsck.f2fs 移除。 | 3.18 | 1.4.0 | 2ae4c673e3cb ("f2fs: retain inconsistency information to initiate fsck.f2fs") | 7eb6c5a ("fsck.f2fs: add auto_fix feature") |
| 快速启动标志 | 允许写入检查点节点摘要以加快突然断电后的启动速度。 | 3.2 | 1.4.1 | 119ee9144534 ("f2fs: split UMOUNT and FASTBOOT flags") | b57708a ("dump.f2fs: show checkpoint flag") |
| 内联数据(修复) | 增强内联数据功能的稳定性(更改磁盘布局)。 | 3.19 | 1.4.1 | b3d208f96d6b ("f2fs: revisit inline_data to avoid data races and potential bugs") | 7279f03 ("fsck.f2fs: fix DATA_EXIST flag for old partition") |
| 内联 dentry | 支持将目录条目存储在目录 inode 中。 | 3.19 | 1.4.1 | 34d67debe02b ("f2fs: add infra struct and helper for inline dir") | 6d88640 ("fsck.f2fs: support inline_dentry") |
| 版本信息 | 存储当前内核版本,在 fsck 时更新。 | 4.2 | 1.4.1 | 0040b933187b ("f2fs: add missing version info in superblock") | 6fa2547 ("fsck.f2fs: trigger fsck.f2fs when new change was made") |
| 初始版本信息 | 标识格式化时的 Linux 内核版本。 | 4.2 | 1.4.1 | 0040b933187b ("f2fs: add missing version info in superblock") | 762eedf ("mkfs.f2fs: give a kernel version for initial format") |
| 保持大小位 | 确保预先分配(使用 fallocate)的文件大小在回滚恢复期间不发生变化。 如果文件需要在回滚恢复期间保持其由 fallocate 设置的 i_size,则需要关闭自动恢复。 |
4.1 | N/A | 26787236b366 ("f2fs: do not activate auto_recovery for fallocated i_size") | N/A |
| 内联点 | 支持修复缺少 '.' 或 '..' dentries 的目录,它会更改磁盘布局。 | 4.1 | 1.5.0 | 510022a85839 ("f2fs: add F2FS_INLINE_DOTS to recover missing dot dentries") | f1e4f9c ("fsck.f2fs: fix missing dentries") |
| 加密 | 启用文件系统级加密支持。 | 4.2 | 1.5.0 | cde4de120577 ("f2fs crypto: declare some definitions for f2fs encryption feature") | 6e6c713 ("mkfs.f2fs: set encryption feature") |
| 块分带 | 指定 F2FS 文件系统支持块分带功能。它依赖于多设备功能。 | 4.8 | 1.7.0 | 52763a4b7a21 ("f2fs: detect host-managed SMR by feature flag") | 70a8fc3 ("mkfs/fsck: add host-managed smr feature") |
| 多设备 | 启用支持将多个物理存储设备视为单个逻辑卷。 | 4.1 | 1.8.0 | 3c62be17d4f5 ("f2fs: support multiple devices") | de7e07e ("f2fs-tools: support multiple devices") |
| Trimmed 标志 | 优化对已丢弃块的处理。此标志(CP_TRIMMED_FLAG)允许 F2FS 内核模块记录在卸载前已修剪所有无效块,以便下次挂载时可以跳过这些操作。 | 4.12 | 1.9.0 | 1f43e2ad7bff ("f2fs: introduce CP_TRIMMED_FLAG to avoid unneeded discard") | f642b24 ("f2fs-tools: support to set and recognize CP_TRIMMED_FLAG") |
| NAT 位图 | 添加位图以表示包含所有已使用/空闲 nid 条目的空/满 NAT 块,以优化 NAT 块的管理。 | 4.11 | 1.9.0 | 22ad0b6ab466 ("f2fs: add bitmaps for empty or full NAT blocks") | 191573e ("mkfs.f2fs: support nat_bits feature") |
| CRC 恢复 | 在回滚恢复期间使用 CRC(除了检查点版本)。这提供了一种更健壮可靠的方法来确定要恢复哪个文件版本。 引入新标志(CP_CRC_RECOVERY_FLAG)以指示何时使用新机制。 |
4.9 | 1.9.0 | a468f0ef516f ("f2fs: use crc and cp version to determine roll-forward recovery") | a0bd5b9 ("f2fs-tools: catch up up-to-date checkpoint flag") |
| 原子写入 | 原子写入功能,此功能不改变磁盘布局。 | 4.14 | 1.9.0 | e65ef20781cb ("f2fs: add ioctl to expose current features") | 8721519 ("f2fs-tools: add atomic_write feature flag") |
| 额外属性 | 启用额外属性功能,某些其他功能(见下文)需要此功能。 | 4.14 | 1.9.0 | 7a2af766af15 ("f2fs: enhance on-disk inode structure scalability") | dad33a1 ("f2fs-tools: enhance on-disk inode structure scalability") |
| 项目配额 | 启用项目 ID 跟踪以进行项目配额会计。使用额外属性。 | 4.14 | 1.9.0 | 5c57132eaf52 ("f2fs: support project quota") | a3d9db1 ("f2fs-tools: support project quota") |
| inode 校验和 | 启用 inode 校验和。使用额外属性。 | 4.14 | 1.9.0 | 704956ecf5bc ("f2fs: support inode checksum") | 7457726 ("f2fs-tools: support inode checksum") |
| 无 CRC 恢复 | 在检查点恢复过程中禁用 CRC 的使用,仅依赖于检查点版本。 | 4.16 | 1.10.0 | f236792311f4 ("f2fs: allow to recover node blocks given updated checkpoint") | f789444 ("fsck.f2fs: allow roll-forward for small checkpoint fix") |
| 灵活的内联 xattr | 启用灵活的内联 xattr 大小。使用额外属性。 | 4.15 | 1.10.0 | 6afc662e68b5 ("f2fs: support flexible inline xattr size") | 8d46072 ("f2fs-tools: support flexible inline xattr size") |
| 配额 sysfile | 启用配额功能(它允许 F2FS 维护一个内部 sysfile 来记录磁盘配额数据)。 | 4.15 | 1.10.0 | 234a96896142 ("f2fs: add quota_ino feature infra") | 23a872f ("mkfs.f2fs: support quota option in mkfs") |
| Pinfile | 支持 Pinfile 以避免迁移其物理数据块。 | 4.16 | 1.12.0 | 1ad71a27124c ("f2fs: add an ioctl to disable GC for specific file") | "91bb7b2 (""f2fs-tools: fix to reset i_gc_failures offline"") 820b5e3 (""sload.f2fs: use F2FS_COMPRESS_RELEASED instead of IMMUTABLE bit"") 添加了 F2FS_PIN_FILE 标志,但未使用。" |
| inode 创建时间 | 启用 inode 创建时间功能。需要额外属性。 | 4.16 | 1.10.0 | 1c1d35df7110 ("f2fs: support inode creation time") | 4862080 ("f2fs-tools: support inode creation time") |
| 扩展节点位图 | 启用扩展节点位图以增加节点块数量的上限。 | 4.17 | 1.11.0 | 199bc3fef29c ("f2fs: support large nat bitmap") | baaa076 ("mkfs.f2fs: expand scalability of nat bitmap") |
| 热文件扩展名 | 允许指定文件扩展名列表,F2FS 将这些扩展名的文件视为热文件。具有这些扩展名的文件的数据将存储在热日志中。 | 4.17 | 1.11.0 | b6a06cbbb5f7 ("f2fs: support hot file extension") | 6fdc37f ("mkfs.f2fs: support hot file extension") |
| lost+found | 启用 lost+found 功能。 | 4.17 | 1.11.0 | b7c409deda6b ("f2fs: introduce F2FS_FEATURE_LOST_FOUND feature") | ff37829 ("mkfs.f2fs: create lost+found directory") |
| fs-verity | 启用对 verity 保护文件(又称 fs-verity)的支持。 | 5.4 | 1.11.0 | 95ae251fe828 ("f2fs: add fs-verity support") | 76cd377 ("mkfs.f2fs: support fsverity feature") |
| 检查点禁用标志 | 指示检查点已禁用。 | 4.2 | 1.12.0 | 4354994f097d ("f2fs: checkpoint disabling") | a48bda0 ("fsck.f2fs: support checkpoint=disable") |
| 配额需要 fsck | 添加全局状态 SBI_QUOTA_NEED_REPAIR 以指示配额操作因 -EIO 或 -ENOSPC 而失败,因此稍后: a) 检查点将跳过同步 dquot 元数据。 b) CP_QUOTA_NEED_FSCK_FLAG 将在最后一个 cp 包中设置,以提示 fsck 进行修复。 |
4.2 | 1.12.0 | af033b2aa8a8 ("f2fs: guarantee journalled quota data by checkpoint") | dfede78 ("fsck.f2fs: detect and recover corrupted quota file") |
| 超级块校验和 | 启用超级块校验和。 | 4.2 | 1.12.0 | d440c52d3151 ("f2fs: support superblock checksum") | 886a924 ("f2fs-tools: introduce sb checksum") |
| 快速检查点禁用 | 添加一种快速的检查点禁用方法。 | 5.1 | N/A | db610a640eee ("f2fs: add quick mode of checkpoint=disable for QA") | N/A |
| 大小写折叠 | 在文件系统中启用大小写折叠支持。可以使用 -C 传递可选标志。 | 5.4 | 1.13.0 | 5aba54302a46 ("f2fs: include charset encoding information in the superblock") | ce64ea0 ("f2fs-tools: Add support for Casefolding") |
| 压缩 | 启用文件系统级压缩支持。需要额外属性。 | 5.6 | 1.14.0 | 4c8ff7095bef ("f2fs: support data compression") | fdd47b2 ("f2fs-tools: support data compression") |
| 调整 FS 标志 | 引入新的检查点标志 CP_RESIZEFS_FLAG,以帮助 fsck 修复与在线调整大小相关的问题。 | 5.7 | 1.14.0 | c84ef3c5e65c ("f2fs: Add a new CP flag to help fsck fix resize SPO issues") | 9a31cef ("fsck.f2fs: allow fsck to fix issues with online resize due to SPO") |
| 压缩(修复) | 此更改引入了一个新标志(F2FS_COMPRESS_RELEASED)来表示已释放的压缩块的状态。先前使用的 IMMUTABLE 位阻止了对已释放块的所有操作。 | 5.14 | 1.15.0 | c61404153eb6 ("f2fs: introduce FI_COMPRESS_RELEASED instead of using IMMUTABLE bit") | 820b5e3 ("sload.f2fs: use F2FS_COMPRESS_RELEASED instead of IMMUTABLE bit") |
| 只读镜像 | 启用只读功能,以消除小只读分区的 OVP/SSA 磁盘布局。 | 5.14 | 1.15.0 | a7d9fe3c3388 ("f2fs: support RO feature") | 1d2683f ("f2fs-tools: support small RO partition") |
| Trunc 位 | "Direct IO (DIO) 在写入实际数据之前预分配物理块,但如果发生错误或断电,用户可以访问未写入块的内容。此补丁通过以下方式修复: 1) 将 DIO 写入空洞转换为缓冲写入。 2) 截断错误或断电时未写入的块。" |
5.17 | N/A | d4dd19ec1ea0 ("f2fs: do not expose unwritten blocks to user by DIO") | N/A |
| 检查点错误记录 | 支持将详细的停止检查点错误记录到 f2fs_super_block.s_stop_reason[] 中。 | 6.1 | 1.16.0 | a9cfee0ef98e ("f2fs: support recording stop_checkpoint reason into super_block") | 2f1dde2 ("fsck.f2fs: trigger repairing if filesystem was forced to stop") |
| FS 错误记录 | 支持将 FSCORRUPTED 错误的详细原因记录到 f2fs_super_block.s_errors[] 中。 | 6.1 | 1.16.0 | 95fa90c9e5a7 ("f2fs: support recording errors into superblock") | 8cbe34e ("fsck.f2fs: trigger repairing if filesystem has inconsistent errors") |
| 16KB 块支持 | 支持 16K 块大小,mkfs 可以通过 -b 选项选择块大小,其他工具从超级块获取块大小。 | 6.7 | 尚未发布 | d7e9a9037de2 ("f2fs: Support Block Size == Page Size") | 50fd00b ("f2fs-tools: Support different block sizes") c404632 ("f2fs-tools: Refactor f2fs_dentry_block struct") ef47782 ("f2fs-tools: Refactor Summary block struct and friends") |
| 设备别名 | 启用设备别名功能。 | 6.13 | 尚未发布 | 128d333f0dff ("f2fs: introduce device aliasing file") | 8cc4e25 ("mkfs.f2fs: add device aliasing feature") |