F2FS

出自 ArchWiki

F2FS (闪存友好文件系统)是一种用于配备闪存转换层(Flash Translation Layer, FTL)的基于 NAND 闪存的文件系统。与 JFFS 或 UBIFS 不同,它依赖 FTL 来处理写入分布。内核 3.8 及更高版本支持它。

在所有具有 SCSI/SATA/PCIe/NVMe 接口的闪存中都可以找到 FTL [1],而不是裸 NAND 闪存和 SmartMediaCards [2]

警告: 如果运行机器上的内核版本旧于用于创建 F2FS 分区的内核版本,则 F2FS 分区上包含的数据可能会变得不可用。例如,如果 F2FS 分区是在 linux 提供的 mainline 内核上创建的,但系统需要降级到 linux-lts 提供的旧版本内核系列,则可能会出现此限制。请参阅 FS#69363

本文或本章节需要扩充。

原因: F2FS 相对于其他文件系统(如 ext4)有哪些优势?是否建议在 LVM 中使用?(在 Talk:F2FS 中讨论)

已知问题

fsck 失败

F2FS 的 fsck 较弱,在突然断电的情况下可能导致数据丢失 [3][4]

如果经常断电,请考虑使用其他 文件系统

长时间运行的 fsck 延迟启动

本文或本章节已过时。

原因: commit 已包含在 f2fs-tools 1.14.0 中。现在此问题的状态如何?(在 Talk:F2FS 中讨论)

如果启动之间内核版本发生了更改,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_attrinode_checksumsb_checksum 选项有助于 fsck.f2fs 检测和修复某些类型的文件系统损坏。有关所有可用选项,请参阅 mkfs.f2fs(8)

压缩

注意: 与其他具有内联压缩的文件系统不同,f2fs 压缩默认情况下不公开额外的可用空间,而是保留相同数量的块,无论是否启用压缩。主要目标是减少写入以延长闪存寿命,并可能 略微提高性能。请参阅内核文档中的 压缩实现F2FS_IOC_RELEASE_COMPRESS_BLOCKS 可用于在每个文件的基础上公开未使用的空间,但这会使文件在此过程中变为不可变。

要使用压缩,请包含 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 31GBexit。现在使用以下命令扩展文件系统以填充新分区

# resize.f2fs /dev/sdxY

其中 /dev/sdxY 是要扩展的目标 F2FS 卷。有关支持的选项,请参阅 resize.f2fs(8)

注意: 如果使用 GPT,分区的 GUID(在 /dev/disk/by-partuuid/ 中可见)可能会更改,但文件系统 UUID(在 /dev/disk/by-uuid/ 中可见)应保持不变。

故障排除

使用某些选项无法重新挂载

正如 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],无论是

  • 添加内核参数 rootflags=atgc 到你的启动引导器配置,
  • 添加内核参数 rw 到你的启动引导器配置,
  • 从 fstab 中移除 atgc 挂载选项。

linux 6.2 起,内核中加入了一项检查,用于在文件系统为只读时禁用 flush_merge,但检查的是重新挂载之前的文件系统状态。正如 FS#77596 中所述,以下两者之一:

  • 添加内核参数 rw 到你的启动引导器配置,
  • 从 fstab 中移除 flush_merge 挂载选项。