BTRFS Changing of separate home volume to subvolume and resizing home

I am running two desktop PCs both complete with large amount of programs and their special settings. Manjaro is installed on both PCs using the same scheme which shows up in fstab like this:

# <file system>                          <mount point>  <type>  <options>  <dump>  <pass>
UUID=0E7B-F5B8                            /boot/efi      vfat    umask=0077 0 2
UUID=8ea8dac6-6a2f-4d63-8f11-a8e1f3c826a1 /              btrfs   subvol=/@,defaults,noatime,compress=zstd:6,discard=async,ssd 0 0
UUID=8ea8dac6-6a2f-4d63-8f11-a8e1f3c826a1 /var/cache     btrfs   subvol=/@cache,defaults,noatime,compress=zstd:6,discard=async,ssd 0 0
UUID=8ea8dac6-6a2f-4d63-8f11-a8e1f3c826a1 /var/log       btrfs   subvol=/@log,defaults,noatime,compress=zstd:6,discard=async,ssd 0 0
UUID=8b37d92c-1577-401b-b896-4ad585b47b01 /home          btrfs   defaults,noatime,compress=zstd:6,discard=async,ssd 0 0
UUID=e867b6e6-26c8-4142-90ee-0df68b69ba4f swap           swap    defaults,noatime 0 0

I would like to do the following changes:

  1. The volume /home should be integrated as a subvolume just as the other already existing subvolumes.
  2. I would like to shrink the entire btrfs set of subvolumes.
  3. I would like to create a new partition in the free space on the ssd drive in order to use this for all my application generated data.

Both desktop PCs are in productive use, but they are different in the configuration of their programs and tools. So I cannot risk to crash one of them by experimenting.

My question: How can I go through these steps while minimizing the risk to crash the stable running systems?

It’s actually not that difficult, but I would advise you to run the operation from a live USB, rather than from inside the system.

First of all, you have to create a subvolume for /home in the filesystem root — note: this is not the @ subvolume! For this purpose, you need to mount the filesystem root, as follows… — note: I’m assuming you’re working from a terminal window in the live USB session… :backhand_index_pointing_down:

sudo -i
mkdir /mnt/btrfsroot
mkdir /mnt/oldhome
mount -t btrfs -o subvolid=5 UUID=8ea8dac6-6a2f-4d63-8f11-a8e1f3c826a1 /mnt/btrfsroot/
mount -t btrfs -o subvolid=5 UUID=8b37d92c-1577-401b-b896-4ad585b47b01 /mnt/oldhome/
cd /mnt/btrfsroot/
btrfs subvolume create @home
cp -RPpv /mnt/oldhome/* @home/

This is going to take some time, but the cp command above is verbose. When it’s done, edit the /etc/fstab of your installed system as follows… :backhand_index_pointing_down:

nano @/etc/fstab

In the file, modify the line for /home so that it becomes… :backhand_index_pointing_down:

UUID=8ea8dac6-6a2f-4d63-8f11-a8e1f3c826a1  /home   btrfs  subvol=/@home,noatime,compress=zstd:6,discard=async,ssd 0 0

Note: The UUID is now the same as that of the root filesystem and the other subvolumes, because it is the same btrfs filesystem, and you now have the subvol=@home mount option in there as well.

Save the file with CtrlO followed by Enter, and exit nano with CtrlX.

At this point, you’ve made the necessary modifications for having /home as a subvolume on the btrfs filesystem. This leaves the question what to do with the partition you used to use for /home. You could now delete everything on that partition, as follows… :backhand_index_pointing_down:

rm -rf /mnt/oldhome/*

If you want to reuse it “as is”, then you could add another mountpoint for it in the /etc/fstab file of the installed system, thereby reusing the UUID that the partition already had when it was still mounted to /home. However, it’ll need a new mountpoint, which I suggest you would create under your home directory, e.g. /home/jaqueline/Data. This can easily be done once you’ve already booted back into the installed system. :backhand_index_pointing_down:

UUID=8b37d92c-1577-401b-b896-4ad585b47b01 /home/jaqueline/Data     btrfs   noatime,compress=zstd:6,discard=async,ssd 0 0

Another option is to reformat the partition, or to delete it with a partitioning tool — e.g. gparted — and recreate it, possibly with a different size. And in that case, you’ll also need to add the partition to /etc/fstab again, and make sure it has a mountpoint.

(Note: If the new mountpoint is under your home directory, as I proposed, then you should create the directory without using sudo, so that it’ll have the correct permissions and ownership.)

As for your idea to shrink the root filesystem, I would advise you not to. You may end up losing data.

Lastly, given that we’re still working from the live USB for now, you must unmount everything and cleanly reboot your system. :backhand_index_pointing_down:

cd 
umount /mnt/oldhome
umount /mnt/btrfsroot
exit

Good luck!

:crossed_fingers:

Oh thank you so much! It seems really safe and relatively easy way to do it.

After I would have created the new @home, I would copy all the configuration data from the former /home to it. Perhaps I should copy this data on a USB stick before, to keep this acessable?
And yes, after this copy, I would create a new partition in the empty space (formerly the old /home) in order to use it for data.

Is there something I should be especially aware of like chown of the new @home etc?

The procedure as I’ve laid it out above will include all of your configuration data. It will effectively copy everything from your original home to the new subvolume. :wink:

No, because the cp command I gave you preserves the original ownership and permissions. :wink:

All you need to make sure of is that when you create /home/jaqueline/Data, you do this as yourself, without using sudo, because it’s a directory in your $HOME, and you want it to be owned by you. :wink:

Note: If you delete and recreate the old partition, then the UUID will be different. Keep this in mind when adding it to fstab. You can ascertain the new UUID with… :backhand_index_pointing_down:

lsblk -o NAME,UUID

I just finished the procedure for the first desktop PC successfully. Your description, how to proceed was absolutely helpful for me and so I everything went easy.
One little thing happened: when I mounted the former /home with the same UUID as before via fstab, the partition itself was owned by root while all the files and folders on it were owned by me. – Quickly chowned the partition and (nearly) everything is OK now.

But although I had moved everything I don’t need in my new @home, reducing space on the /oldhome before I followed your steps, I now have only 11 GB space free on the btrfs subvolume set.
This is of course not enough, especially because I additionally want VirtualBox and a Win-7 VM on it. So I would like to resize / enlarge the btrfs subvolume set as well as shrinking the new data partition.

You wrote:

OK, I have something read about shrinking a btrfs system in the old btrfs wiki. They recommended to use btrfs-tools to first make data compact and after this in a second step, a volume can be shrinked without risking to loose data.
In my case, I want to enlarge the partition which contains the btrfs subvolume set of the system. To my knowledge, this would not be risky.
And on the new data partition, I can eliminate all data from it and then shrinking.

BTW: I just have found this Info here: Is it safe to resize BTRFS partition? - #3 by anon7296107

What is your opinion about these variations in size?

Mod edit: Fixed quote.

:partying_face:

That is very nice to hear, thank you. :wink:

I would recommend deleting the data partition and then enlarging the root filesystem. You can then more easily create a new and smaller data partition behind it. You cannot shrink a partition from the left — only from the right — so this is the safest bet.

Also, I would recommend running a balance operation on the root filesystem before resizing the root filesystem. btrfs is rather peculiar in how it allocates free space, and as such you may at one point find that you don’t have enough free space left, even though you actually do.

Start with the metadata, and then the data. :backhand_index_pointing_down:

sudo btrfs balance start -musage=95 /
sudo btrfs balance start -dusage=95 /

This will neatly pack things together as tightly as possible, leaving more contiguous free space. After the balancing, you can check the usage with… :backhand_index_pointing_down:

btrfs filesystem usage -h /

An example from my own system here… :backhand_index_pointing_down:

[nx-74205:/dev/pts/2][/root] #  btrfs filesystem usage -h /
Overall:
    Device size:                 930.51GiB
    Device allocated:            159.06GiB
    Device unallocated:          771.45GiB
    Device missing:                  0.00B
    Device slack:                    0.00B
    Used:                        155.00GiB
    Free (estimated):            775.23GiB      (min: 389.50GiB)
    Free (statfs, df):           775.23GiB
    Data ratio:                       1.00
    Metadata ratio:                   2.00
    Global reserve:              204.50MiB      (used: 0.00B)
    Multiple profiles:                  no

Data,single: Size:157.00GiB, Used:153.22GiB (97.59%)
   /dev/sda3     157.00GiB

Metadata,DUP: Size:1.00GiB, Used:913.39MiB (89.20%)
   /dev/sda3       2.00GiB

System,DUP: Size:32.00MiB, Used:48.00KiB (0.15%)
   /dev/sda3      64.00MiB

Unallocated:
   /dev/sda3     771.45GiB

[nx-74205:/dev/pts/2][/root] # 

Pay attention to the percentages for… :backhand_index_pointing_down:

  • Data, single
  • Metadata, DUP
  • System, DUP

The first two are the ones to watch, and ideally, they should hover around 90% or higher, which gives you optimal filesystem usage and the most free/unallocated space.

By the way… :backhand_index_pointing_down:

Don’t put virtualbox images on btrfs. This is going to cause you headaches, because btrfs uses copy-on-write and sparse files.

You should put the disk images on an ext4 filesystem instead. If not possible, then at least make sure that copy-on-write is disabled in the mount options (nodatacow) for the filesystem with the virtualbox disk images — I’m assuming it’ll be the partition that /home used to be on.

However, you wouldn’t want nodatacow on your root filesystem, because then you also wouldn’t be able to make snapshots anymore. Therefore, the best option for virtualbox disk images is still to put them on an ext4 filesystem instead.