:PROPERTIES: :ID: 20211221T151214.142594 :END: #+TITLE: btrfs retrospective #+AUTHOR: Chris Cochrun #+CREATED: 12/20/21 - 12:00 AM Create btrfs subvolumes retrospectively This posts describes how to create subvolumes in btrfs retrospectively (with existing data). I’m using archlinux, but most of the things should be applicable to other distors as well. It is mostly a list of the required commands, with a tiny bit of explanations :). All the commands are real world examples from my system, so you need to adapt device names etc. to your setup. Move the top-level volume to a subvolume create a snapshot 1 sudo btrfs subvol snapshot / /@ (ā€œ@ā€ seems to be a common name for the main subvolume) set the new snapshot as default subvolume 1 2 3 4 sudo btrfs subvol list / # outputs: ID 330 gen 1354 top level 5 path @ # use the id from the output above to sudo btrfs subvol set-default 330 / if it is not the root volume, skip to the last point of this section adapt grub to boot from the new subvolume mount the new subvolume 1 2 3 cd /mnt sudo mkdir newroot sudo mount -o subvol=@ /dev/mapper/cryptroot newroot edit newroot/etc/fstab to include subvol=@ in the / options This should not be needed theoretically since it is the default volume, but grub-mkconfig did not produce a correct config for me without it. 1 2 UUID=2240f8f3-3dfa-4aad-a62f-899f5970cb3d / btrfs defaults,subvol=@,noatime,discard,space_cache,autodefrag,compress=lzo 0 0 chroot into the new subvolume and update grub 1 2 3 4 5 6 7 for i in /dev /dev/pts /proc /sys /run; do sudo mount --bind $i newroot$i; done sudo mount /dev/mapper/cryptboot newroot/boot sudo mount /dev/sdc1 newroot/boot/efi sudo mount --bind /sys/firmware/efi/efivars newroot/sys/firmware/efi/efivars sudo chroot /mnt/newroot grub-mkconfig -o /boot/grub/grub.cfg grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=arch-grub --recheck unmount and reboot (at your own risk of course :D) delete the old data from the toplevel 1 2 3 4 5 cd /mnt sudo mkdir oldroot sudo mount -o subvolid=5 /dev/mapper/cryptroot oldroot cd oldroot # CAREFULLY delete everything except @ subvolume Move existing directory to a subvolume In this example the directory /home/martin/develop will be replaced with a subvolume. create the new subvolume 1 2 3 sodo mkdir /mnt/toplevel sudo mount -o subvolid=5 /dev/mapper/cryptroot /mnt/toplevel sudo btrfs subvol create /mnt/toplevel/@develop move the data to the new subvolume in the most efficient way (as far as I know) by creating reflinks 1 sudo cp -ax --reflink=always /mnt/toplevel/@/home/martin/develop/. /mnt/toplevel/@develop delete the old directory 1 2 # DO THIS AT YOUR OWN RISK rm -rf /home/martin/develop mount the new subvolume instead 1 2 mkdir /home/martin/develop sudo mount -o subvol=@develop /dev/mapper/cryptroot /home/martin/develop add new fstab entry to mount the new subvolume automatically 1 2 UUID=2240f8f3-3dfa-4aad-a62f-899f5970cb3d /home/martin/develop btrfs defaults,subvol=@develop,noatime,discard,space_cac he,autodefrag,compress=lzo 0 0 Note that the top-level volume always has the ID 5. Reference: https://btrfs.wiki.kernel.org/index.php/UseCases#Can_I_take_a_snapshot_of_a_directory.3F