SGI XFS 文件系统¶
XFS 是一种高性能日志文件系统,起源于 SGI IRIX 平台。它是完全多线程的,可以支持大型文件和大型文件系统、扩展属性、可变块大小,是基于范围的,并且广泛使用 B 树(目录、范围、可用空间)来帮助提高性能和可伸缩性。
有关更多详细信息,请参阅 https://xfs.wiki.kernel.org/ 上的文档。此实现与 IRIX 版本的 XFS 在磁盘上兼容。
挂载选项¶
挂载 XFS 文件系统时,接受以下选项。
- allocsize=size
在执行延迟分配写入时,设置缓冲 I/O 文件末尾预分配大小(默认大小为 64KiB)。此选项的有效值是从页面大小(通常为 4KiB)到 1GiB(包括 1GiB),以 2 的幂递增。
默认行为是动态文件末尾预分配大小,它使用一组启发式方法来优化预分配大小,基于文件中的当前分配模式和对文件的访问模式。指定固定
allocsize
值会关闭动态行为。- attr2 或 noattr2
这些选项启用/禁用对内联扩展属性在磁盘上的存储方式进行“机会性”改进。首次使用新格式时(当选择
attr2
时,无论是设置还是删除扩展属性),磁盘上的超级块特征位字段将更新,以反映正在使用的这种格式。默认行为由磁盘上的特征位确定,该特征位指示
attr2
行为处于活动状态。如果设置了任一挂载选项,则它将成为文件系统使用的新默认值。启用 CRC 的文件系统始终使用
attr2
格式,因此如果设置了noattr2
挂载选项,则会拒绝该选项。- discard 或 nodiscard (默认)
启用/禁用发出命令,让块设备回收文件系统释放的空间。这对于 SSD 设备、精简配置的 LUN 和虚拟机映像很有用,但可能会对性能产生影响。
注意:目前建议您使用
fstrim
应用程序来discard
未使用的块,而不是discard
挂载选项,因为此选项的性能影响非常严重。- grpid/bsdgroups 或 nogrpid/sysvgroups (默认)
这些选项定义了新创建的文件获取的组 ID。当设置了
grpid
时,它会采用创建文件所在的目录的组 ID;否则,它会采用当前进程的fsgid
,除非该目录设置了setgid
位,在这种情况下,它会采用父目录的gid
,并且如果它本身是一个目录,还会设置setgid
位。- filestreams
使数据分配器在整个文件系统中使用文件流分配模式,而不仅仅是在配置为使用它的目录上。
- ikeep 或 noikeep (默认)
当指定
ikeep
时,XFS 不会删除空的 inode 集群,而是将其保留在磁盘上。当指定noikeep
时,空的 inode 集群会返回到可用空间池。- inode32 或 inode64 (默认)
当指定
inode32
时,它表示 XFS 将 inode 创建限制在不会导致 inode 编号具有超过 32 位有效性的位置。当指定
inode64
时,它表示 XFS 允许在文件系统中的任何位置创建 inode,包括那些会导致 inode 编号占用超过 32 位有效性的位置。
inode32
提供用于与旧系统和应用程序向后兼容,因为 64 位 inode 编号可能会导致某些无法处理大型 inode 编号的应用程序出现问题。如果正在使用的应用程序无法处理大于 32 位的 inode 编号,则应指定inode32
选项。- largeio 或 nolargeio (默认)
如果指定了
nolargeio
,则 stat(2) 在st_blksize
中报告的最佳 I/O 将尽可能小,以允许用户应用程序避免低效的读取/修改/写入 I/O。这通常是机器的页面大小,因为这是页面缓存的粒度。如果指定了
largeio
,则使用指定的swidth
创建的文件系统将在st_blksize
中返回swidth
值(以字节为单位)。如果文件系统未指定swidth
,但指定了allocsize
,则将返回allocsize
(以字节为单位)。否则,行为与指定nolargeio
时相同。- logbufs=value
设置内存中日志缓冲区数量。有效数字范围为 2-8(含)。
默认值为 8 个缓冲区。
如果在小型系统上 8 个日志缓冲区的内存成本太高,则可以在元数据密集型工作负载上以一定的性能损失为代价来减少它。下面的
logbsize
选项控制每个缓冲区的大小,因此也与这种情况相关。- lifetime (默认) 或 nolifetime
启用基于用户提供的写入生存期提示的数据放置。当统计上有利于降低垃圾回收成本时,这将打开类似生存期数据的协同分配。
这些选项仅适用于分区 rt 文件系统。
- logbsize=value
设置每个内存中日志缓冲区的大小。大小可以以字节为单位指定,也可以以千字节为单位指定,带有“k”后缀。版本 1 和版本 2 日志的有效大小为 16384 (16k) 和 32768 (32k)。版本 2 日志的有效大小还包括 65536 (64k)、131072 (128k) 和 262144 (256k)。logbsize 必须是 mkfs(8) 时配置的日志条带单元的整数倍。
版本 1 日志的默认值为 32768,而版本 2 日志的默认值为 MAX(32768, log_sunit)。
- logdev=device 和 rtdev=device
使用外部日志(元数据日志)和/或实时设备。XFS 文件系统最多有三个部分:数据部分、日志部分和实时部分。实时部分是可选的,日志部分可以与数据部分分开,也可以包含在其中。
- max_atomic_write=value
设置原子写入的最大大小。大小可以以字节为单位指定,以千字节为单位指定,带有“k”后缀,以兆字节为单位指定,带有“m”后缀,或者以千兆字节为单位指定,带有“g”后缀。大小不能大于最大写入大小,不能大于任何分配组的大小,也不能大于日志可以原子完成的重映射操作的大小。
默认值是将最大 I/O 完成大小设置为允许每个 CPU 一次处理一个。
- max_open_zones=value
指定要为分区 rt 设备上的写入保持打开的最大区域数。许多打开的区域有助于文件数据分离,但可能会影响 HDD 的性能。
如果未指定
max_open_zones
,则该值由分区 rt 设备的功能和大小确定。- noalign
数据分配将不对齐到条带单元边界。这仅与由 mkfs(8) 使用非零数据对齐参数(
sunit
、swidth
)创建的文件系统相关。- norecovery
文件系统将在不运行日志恢复的情况下挂载。如果文件系统未干净地卸载,则在
norecovery
模式下挂载时,它很可能不一致。由于这个原因,可能无法访问某些文件或目录。以norecovery
挂载的文件系统必须以只读方式挂载,否则挂载将失败。- nouuid
不要使用文件系统的
uuid
检查双重挂载的文件系统。这对于挂载 LVM 快照卷很有用,并且通常与norecovery
结合使用,用于挂载只读快照。- noquota
强制关闭文件系统中的所有配额记帐和强制执行。
- uquota/usrquota/uqnoenforce/quota
用户磁盘配额记帐已启用,并且(可选)强制执行限制。有关更多详细信息,请参阅 xfs_quota(8)。
- gquota/grpquota/gqnoenforce
组磁盘配额记帐已启用,并且(可选)强制执行限制。有关更多详细信息,请参阅 xfs_quota(8)。
- pquota/prjquota/pqnoenforce
项目磁盘配额记帐已启用,并且(可选)强制执行限制。有关更多详细信息,请参阅 xfs_quota(8)。
- sunit=value 和 swidth=value
用于指定 RAID 设备或条带卷的条带单元和宽度。“value”必须以 512 字节的块单元指定。这些选项仅与使用非零数据对齐参数创建的文件系统相关。
指定的
sunit
和swidth
参数必须与现有的文件系统对齐特性兼容。一般来说,这意味着对sunit
的唯一有效更改是以 2 的幂倍数增加它。有效的swidth
值是有效sunit
值的任何整数倍。通常,只有在底层 RAID 设备的几何形状被修改后,例如向 RAID5 lun 添加新磁盘并重塑它时,这些挂载选项才是必要的。
- swalloc
当扩展当前文件末尾并且文件大小大于条带宽度大小时,数据分配将四舍五入到条带宽度边界。
- wsync
指定后,所有文件系统命名空间操作都将同步执行。这确保了当命名空间操作(创建、取消链接等)完成时,对命名空间的更改已在稳定存储上。这在 HA 设置中很有用,其中故障转移不得导致客户端在故障转移期间或之后看到不一致的命名空间表示。
弃用 V4 格式¶
V4 文件系统格式缺少 V5 格式支持的某些功能,例如元数据校验和、加强的元数据验证以及存储超过 2038 年的时间戳的能力。因此,V4 格式已被弃用。所有用户都应该通过备份他们的文件、重新格式化和从备份恢复来升级。
管理员和用户可以通过针对文件系统挂载点运行 xfs_info 并检查是否包含包含“crc=”的字符串来检测 V4 文件系统。如果没有找到这样的字符串,请将 xfsprogs 升级到最新版本并重试。
弃用将分两部分进行。现在可以通过 Kconfig 选项在内核构建时禁用对挂载 V4 文件系统的支持。该选项将默认为 yes,直到 2025 年 9 月,届时它将更改为默认为 no。在 2030 年 9 月,将从代码库中完全删除支持。
注意:分销商可能会选择早于上面列出的日期撤回 V4 格式支持。
已弃用的挂载选项¶
名称 |
删除计划 |
---|---|
使用 V4 文件系统挂载 |
2030 年 9 月 |
挂载 ascii-ci 文件系统 |
2030 年 9 月 |
ikeep/noikeep |
2025 年 9 月 |
attr2/noattr2 |
2025 年 9 月 |
已删除的挂载选项¶
名称 |
已删除 |
---|---|
delaylog/nodelaylog |
v4.0 |
ihashsize |
v4.0 |
irixsgid |
v4.0 |
osyncisdsync/osyncisosync |
v4.0 |
barrier |
v4.19 |
nobarrier |
v4.19 |
sysctls¶
以下 sysctl 可用于 XFS 文件系统
- fs.xfs.stats_clear(最小值:0 默认值:0 最大值:1)
将其设置为“1”会清除 /proc/fs/xfs/stat 中累积的 XFS 统计信息。然后立即重置为“0”。
- fs.xfs.xfssyncd_centisecs(最小值:100 默认值:3000 最大值:720000)
文件系统将元数据刷新到磁盘并运行内部缓存清理例程的间隔。
- fs.xfs.filestream_centisecs(最小值:1 默认值:3000 最大值:360000)
文件系统老化文件流缓存引用并将超时的 AG 返回到可用流池的间隔。
- fs.xfs.speculative_prealloc_lifetime
(单位:秒 最小值:1 默认值:300 最大值:86400)在后台扫描具有未使用投机预分配的 inode 的运行间隔。扫描会从干净的 inode 中删除未使用的预分配,并将未使用的空间释放回可用池。
- fs.xfs.speculative_cow_prealloc_lifetime
这是 speculative_prealloc_lifetime 的别名。
- fs.xfs.error_level(最小值:0 默认值:3 最大值:11)
当发生内部错误时,用于错误报告的卷旋钮。例如,这将为文件系统关闭生成详细的消息和回溯。当前阈值是
XFS_ERRLEVEL_OFF:0 XFS_ERRLEVEL_LOW:1 XFS_ERRLEVEL_HIGH:5
- fs.xfs.panic_mask(最小值:0 默认值:0 最大值:511)
导致某些错误情况调用 BUG()。该值是一个位掩码;将表示应导致崩溃的错误的标签 OR 在一起
XFS_NO_PTAG 0 XFS_PTAG_IFLUSH 0x00000001 XFS_PTAG_LOGRES 0x00000002 XFS_PTAG_AILDELETE 0x00000004 XFS_PTAG_ERROR_REPORT 0x00000008 XFS_PTAG_SHUTDOWN_CORRUPT 0x00000010 XFS_PTAG_SHUTDOWN_IOERROR 0x00000020 XFS_PTAG_SHUTDOWN_LOGERROR 0x00000040 XFS_PTAG_FSBLOCK_ZERO 0x00000080 XFS_PTAG_VERIFIER_ERROR 0x00000100
此选项仅用于调试。
- fs.xfs.irix_symlink_mode(最小值:0 默认值:0 最大值:1)
控制是否使用模式 0777(默认)创建符号链接,或者其模式是否受 umask(irix 模式)影响。
- fs.xfs.irix_sgid_inherit(最小值:0 默认值:0 最大值:1)
控制在 SGID 目录中创建的文件。如果新文件的组 ID 与父目录的有效组 ID 或补充组 ID 之一不匹配,则如果设置了 irix_sgid_inherit 兼容性 sysctl,则会清除 ISGID 位。
- fs.xfs.inherit_sync(最小值:0 默认值:1 最大值:1)
将其设置为“1”将导致 xfs_io(8) chattr 命令在目录上设置的“sync”标志被该目录中的文件继承。
- fs.xfs.inherit_nodump(最小值:0 默认值:1 最大值:1)
将其设置为“1”将导致 xfs_io(8) chattr 命令在目录上设置的“nodump”标志被该目录中的文件继承。
- fs.xfs.inherit_noatime(最小值:0 默认值:1 最大值:1)
将其设置为“1”将导致 xfs_io(8) chattr 命令在目录上设置的“noatime”标志被该目录中的文件继承。
- fs.xfs.inherit_nosymlinks(最小值:0 默认值:1 最大值:1)
将其设置为“1”将导致 xfs_io(8) chattr 命令在目录上设置的“nosymlinks”标志被该目录中的文件继承。
- fs.xfs.inherit_nodefrag(最小值:0 默认值:1 最大值:1)
将其设置为“1”将导致 xfs_io(8) chattr 命令在目录上设置的“nodefrag”标志被该目录中的文件继承。
- fs.xfs.rotorstep(最小值:1 默认值:1 最大值:256)
在“inode32”分配模式下,此选项确定分配器在移动到下一个分配组之前尝试在同一分配组中分配多少个文件。目的是控制分配器在为新文件分配范围时在分配组之间移动的速率。
已弃用的 Sysctl¶
名称 |
删除计划 |
---|---|
fs.xfs.irix_sgid_inherit |
2025 年 9 月 |
fs.xfs.irix_symlink_mode |
2025 年 9 月 |
fs.xfs.speculative_cow_prealloc_lifetime |
2025 年 9 月 |
已删除的 Sysctl¶
名称 |
已删除 |
---|---|
fs.xfs.xfsbufd_centisec |
v4.0 |
fs.xfs.age_buffer_centisecs |
v4.0 |
错误处理¶
XFS 可以根据在其操作期间发现的错误类型采取不同的操作。该实现将以下概念引入到错误处理程序
- -故障速度
定义当在文件系统操作期间发现特定错误时,XFS 应以多快的速度向上层传播错误。它可以立即传播,可以在定义的重试次数后传播,可以在设定的时间段后传播,或者只是永远重试。
- -错误类
指定错误配置将应用到的子系统,例如元数据 IO 或内存分配。不同的子系统将具有不同的错误处理程序,可以为其配置行为。
- -错误处理程序
定义特定错误的行为。
错误期间的文件系统行为可以通过 sysfs
文件设置。每个错误处理程序独立工作 - 特定类的错误处理程序满足的第一个条件将导致错误被传播,而不是重置和重试。
当错误被传播时,文件系统采取的操作取决于上下文 - 它可能会在发生不可恢复的错误时导致关闭,它可能会报告回用户空间,或者它甚至可能会被忽略,因为我们无法对错误做任何有用的事情,或者我们可以将其报告给任何人(例如,在卸载期间)。
配置文件被组织成以下层次结构,用于每个挂载的文件系统
/sys/fs/xfs/<dev>/error/<class>/<error>/
- 其中
- <dev>
挂载的文件系统的短设备名称。这与 XFS 内核错误消息中显示的设备名称相同,如“XFS(<dev>): ...”
- <class>
错误配置所属的子系统。截至 4.9,定义的类是
“metadata”:应用元数据缓冲区写入 IO
- <error>
单个错误处理程序配置。
每个文件系统都有在其顶级目录中定义的“全局”错误配置选项
/sys/fs/xfs/<dev>/error/
- fail_at_unmount(最小值:0 默认值:1 最大值:1)
定义卸载时的文件系统错误行为。
如果设置为 1 的值,则 XFS 将覆盖卸载期间的所有其他错误配置,并将其替换为“立即失败”特性。即没有重试,没有重试超时。这将始终允许卸载在存在持久性错误时成功。
如果设置为 0,则配置的重试行为将继续,直到所有重试和/或超时都已耗尽。这将延迟卸载完成,当存在持久性错误时,并且它可能会阻止文件系统在“永远重试”处理程序配置的情况下完全卸载。
注意:不能保证在卸载正在进行时可以设置 fail_at_unmount。在“永远重试”错误处理程序配置导致卸载挂起之前,
sysfs
条目可能会被卸载的文件系统删除,因此必须在卸载开始之前正确配置文件系统以防止卸载挂起。
每个文件系统都有特定的错误类处理程序,用于定义特定错误的错误传播行为。还定义了一个“默认”错误处理程序,用于定义所有未定义特定处理程序的错误的行为。如果为单个错误配置了多个重试约束,则第一个过期的重试配置将导致错误被传播。处理程序配置位于目录中
/sys/fs/xfs/<dev>/error/<class>/<error>/
- max_retries(最小值:-1 默认值:Varies 最大值:INTMAX)
定义在文件系统传播错误之前允许重试特定错误的次数。给定错误上下文(例如,特定元数据缓冲区)的重试计数会在每次成功完成操作时重置。
将值设置为“-1”将导致 XFS 永远重试此特定错误。
将值设置为“0”将导致 XFS 在报告特定错误时立即失败。
将值设置为“N”(其中 0 < N < Max)将使 XFS 重试操作“N”次,然后再传播错误。
- retry_timeout_seconds(最小值:-1 默认值:Varies 最大值:1 天)
定义当发现特定错误时,文件系统允许重试其操作的时间量(以秒为单位)。
将值设置为“-1”将允许 XFS 永远重试此特定错误。
将值设置为“0”将导致 XFS 在报告特定错误时立即失败。
将值设置为“N”(其中 0 < N < Max)将允许 XFS 重试操作最多“N”秒,然后再传播错误。
注意:特定错误处理程序的默认行为取决于类和错误上下文。 例如,“metadata/ENODEV”的默认值是“0”而不是“-1”,因此此错误处理程序默认为“立即失败”的行为。 这样做是因为 ENODEV 是一个致命的、不可恢复的错误,无论元数据 IO 重试多少次都是如此。
工作队列并发¶
XFS 使用内核工作队列来并行化元数据更新过程。 这使其能够利用可以同时处理多个 IO 操作的存储硬件。 此接口暴露了 XFS 的内部实现细节,因此明确不属于内核可能提供给用户的任何用户空间 API/ABI 保证。 这些是 XFS 用于并发的通用工作队列实现的未文档化的特性,在此提供它们仅用于诊断和调整目的,并且可能随时更改。
文件系统工作队列的控制旋钮按手头的任务和数据设备的简称进行组织。 它们都可以在以下位置找到:
/sys/bus/workqueue/devices/${task}!${device}
任务 |
描述 |
---|---|
xfs_iwalk-$pid |
整个文件系统的 Inode 扫描。 目前仅限于挂载时 quotacheck。 |
xfs-gc |
对磁盘空间的后台垃圾回收,这些磁盘空间已被推测性地分配到 EOF 之外或用于暂存写入时复制操作。 |
例如,/dev/nvme0n1 的 quotacheck 工作队列的控制旋钮可以在 /sys/bus/workqueue/devices/xfs_iwalk-1111!nvme0n1/ 中找到。
XFS 工作队列的有趣控制旋钮如下:
旋钮 |
描述 |
---|---|
max_active |
可以启动以运行工作的最大后台线程数。 |
cpumask |
允许线程在其上运行的 CPU。 |
nice |
调度线程的相对优先级。 这些是可以应用于用户空间进程的相同的 nice 级别。 |
分区文件系统¶
对于分区文件系统,以下属性在以下位置公开:
/sys/fs/xfs/<dev>/zoned/
- max_open_zones(最小值:1 默认值:变化 最大值:UINTMAX)
此只读属性公开可用于数据放置的最大开放分区数。 该值在挂载时确定,并且受到后备分区设备的容量、文件系统大小和 max_open_zones 挂载选项的限制。
- zonegc_low_space(最小值:0 默认值:0 最大值:100)
定义 GC 应保留多少未用空间百分比以供写入。 较高的值将回收更多被未使用块占用的空间,从而创建一个更大的缓冲区来抵抗写入突发,但会增加写入放大。 无论此值如何,垃圾回收将始终旨在释放最少数量的块,以保持 max_open_zones 处于打开状态以用于数据放置目的。