Swapfile 交换文件 

A swapfile, when active, is a file-backed swap area. It is supported since kernel 5.0. Use swapon(8) to activate it, until then (respectively again after deactivating it with swapoff(8)) it’s just a normal file (with NODATACOW set), for which the special restrictions for active swapfiles don’t apply.
当活动时,交换文件是一个基于文件的交换区域。自内核 5.0 起支持。使用 swapon(8) 来激活它,在那之前(分别在使用 swapoff(8) 停用后再次激活之前),它只是一个普通文件(设置了 NODATACOW),对于活动交换文件的特殊限制不适用。

There are some limitations of the implementation in BTRFS and Linux swap subsystem:
BTRFS 和 Linux 交换子系统中的实现存在一些限制:

  • filesystem - must be only single device
    文件系统 - 必须只有单个设备

  • filesystem - must have only single data profile
    文件系统 - 必须只有单个数据配置文件

  • subvolume - cannot be snapshotted if it contains any active swapfiles
    子卷 - 如果包含任何活动的交换文件,则无法进行快照

  • swapfile - must be preallocated (i.e. no holes)
    交换文件 - 必须预分配(即没有空洞)

  • swapfile - must be NODATACOW (i.e. also NODATASUM, no compression)
    交换文件 - 必须为 NODATACOW(即也是 NODATASUM,无压缩)

The limitations come namely from the COW-based design and mapping layer of blocks that allows the advanced features like relocation and multi-device filesystems. However, the swap subsystem expects simpler mapping and no background changes of the file block location once they’ve been assigned to swap.
限制主要来自基于 COW 的设计和映射层的块,这使得像重定位和多设备文件系统这样的高级功能成为可能。然而,交换子系统期望更简单的映射,并且一旦文件块被分配给交换,就不会在后台更改文件块位置。

With active swapfiles, the following whole-filesystem operations will skip swapfile extents or may fail:
在活动的交换文件中,以下整个文件系统操作将跳过交换文件范围,或者可能失败:

  • balance - block groups with extents of any active swapfiles are skipped and reported, the rest will be processed normally
    平衡 - 具有任何活动交换文件范围的块组将被跳过并报告,其余部分将被正常处理

  • resize grow - unaffected 调整大小增加 - 不受影响

  • resize shrink - works as long as the extents of any active swapfiles are outside of the shrunk range
    调整大小缩小 - 只要任何活动交换文件的范围在缩小范围之外,就可以正常工作

  • device add - if the new devices do not interfere with any already active swapfiles this operation will work, though no new swapfile can be activated afterwards
    添加设备 - 如果新设备不干扰任何已经激活的交换文件,此操作将正常工作,尽管之后无法激活新的交换文件

  • device delete - if the device has been added as above, it can be also deleted
    设备删除 - 如果设备已添加如上所述,则也可以删除

  • device replace - ditto 设备替换 - 同上

When there are no active swapfiles and a whole-filesystem exclusive operation is running (e.g. balance, device delete, shrink), the swapfiles cannot be temporarily activated. The operation must finish first.
当没有活动的交换文件并且正在运行整个文件系统独占操作(例如平衡、设备删除、收缩)时,交换文件无法被临时激活。操作必须先完成。

To create and activate a swapfile run the following commands:
要创建并激活交换文件,请运行以下命令:

# truncate -s 0 swapfile
# chattr +C swapfile
# fallocate -l 2G swapfile
# chmod 0600 swapfile
# mkswap swapfile
# swapon swapfile

Since version 6.1 it’s possible to create the swapfile in a single command (except the activation):
从版本 6.1 开始,可以使用单个命令创建交换文件(激活除外):

# btrfs filesystem mkswapfile --size 2G swapfile
# swapon swapfile

Please note that the UUID returned by the mkswap utility identifies the swap “filesystem” and because it’s stored in a file, it’s not generally visible and usable as an identifier unlike if it was on a block device.
请注意,mkswap 实用程序返回的 UUID 用于标识交换“文件系统”,因为它存储在文件中,通常不可见且不可用作标识符,不像它在块设备上的情况。

Once activated the file will appear in /proc/swaps:
一旦激活,文件将出现在 /proc/swaps 中:

# cat /proc/swaps
Filename          Type          Size           Used      Priority
/path/swapfile    file          2097152        0         -2

The swapfile can be created as one-time operation or, once properly created, activated on each boot by the swapon -a command (usually started by the service manager). Add the following entry to /etc/fstab, assuming the filesystem that provides the /path has been already mounted at this point. Additional mount options relevant for the swapfile can be set too (like priority, not the BTRFS mount options).
交换文件可以作为一次性操作创建,或者一旦正确创建,可以通过 swapon -a 命令在每次启动时激活(通常由服务管理器启动)。在 /etc/fstab 中添加以下条目,假设提供 /path 的文件系统在此时已经挂载。还可以设置适用于交换文件的其他挂载选项(如优先级,而不是 BTRFS 挂载选项)。

/path/swapfile        none        swap        defaults      0 0

From now on the subvolume with the active swapfile cannot be snapshotted until the swapfile is deactivated again by swapoff. Then the swapfile is a regular file and the subvolume can be snapshotted again, though this would prevent another activation any swapfile that has been snapshotted. New swapfiles (not snapshotted) can be created and activated.
从现在开始,具有活动交换文件的子卷在交换文件再次被 swapoff 停用之前无法进行快照。然后,交换文件是一个常规文件,子卷可以再次进行快照,尽管这将阻止对已经进行快照的任何交换文件的另一个激活。可以创建和激活新的交换文件(未进行快照)。

Otherwise, an inactive swapfile does not affect the containing subvolume. Activation creates a temporary in-memory status and prevents some file operations, but is not stored permanently.
否则,非活动的交换文件不会影响包含的子卷。激活会创建一个临时的内存状态并阻止一些文件操作,但不会永久存储。

Hibernation 休眠

A swapfile can be used for hibernation but it’s not straightforward. Before hibernation a resume offset must be written to file /sys/power/resume_offset or the kernel command line parameter resume_offset must be set.
交换文件可以用于休眠,但并不直接。在休眠之前,必须将恢复偏移写入文件/sys/power/resume_offset,或者必须设置内核命令行参数 resume_offset。

The value is the physical offset on the device. Note that this is not the same value that filefrag prints as physical offset!
该值是设备上的物理偏移量。请注意,这不是 filefrag 打印的物理偏移量!

Btrfs filesystem uses mapping between logical and physical addresses but here the physical can still map to one or more device-specific physical block addresses. It’s the device-specific physical offset that is suitable as resume offset.
Btrfs 文件系统使用逻辑地址和物理地址之间的映射,但这里的物理地址仍然可以映射到一个或多个特定于设备的物理块地址。适合作为恢复偏移量的是特定于设备的物理偏移量。

Since version 6.1 there’s a command btrfs inspect-internal map-swapfile that will print the device physical offset and the adjusted value for /sys/power/resume_offset. Note that the value is divided by page size, i.e. it’s not the offset itself.
从版本 6.1 开始,有一个名为 btrfs inspect-internal map-swapfile 的命令,它将打印设备的物理偏移量和调整后的值为 /sys/power/resume_offset 。请注意,该值被页面大小除,即它不是偏移量本身。

# btrfs filesystem mkswapfile swapfile
# btrfs inspect-internal map-swapfile swapfile
Physical start: 811511726080
Resume offset:     198122980

For scripting and convenience the option -r will print just the offset:
为了脚本编写和方便起见,选项 -r 将仅打印偏移量:

# btrfs inspect-internal map-swapfile -r swapfile
198122980

The command map-swapfile also verifies all the requirements, i.e. no holes, single device, etc.
命令 map-swapfile 还验证所有要求,即没有空洞,单个设备等。

Troubleshooting 故障排除 

If the swapfile activation fails please verify that you followed all the steps above or check the system log (e.g. dmesg or journalctl) for more information.
如果交换文件激活失败,请验证您是否按照上述所有步骤操作,或者检查系统日志(例如 dmesg 或 journalctl)以获取更多信息。

Notably, the swapon utility exits with a message that does not say what failed:
值得注意的是,swapon 实用程序退出时会显示一条未说明失败原因的消息:

# swapon /path/swapfile
swapon: /path/swapfile: swapon failed: Invalid argument

The specific reason is likely to be printed to the system log by the btrfs module:
具体原因可能会由 btrfs 模块打印到系统日志中:

# journalctl -t kernel | grep swapfile
kernel: BTRFS warning (device sda): swapfile must have single data profile