I have just recently set up a new Arch Linux system with LVM on LUKS for disk encryption. The system is installed on an NVMe SSD. SSD controllers can be notified about unused blocks using TRIM, but by default this feature is not enabled on Arch Linux.
There are two approaches to enabling TRIM on Linux:
periodically running fstrim
and enabling discard option on the filesystem.
Enabling option the filesystem seems to be discouraged for multiple reasons,
one of which is that it wastes throughput on processing TRIM commands while the system is used.
fstrim.timer
Usually recommended setup is enabling periodic cleanup
by enabling fstrim.timer.
I enabled it with
# systemctl enable --now fstrim.timer Created symlink '/etc/systemd/system/timers.target.wants/fstrim.timer' → '/usr/lib/systemd/system/fstrim.timer'.
Then I ran fstrim manually:
# fstrim -av /efi: 1021.8 MiB (1071456256 bytes) trimmed on /dev/nvme0n1p1 /boot: 890.7 MiB (933982208 bytes) trimmed on /dev/nvme0n1p2
This discarded blocks on /efi and /boot partitions,
but did not work for encrypted partitions even though they were mounted.
LUKS disables discard by default for security reasons: it is possible to get some information about disk usage by looking at which blocks are discarded.
The issue sounds mostly theoretical, so I enabled discards on LUKS partition with
# cryptsetup luksDump /dev/nvme0n1p3 | grep Flags Flags: (no flags) # cryptsetup --allow-discards --persistent refresh crypt Enter passphrase for /dev/nvme0n1p3: # cryptsetup luksDump /dev/nvme0n1p3 | grep Flags Flags: allow-discards
Afterwards lsblk
showed that discards are now allowed on LUKS.
# lsblk --discard
NAME DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
nvme0n1 0 512B 2T 0
├─nvme0n1p1 0 512B 2T 0
├─nvme0n1p2 0 512B 2T 0
└─nvme0n1p3 0 512B 2T 0
└─crypt 0 512B 2T 0
├─vg-root 0 0B 0B 0
└─vg-home 0 0B 0B 0
LVM however still did not allow discards.
I rebooted the laptop, and then LVM detected that discards are allowed:
# lsblk --discard
NAME DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
nvme0n1 0 512B 2T 0
├─nvme0n1p1 0 512B 2T 0
├─nvme0n1p2 0 512B 2T 0
└─nvme0n1p3 0 512B 2T 0
└─crypt 0 512B 2T 0
├─vg-root 0 512B 2T 0
└─vg-home 0 512B 2T 0
Then I ran fstrim manually again
and it detected unused space on /home
and / partitions.
# fstrim -av /home: 167.3 GiB (179596095488 bytes) trimmed on /dev/mapper/vg-home /efi: 1021.8 MiB (1071456256 bytes) trimmed on /dev/nvme0n1p1 /boot: 890.7 MiB (933982208 bytes) trimmed on /dev/nvme0n1p2 /: 77.1 GiB (82783838208 bytes) trimmed on /dev/mapper/vg-root
I still have unused space on LVM, so I trimmed it manually by temporarily creating a logical volume, discarding it once, and removing it:
# lvcreate vg -l 100%FREE -n trim # blkdiscard /dev/vg/trim # lvremove /dev/vg/trim Do you really want to remove active logical volume vg/trim? [y/n]: y Logical volume "trim" successfully removed.