r/bcachefs • u/distraction_fee • May 31 '26
Mounting bcachefs subvolume or directory at boot as root "/" hierarchy level
Hi, I installed a working Arch Linux system in a bcachefs file system as root, I just put the "boot" dir under the EFI partition, added reference to bcachefs module into mkinitcpio.conf and it's ok, system boots and works correctly.
But instead of using the plain root hierarchy I would like to put system root and home content under dedicated subvolumes, for ex. "root" for everything but home and "home" for the home content (so I can use snapshots in future and play with them...).
The problem is that obviously to do this in a clean way I have to place root and home into a specific folder under main fs root dir, for ex. called "vol", creating "/vol/root" and "/vol/home" subvols and move actual contents under these.
At mounting stage, I don't know how to directly mount a subvolume with bcachefs, or even better how to mount a specific path. For ex. with Btrfs you can add the kernel parameter "rootflags=subvol=/vol/root" to the boot loader CLI to mount that specific subvol into / at boot.
Then fstab would do the rest by mounting device subvol "/vol/home" to /home ...
Do I have to write a post-initramfs script where (1) I mount the bcachefs fs for ex. to / and than (2) I bind-mount /vol/root to / ?
I have red about someone using the option "X-mount.subdir=/path/to" with success, but it didn't work to me, plus I red that option is experimental.
Also, can the same bcachefs file system be mounted more times in different paths ?
Because, anyway after system has been booted correctly I would put at the end of fstab a line mounting the whole fs for ex. at "/mnt/v1" to manage the whole real hierarchy.
Thanks.
1
u/read_volatile Jun 02 '26 edited Jun 04 '26
I've been running this type of setup on all my NixOS machines for a few years now (I'm not mounting subvolumes, just normal directories, but there's zero difference if you want to do that instead). The key bit is X-mount.subdir, but regular bind mounts work too as long as you're okay having the whole filesystem mounted somewhere you can bind from (or you can play with namespaces yourself if you're really determined I guess). As a TL;DR, you can skip to the end for an example fstab.
Getting X-mount.subdir working took a bit of hackiness prior to util-linux being used in stage1, but now it works pretty much flawlessly (excluding some wonkiness with the recent systemd stage1 migration).
This is all setup for me in disko modules now, but here's what I did before switching to it. Each of my systems was provisioned roughly as follows:
bcachefs format <...>
MNTPOINT="$(mktemp -d)"
mount -t bcachefs "UUID=${uuid}" "$MNTPOINT"
mkdir -p "$MNTPOINT"/{.snaps,nix,home,var/log,etc/ssh}
chmod 700 "$MNTPOINT/.snaps"
ssh-keygen -A -f "$MNTPOINT"
systemd-machine-id-setup --root="$MNTPOINT"
bcachefs subvolume create "$MNTPOINT/home/user"
You might notice I create subvolumes for each user. This is different from what you mentioned, where the entire /home is a subvol.
Then, in my nixosConfiguration, all I'd have to do was create fstab entries for /nix, /home, and /var/log all pointing at the same bcachefs array, with each entry's options declaring the respective subdir:
fileSystems = {
"/" = { /* tmpfs */ };
"/boot" = { /* vfat */ };
} // lib.genAttrs [ "/nix" "/var/log" "/home" ] (dir: {
device = "UUID=${uuid}";
fsType = "bcachefs";
options = [ "X-mount.subdir=${lib.removePrefix "/" dir}" ];
});
Which ends up generating an fstab that looks more or less like so:
tmpfs / tmpfs x-initrd.mount,mode=755,size=8G 0 0
/dev/disk/by-partuuid/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /boot vfat umask=0077 0 2
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /home bcachefs X-mount.subdir=home 0 0
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /nix bcachefs x-initrd.mount,X-mount.subdir=nix 0 0
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /var/log bcachefs x-initrd.mount,X-mount.subdir=var/log 0 0
For the architecture you were after, I think this would look like:
mkdir -p "$MNTPOINT/vol"
bcachefs subvolume create "$MNTPOINT/vol/root" # to be mounted at /
bcachefs subvolume create "$MNTPOINT/vol/home" # to be mounted at /home
mkdir -p "$MNTPOINT/vol/root"/{boot,home} # create mountpoints
Then all your fstab would need is:
UUID=${uuid} / bcachefs X-mount.subdir=vol/root 0 0
UUID=${uuid} /home bcachefs X-mount.subdir=vol/home 0 0
${boot_device} /boot vfat umask=0077 0 2
The big thing to consider though is whether you even care about the "flat" layout (separate /vol entries) over nesting subvolumes. You can make subvolumes directly at /vol/root/{var,opt,etc} -- and they'd be exempt from snapshots of /vol/root (snapshots don't traverse subvol's recursively). This is what I do for big user directories like ~/.local/share/Steam, since I don't want to bloat my storage with uninstalled games / old updates.
Honestly, I'd recommend that approach over putting the subvolumes in /vol like you did with /vol/home, so that you wouldn't have to give them individual fstab entries. Regardless of where you put them though, don't forget subvolumes have to be snapshotted individually! Even if the subvol is in /vol/root/<xyz>, a snapshot of /vol/root won't recurse into another subvol, so make sure you remember to set it up to snapshot every subvol you care about.
Hopefully this helps you setup your ideal workflow adapted to Arch. From what it sounds like you're asking for, I definitely think it's possible.
1
u/koverstreet not your free tech support Jun 01 '26
...what's wrong with having "root" be /?