Multi-boot partitioning / The layout
The machine
WD Black SN770 2TB NVMe (/dev/nvme0n1). One disk, three operating systems. The layout was not designed all at once — it evolved under real constraints. What follows is the current state and the reasoning behind it.
/dev/nvme0n1
├── p1 /boot/efi fat32 1.0G ESP (UUID: 1A4A-CE0B)
├── p2 MSR ntfs 16M Windows metadata
├── p3 Windows ntfs 431G (shrunk from 487G)
├── p4 BSD — 31G empty — future experimentation
├── p5 btrfs pool btrfs 887G UUID: d7a98795-1604-4baa-ae07-05e29a3ff1e6
├── p7 Arch btrfs 487G UUID: 275bce6c-f037-43f9-be0f-650efb12cf1e
├── p8 /boot ext4 7.6G UUID: fba989bd-2a90-4e11-9aa2-4c941d3e0460
└── p9 recovery ext4 18.6G empty — future Arch recovery
p5 is the main Linux pool. It holds all Void subvolumes, the shared home, shared data, shared Docker storage, and the cache subvolume. p7 is Arch’s separate btrfs root. p8 is the shared /boot that both distros write kernels into.
Partition by partition
p1 — ESP
The EFI System Partition holds only bootloader binaries. GRUB’s EFI stub is a few megabytes. 1G is generous but causes no harm. Formatted fat32, shared across all operating systems. There is one GRUB installation here — Arch owns it. Void does not install its own EFI entry.
p2 — MSR
Windows requires a Microsoft Reserved Partition on GPT disks for its own metadata. Non-negotiable if Windows is on a GPT disk. 16M, ntfs, not mounted by Linux.
p3 — Windows
Shrunk from 487G to 431G using the Windows disk management tool. The shrink was done from within Windows rather than from Linux — ntfs resize from Linux with ntfsresize requires the volume to be cleanly unmounted, and the Windows fast-startup feature leaves it in a hibernate state. Easier to shrink it from the inside.
p4 — BSD placeholder
Empty, unformatted. Reserved for future experimentation with DragonFlyBSD or FreeBSD. BSD partitions do not sit well inside Linux partition tables without dedicated space planned upfront.
p5 — btrfs pool
887G, the result of merging two separate partitions. Originally p5 was 430G and p6 was 457G. Merging them into a single pool eliminated artificial boundaries between subvolumes and simplified the fstab. The merge process is covered in [Multi-boot partitioning / Merging btrfs partitions].
This partition hosts the following subvolumes:
@void /
@void-var /var
@void-snapshots /.snapshots
@home /home
@data /data
@docker /var/lib/docker
@home-cache ~/.cache
p7 — Arch btrfs root
Arch predates the unified pool. Its btrfs partition is separate and carries its own subvolume layout. Migrating it into p5 is technically possible but adds no practical benefit for how this machine is used.
p8 — shared /boot
The original /boot lived on a 1G partition. It filled up. Two Linux kernels with headers and initramfs images exhaust 1G faster than expected. p8 is 7.6G — enough for both distros to keep multiple kernel versions without pressure. Both Void and Arch write their kernels here. GRUB reads from here. See [Multi-boot partitioning / Shared GRUB partition].
p9 — recovery
Empty ext4 partition. Reserved for a future Arch rescue environment or a minimal live system. Not currently in use.
Why not LVM
LVM adds logical volume management on top of block devices: resize volumes without repartitioning, group physical devices, thin provisioning. btrfs subvolumes do the same thing inside a single filesystem — create, destroy, snapshot, and resize namespaces without touching the partition table.
For a single-disk setup, LVM on top of btrfs is two abstraction layers for no gain. The one thing LVM provides that btrfs subvolumes don’t is spanning multiple physical block devices. btrfs supports this too (btrfs RAID), but on a single NVMe the point is moot.
What forced the layout to evolve
Two constraints drove the major structural changes.
The first was the 1G /boot filling up. Arch’s kernel packages — linux, linux-lts, linux-headers — each consume several hundred MB. Two kernels plus initramfs images exhausted 1G. Managing it meant manually dropping old kernels, which is error-prone. Migrating to a 7.6G partition eliminated the pressure and made room for Void to coexist.
The second was the p5+p6 boundary. Two separate btrfs partitions meant two mount points, two sets of fstab entries, and no clean way to share subvolumes across them. A @home subvolume on p5 cannot be accessed from p6 without explicit cross-mount plumbing. Merging into a single pool resolved this structurally — shared subvolumes become trivial.
Connection closed. Returning to terminal...