我有带 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 支持交换文件吗?目前不支持。仅仅将文件设为 NOCOW 是没有用的,交换文件支持依赖于 btrfs 故意不实现的一个功能,因为可能会损坏。(...) 一种解决方法是通过循环设备挂载交换文件,尽管性能较差。
因此,目前还没有在 btrfs 分区上创建交换文件的好方法。
答案2
正如刚才提到的,自 Linux 5.0 起现在可以在 BTRFS 上创建交换文件。但它们应该是非压缩的和 NoCOW。以下是实际创建此类文件的方法:
- 创建一个空文件:
touch /swap
- 用于
chattr
设置NoCOW
其属性:chattr +C /swap
- 验证
C
属性是否出现:lsattr /swap
- 填写:
dd if=/dev/zero of=/swap bs=1M count=1024
# 代表 1 GB 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
再次在主卷上 - 但接下来我将创建一个专用的子卷。