16

I have SSD with btrfs, I tried creating a swapfile like:

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

In dmesg I see

[238434.731654] swapon: swapfile has holes

I understand that there are probably some holes caused by disk fragmentation, but this is SSD disk so it probably shouldn't matter? Is there a way to ignore the holes? Or how can I fix this?

Off topic - why I want this (to avoid irrelevant questions in comments): I have encrypted disk which is pain in the **** to resize, so I just decided to create a swapfile instead of resizing the swap partition (I added 14GB of ram, from 4gb to 16gb and can't hibernate now).

Kamil Maciorowski
  • 69,815
  • 22
  • 136
  • 202
Petr
  • 2,203
  • 6
  • 26
  • 39
  • By "holes" it means that the file hasn't actually allocated all its space, making it useless as a swapfile. You can use [fallocate](http://manpages.courier-mta.org/htmlman1/fallocate.1.html) to plug the holes. – David Schwartz Apr 19 '16 at 07:56
  • Regarding hibernation, if you use systemd, you need a release that incorporates [PR #12760](https://github.com/systemd/systemd/pull/12760). – Mihai Capotă Aug 15 '19 at 22:18
  • @MihaiCapotă I avoid systemd like black plague, it's Gentoo with open-rc – Petr Oct 25 '19 at 09:23

6 Answers6

20

As mentioned above, since Linux 5.0 it is now possible to create swap files on BTRFS. But they should be non-compressed and NoCOW. Here is how do you actually create such a file:

  1. Create an empty file: touch /swap
  2. Use chattr to set NoCOW attribute to it: chattr +C /swap
  3. Verify that C attribute appeared: lsattr /swap
  4. Fill it: dd if=/dev/zero of=/swap bs=1M count=1024 # for 1 gigabyte
  5. mkswap /swap && chmod 600 /swap && swapon /swap

Alternatively, you can create a directory, set chattr +C to that directory and then create a swapfile under it.

Note that you cannot do chattr +C to already existing non-empty file. It is documented to be undefined behaviour (in fact it just doesn't change attributes). So you should either create an empty file and then chattr, or create a directory with chattr and then create a file in it (in such case all files created after chattring the directory will have the nocow attribute).

Caveat: as mentioned, this requires kernel version 5.0 or higher. Raspberry Pi for example uses 4.19.* kernels so you won't be able to use this technique on it.

MarSoft
  • 381
  • 3
  • 5
9

Status in 2019

The development of Btrfs and Linux kernel rendered my original answer obsolete. Please see this other answer.


Original answer from 2016

From btrfs FAQ:

Does btrfs support swap files? Currently no. Just making a file NOCOW does not help, swap file support relies on one function that btrfs intentionally does not implement due to potential corruptions. (...) A workaround, albeit with poor performance, is to mount a swap file via a loop device.

So there is no good way to create swapfile on btrfs partition yet.

Kamil Maciorowski
  • 69,815
  • 22
  • 136
  • 202
  • 2
    Well, this is a first time after years of using btrfs that I found some really important feature that is missing, and probably first disadvantage compared with other FS :( – Petr Apr 19 '16 at 14:08
  • Is there any benchmark data or testing methods to support the poor performance the Btrfs devs claim? – Hydranix Dec 19 '16 at 03:25
  • @Hydranix I know none. Consider asking a separate question. – Kamil Maciorowski Dec 19 '16 at 06:05
  • @Petr Yepp, I have ECC memory, but if swap is not on a btrfs partition, there is no guarantee data stored there keeps its integrity. Another point to zfs. :S – inf3rno Jan 24 '18 at 03:21
  • 1
    @Petr Things have changed. I won't mind *at all* if you accept another answer now. – Kamil Maciorowski Mar 10 '19 at 09:26
8

Swap file support has been added to kernel version 5.0 as can be seen at commit https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ed46ff3d423780fa5173b38a844bf0fdb210a2a7 To activate swap file on btrfs, file must be fully allocated as NOCOW with no compression on one device.

arvati
  • 81
  • 1
  • 5
5

In Linux 5.0 or later:

file='/swapfile'
# create file
touch "$file"
# No Copy-on-Write
chattr +C "$file"
# Allocate 10 GB  (much faster than dd)
fallocate -l 10G "$file"
# Set permissions to make mkswap happy
chmod 600 "$file"
# Set swap file signature
mkswap "$file"
# change owner if not already root to make swapon happy
sudo chown root "$file"
# Activate
sudo swapon "$file"
Kamil Maciorowski
  • 69,815
  • 22
  • 136
  • 202
Ole Tange
  • 4,529
  • 2
  • 34
  • 51
3

Useful thing to know about swap on btrfs is: if you are doing backup snapshots / subvolumes, you should create a dedicated subvolume that you're not snapshotting.

On snapshot subvolume, your swapfile will become COW again, and you won't be able to swapon after reboot: https://www.spinics.net/lists/linux-btrfs/msg96790.html

I made my last subvolume writeable, like sudo btrfs property set -ts /.sxbackup/sx-20210211-092159-utc/ ro false, deleted swap, and was able to swapon on main volume again - but I will make a dedicated subvolume next.

lkraav
  • 1,239
  • 13
  • 18
1

Here's how to setup swap via loopback on btrfs:

# dd if=/dev/zero of=/swapfile bs=1M count=1k
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 1.23138 s, 872 MB/s

# losetup --find --show /swapfile
/dev/loop0

# mkswap /dev/loop0
Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes)
no label, UUID=04b048e2-47ab-4ab0-a79e-7e1c481a10c9

# swapon /dev/loop0

Is this ideal? No. Avoid using it in production. But it works as a last resort kind of thing.

w00t
  • 819
  • 6
  • 12