From e2bc980116461435788623b7493ccab4fe49e803 Mon Sep 17 00:00:00 2001 From: Amaan Qureshi Date: Mon, 25 May 2026 20:04:30 -0400 Subject: [PATCH] fix: unlock once per bcachefs filesystem Encrypted bcachefs filesystems can have several mountpoints, but we only need to unlock the filesystem once. Unlocking inside each mount fragment can hit `EBUSY` after the first mount has already opened the device. This commit moves the unlock step to the filesystem-level mount setup so it runs once before mounting the root and subvolumes, while keeping the existing already-unlocked check. --- lib/types/bcachefs_filesystem.nix | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/types/bcachefs_filesystem.nix b/lib/types/bcachefs_filesystem.nix index 232f9e14..42a64076 100644 --- a/lib/types/bcachefs_filesystem.nix +++ b/lib/types/bcachefs_filesystem.nix @@ -230,11 +230,6 @@ # @todo Figure out why the "X-mount.mkdir" option here doesn't seem to work, # necessitating running `mkdir` here. mkdir -p "${rootMountPoint}${subvolume.mountpoint}"; - ${lib.optionalString (config.passwordFile != null) '' - if ! bcachefs unlock -k session "/dev/disk/by-uuid/${config.uuid}" < "${config.passwordFile}"; then - test -d "/sys/fs/bcachefs/${config.uuid}"; - fi; - ''} mount \ -t bcachefs \ -o "${ @@ -256,6 +251,17 @@ ) (lib.attrValues config.subvolumes); in { + dev = lib.optionalString (config.passwordFile != null) '' + # Unlock once per filesystem, before any of its mountpoints are + # processed. Doing this inside each per-mountpoint fragment causes + # EBUSY on the second mount because the first mount holds the + # device exclusively. + if ! findmnt "UUID=${config.uuid}" >/dev/null 2>&1; then + if ! bcachefs unlock -k session "/dev/disk/by-uuid/${config.uuid}" < "${config.passwordFile}"; then + test -d "/sys/fs/bcachefs/${config.uuid}"; + fi; + fi; + ''; fs = subvolumeMounts // lib.optionalAttrs (config.mountpoint != null) { @@ -264,11 +270,6 @@ # @todo Figure out why the "X-mount.mkdir" option here doesn't seem to work, # necessitating running `mkdir` here. mkdir -p "${rootMountPoint}${config.mountpoint}"; - ${lib.optionalString (config.passwordFile != null) '' - if ! bcachefs unlock -k session "/dev/disk/by-uuid/${config.uuid}" < "${config.passwordFile}"; then - test -d "/sys/fs/bcachefs/${config.uuid}"; - fi; - ''} mount \ -t bcachefs \ -o "${lib.concatStringsSep "," (lib.unique ([ "X-mount.mkdir" ] ++ config.mountOptions))}" \