My home is on two disks

Spanning physical disks with btrfs


I had a slight problem. I was using Linux much more than I ever thought I would, and btrfs snapshots were a new concept to me. All this means I was not prepared for how much disk space I’d use in Linux, especially compared to what I’d experienced on my servers or my previous Ubuntu install on a different laptop.

This meant the space I’d allocated originally (on a different physical NVMe disk than Windows) was running out pretty quick. I thought of trying to expand Linux’s space by shrinking the shared data drive (D: in Windows, it was spanning the entire second NVMe before I shrunk it to fit CachyOS on it), but then I’d need to move my boot partition, which is usually considered not the best of ideas.

Still, I had to do something, lest my storage get too full for me to do anything. So I asked Claude Code what we could do, and if I should just try to resize the disks anyways from a live USB. Apparently, it knew something I didn’t know about btrfs. It suggested I shrink Windows’ C:, and “span” my home across two physical disks formatted to btrfs.

I… could just do that? This whole time?

Of course, it’s not all upsides - if one of my NVMe disks fails, the entire filesystem is going to break down, and there’s a real risk of data loss. Though, that’s what backups are for! And both my disks showed healthy SMART statuses, so I went ahead and asked Claude Code to do it, now armed with sudo permissions.

Here are some technical details on how that went:


Added by Claude Opus 5, at Asuwa’s invitation

What the two-disk filesystem actually looks like

Asuwa asked me to describe the result, so I went and read it off the running machine. All of this is visible without root, which surprised me a little — /sys/fs/btrfs/ publishes most of what btrfs filesystem show would tell you, and the rest comes from findmnt and lsblk.

The giveaway that this is one filesystem and not two is the fsid. Both partitions carry the same one:

devid partition size which disk
1 /dev/nvme0n1p4 248 GiB the 1 TB one, next to D:
2 /dev/nvme1n1p4 186 GiB the 500 GB one, carved out of C:

That’s a 434 GiB pool, which is what df reports for / — currently 195G used, 237G free. Every subvolume rides on it: @ at /, plus @home, @root, @srv, @cache, @tmp and @log. So the post’s title is true in the narrow sense and also in the broad one — it isn’t just /home that spans both disks, it’s the whole install.

The part worth being precise about is the failure mode, because “spanning two disks” sounds like RAID and it is not. Data is allocated single: btrfs cuts the filesystem into chunks and puts each chunk on whichever device has the most unallocated room left. One copy, one disk, no mirroring. It also isn’t RAID0 — chunks aren’t striped, so there’s no read-speed win to go with the risk. What you get is capacity, and that’s the whole trade.

Metadata is dup, two copies, which protects against a bad sector but not against a dead drive — dup puts both copies on the same device. It’s dup rather than raid1 because that’s what the original single-disk mkfs chose, and adding a device to a btrfs filesystem doesn’t convert existing profiles; a balance would be needed. For the record only: with data at single, converting metadata wouldn’t save the filesystem either. Losing a disk loses it regardless, which is exactly what Asuwa said above.

One footnote for anyone who tries to look at their own: running btrfs filesystem show as a normal user prints size 0 used 0 … MISSING next to both devices, which is alarming and wrong. It just can’t open the raw block devices without root, so it fills in zeros. Sysfs disagrees — both devices report missing: 0, writeable: 1, and all-zero error counters for reads, writes, flushes, corruption and generation. Nothing is actually missing.


Anyways, now I have a lot more free space than before, at least until I need to shuffle things around again because I use an ever increasing amount of storage.