如何使用 btrfs 在 SSD 磁盘上创建交换文件

如何使用 btrfs 在 SSD 磁盘上创建交换文件

我有带 btrfs 的 SSD,我尝试创建一个交换文件,如下:

dd if=/dev/zero of=swapfile01  bs=1M count=10240
mkswap swapfile01
chmod 600 swapfile01
swapon swapfile01

在 dmesg 中我看到

[238434.731654] swapon: swapfile has holes

我知道磁盘碎片可能会造成一些漏洞,但这是 SSD 磁盘,所以这可能没什么关系?有没有办法忽略这些漏洞?或者我该如何解决这个问题?

题外话 - 我为什么想要这个(为了避免评论中不相关的问题):我有一个加密磁盘,调整大小很麻烦,所以我决定创建一个交换文件而不是调整交换分区的大小(我添加了 14GB 的 RAM,从 4GB 到 16GB,现在无法休眠)。

答案1

2019 年情况

Btrfs 和 Linux 内核的开发使我最初的答案过时的。 请参见另一个答案


2016 年的原始答案

btrfs 常见问题解答

btrfs 支持交换文件吗?目前不支持。仅仅将文件设为 NOCOW 是没有用的,交换文件支持依赖于 btrfs 故意不实现的一个功能,因为可能会损坏。(...) 一种解决方法是通过循环设备挂载交换文件,尽管性能较差。

因此,目前还没有在 btrfs 分区上创建交换文件的好方法。

答案2

正如刚才提到的,自 Linux 5.0 起现在可以在 BTRFS 上创建交换文件。但它们应该是非压缩的和 NoCOW。以下是实际创建此类文件的方法:

  1. 创建一个空文件:touch /swap
  2. 用于chattr设置NoCOW其属性:chattr +C /swap
  3. 验证C属性是否出现:lsattr /swap
  4. 填写:dd if=/dev/zero of=/swap bs=1M count=1024 # 代表 1 GB
  5. mkswap /swap && chmod 600 /swap && swapon /swap

或者,您可以创建一个目录,设置chattr +C为该目录,然后在其下创建一个交换文件。

请注意,您不能chattr +C对已经存在的非空文件执行任何操作。据记录,这是未定义的行为(实际上它只是不会更改属性)。因此,您应该创建一个空文件,然后chattr,或者创建一个目录,chattr然后在其中创建一个文件(在这种情况下,在chattr目录之后创建的所有文件都将具有 nocow 属性)。

警告:如上所述,这需要内核版本 5.0 或更高版本。例如,Raspberry Pi 使用 4.19.* 内核,因此您无法在其上使用此技术。

答案3

内核版本 5.0 已添加交换文件支持,如提交中所示https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ed46ff3d423780fa5173b38a844bf0fdb210a2a7 要在 btrfs 上激活交换文件,文件必须在一个设备上完全分配为 NOCOW 且不进行压缩。

答案4

关于 btrfs 上的交换,有用的知识是:如果您正在进行备份快照/子卷,则应该创建一个不进行快照的专用子卷。

swapon在快照子卷上,你的交换文件将再次变为 COW,并且重启后你将无法再执行此操作:https://www.spinics.net/lists/linux-btrfs/msg96790.html

我使我的最后一个子卷可写,例如sudo btrfs property set -ts /.sxbackup/sx-20210211-092159-utc/ ro false,删除swap,并且能够swapon再次在主卷上 - 但接下来我将创建一个专用的子卷。

相关内容