You are not logged in.

#1 2019-06-08 10:52:52

woodape
Member
Registered: 2015-03-25
Posts: 159

[SOLVED] Swapfile on BTRFS filesystem with compression enabled

Hi All,

I've recently set up a system with two SSDs, with LUKS partions formatted with Btrfs RAID0, in which I have top-level subvolumes for @root, @home, @backups, and @swap. As might be obvious, my plan was to mount @root to /, @home to /home, @backups to /backups, and @swap to /swap. My /etc/fstab is below:

# /dev/mapper/cryptroot1
UUID=fd0d3a2a-9be9-440f-a097-ee457402b793	/         	btrfs     	rw,relatime,compress=zstd,ssd,space_cache,subvolid=256,subvol=/@root,subvol=@root	0 0

# /dev/mapper/cryptroot1
UUID=fd0d3a2a-9be9-440f-a097-ee457402b793	/swap     	btrfs     	rw,relatime,compress=zstd,ssd,space_cache,subvolid=261,subvol=/@swap,subvol=@swap	0 0

# /dev/sda1
UUID=924a6567-395e-4bad-8003-98b44e5e6207	/boot     	btrfs     	rw,relatime,ssd,space_cache,subvolid=5,subvol=/	0 0

# /dev/mapper/cryptroot1
UUID=fd0d3a2a-9be9-440f-a097-ee457402b793	/home     	btrfs     	rw,relatime,compress=zstd,ssd,space_cache,subvolid=262,subvol=/@home,subvol=@home	0 0

# /dev/mapper/cryptroot1
UUID=fd0d3a2a-9be9-440f-a097-ee457402b793	/backups  	btrfs     	rw,relatime,compress=zstd,ssd,space_cache,subvolid=263,subvol=/@backups,subvol=@backups	0 0

# /dev/nvme0n1p1 LABEL=SYSTEM
UUID=B212-D043      	/efi      	vfat      	rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro	0 2

# /dev/mapper/cryptroot1
UUID=fd0d3a2a-9be9-440f-a097-ee457402b793	/btrfs_pool	btrfs     	rw,relatime,ssd,space_cache,subvolid=5,subvol=/	0 1

As I've found out via the Btrfs Wiki, and as mentioned in Arch's own Wiki, one cannot mount different subvolumes of the same file system with different Btrfs-specific mount options, namely nodatacow and compress=zstd.

Since Btrfs swapfiles cannot be on a filesystem with CoW or compress, the Arch Wiki's suggestion is to use chattr +C to turn of CoW and btrfs property set /swapfile compression none to turn off compression on the individual file to be used as the swapfile before allocating blocks to it (in the Wiki example, "/swapfile").

I'm having no luck with this, and I'm wondering if it's because even though I've set the nodatacow flag with chattr, and the no conmpression flag with the btrfs command:

-> % sudo lsattr
---------------C---- ./swapfile

the @swap subvolume is still mounted with the compress option turned on. I've followed the steps exactly, with no errors showing, right up until I try to use swapon at which point I get:

-> % sudo swapon swapfile
swapon: /swap/swapfile: swapon failed: Invalid argument

Contrary to what's in the Wiki, are swapfiles not supported on Btrfs filesystems mounted with a compression flag, even if CoW and compression are turned off for the file individually? Has anyone had any success with a similar setup?

Last edited by woodape (2019-06-09 05:41:24)

Offline

#2 2019-06-08 12:26:48

Ropid
Member
Registered: 2015-03-09
Posts: 1,069

Re: [SOLVED] Swapfile on BTRFS filesystem with compression enabled

Did you run "mkswap filename" to format the swap file?

You don't need to worry about compression because "nodatacow" is already forcing compression off as a side-effect. The reason is that compression makes parts of a file randomly change size, and that's not possible to manage on the real disk without CoW. You also don't need to do "btrfs property set ...", just that "chattr +C" you used is already enough.

Offline

#3 2019-06-08 14:21:26

woodape
Member
Registered: 2015-03-25
Posts: 159

Re: [SOLVED] Swapfile on BTRFS filesystem with compression enabled

Thanks for the reply Ropid, yes I did run mkswap on the file. I have just put all the commands from the wiki into the following bash script called make_a_swap_file:

#!/bin/bash
truncate -s 0 /swapfile
chattr +C /swapfile
btrfs property set /swapfile compression none
fallocate -l 512M /swapfile
chmod 600 /swapfile
mkswap /swapfile
lsattr /swapfile
swapon /swapfile

and as root I've run ./make_a_swap_file &> log, and here are the contents of log

Setting up swapspace version 1, size = 512 MiB (536866816 bytes)
no label, UUID=a515b3a2-c99c-4b95-bc16-98df1d7b9ce3
---------------C---- /swapfile
swapon: /swapfile: swapon failed: Invalid argument

Which indicates the file was created, has the nodatacow attribute, and successfully formatted as a swap file. But the swapon command fails with "invalid argument", which Btrfs users before kernel 5.0 have observed as meaning the filesystem isn't supported. I'm running the lastest kernel, 5.1.7-arch1-ARCH.

There's no difference if I exclude the btrfs ... command. Have you tried making a swapfile on a btrfs filesystem mounted with compression and CoW turned on? Does it work for you?

Offline

#4 2019-06-08 19:42:24

Ropid
Member
Registered: 2015-03-09
Posts: 1,069

Re: [SOLVED] Swapfile on BTRFS filesystem with compression enabled

In your script, you are working inside the "/" subvolume, not inside the "/swap" subvolume. Can you try changing things around so that the lines in the script all work on a file named "/swap/swapfile" instead of the current "/swapfile", and then see what happens?

Offline

#5 2019-06-08 20:50:08

latalante1
Member
Registered: 2018-08-30
Posts: 110

Re: [SOLVED] Swapfile on BTRFS filesystem with compression enabled

woodape wrote:

Contrary to what's in the Wiki, are swapfiles not supported on Btrfs filesystems mounted with a compression flag, even if CoW and compression are turned off for the file individually? Has anyone had any success with a similar setup?

https://btrfs.wiki.kernel.org/index.php/FAQ#Does_btrfs_support_swap_files.3F wrote:

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.

Offline

#6 2019-06-09 04:39:15

woodape
Member
Registered: 2015-03-25
Posts: 159

Re: [SOLVED] Swapfile on BTRFS filesystem with compression enabled

Ropid, just did the change and the result is the same. The swapfile is created, formatted, and set to nodatacow, but I get "Invalid argument" with swapon. I'm going to do some tests with a couple of usb-drives and report back.

latalante1, when quoting it's useful to provide the full context of the quote. Here is the section from the btrfs wiki (which I link to in my OP):

From kernel 5.0+ btrfs have native swap files support, but with some limitations. Swap file - must be fully allocated as NOCOW with no compression on one device.

For kernels before 5.0, swap files not supported. 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. The swap implementation used to rely on some assumptions which may not hold in btrfs, like block numbers in the swap file while btrfs has a different block number mapping in case of multiple devices. There is a new API that could be used to port swap to btrfs; for more details have a look at project ideas#Swap file support.

(emphasis mine)

I read that as saying that "Just making a file NOCOW..." applies to kernels before 5.0. This also seems to be the interpretation of whoever wrote the swapfile section of the Arch Wiki, which is the Wiki I'm referring to where you quote me. Are you agreeing that the Arch Wiki may be incorrect?

Last edited by woodape (2019-06-09 04:52:52)

Offline

#7 2019-06-09 05:29:54

woodape
Member
Registered: 2015-03-25
Posts: 159

Re: [SOLVED] Swapfile on BTRFS filesystem with compression enabled

And I think I've come to the solution here. I used to 8GB USB-drives to do the following tests. I formatted them with mkfs.btrfs /dev/sdb1 for "One-disk" or mkfs.btrfs -d raid{0,1} -m raid1 /dev/sdb1 /dev/sdc1 for RAID{0,1}. After formatting and mounting to "/mnt", I ran the following script as root (just the Arch Wiki commands one after another):

#!/bin/bash

truncate -s 0 /mnt/swapfile
chattr +C /mnt/swapfile
btrfs property set /mnt/swapfile compression none
fallocate -l 512M /mnt/swapfile
chmod 600 /mnt/swapfile
lsattr /mnt/swapfile
mkswap /mnt/swapfile
swapon /mnt/swapfile

Results below:

Mount Options      | RAID     | Result
===================================
CoW                | One-disk | GOOD
CoW, compress=zstd | One-disk | GOOD
CoW                | RAID0    | FAIL
CoW, compress=zstd | RAID0    | FAIL
CoW                | RAID1    | FAIL
CoW, compress=zstd | RAID1    | FAIL

It appears that the Arch Wiki isn't wrong but it is missing that swapfiles are not supported on Btrfs filesystems formatted with RAID. I'll proposed the edit.

Now I'll need to consider whether it's worth shrinking my already encrypted partitions to fit in a partition for swap. If making a separate partion, I may just make a raw swap partition and encrypt it with plain dm-crypt and a random password.

Thanks for helping me work through this issue.

Offline

#8 2022-02-19 22:26:05

Simorgh
Member
From: Burlington, Ontario, Canada
Registered: 2016-12-20
Posts: 6

Re: [SOLVED] Swapfile on BTRFS filesystem with compression enabled

Hi all Arch-ers,

I am absolute new to Arch environment and today I managed to install Arch with btrfs on metal.
I followed a guide which installed zram, but I didn't want to go that route.

I did the following to make swap:

[root@simarch ~]# truncate -s 0 /mnt/swapfile
[root@simarch ~]# ls -la /mnt/swapfile 
-rw-r--r-- 1 root root 0 Feb 19 17:03 /mnt/swapfile
[root@simarch ~]# chattr +C /mnt/swapfile
[root@simarch ~]# btrfs property set /mnt/swapfile compression none
[root@simarch ~]# fallocate -l 512M /mnt/swapfile
[root@simarch ~]# chmod 600 /mnt/swapfile
[root@simarch ~]# lsattr /mnt/swapfile
---------------C------ /mnt/swapfile
[root@simarch ~]# mkswap /mnt/swapfile
Setting up swapspace version 1, size = 512 MiB (536866816 bytes)
no label, UUID=a5a44527-fcb9-49df-846a-d70c76a1a555
[root@simarch ~]# swapon /mnt/swapfile
[root@simarch ~]# free -m
               total        used        free      shared  buff/cache   available
Mem:           15896        1242       13391          30        1262       14341
Swap:            511           0         511

How can I add the swap to my fstab?
My fstab looks like this right now:

# /dev/sda2
UUID=de68207d-4e98-4989-a4a1-5e73ec3e1979	/         	btrfs     	rw,noatime,compress=zstd:3,ssd,discard=async,space_cache=v2,subvolid=256,subvol=/@	0 0

# /dev/sda1
UUID=2DCC-1A76      	/boot/efi 	vfat      	rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro	0 2

# /dev/sda2
UUID=de68207d-4e98-4989-a4a1-5e73ec3e1979	/home     	btrfs     	rw,noatime,compress=zstd:3,ssd,discard=async,space_cache=v2,subvolid=257,subvol=/@home	0 0

# /dev/sda2
UUID=de68207d-4e98-4989-a4a1-5e73ec3e1979	/var      	btrfs     	rw,noatime,compress=zstd:3,ssd,discard=async,space_cache=v2,subvolid=258,subvol=/@var	0 0

Would appreciate guidance.

Offline

Board footer

Powered by FluxBB