From cb7618cb34a638c5778b8b2f579ca6d5a71d1fe3 Mon Sep 17 00:00:00 2001 From: Aiden McClelland Date: Sat, 21 Mar 2026 18:20:15 -0600 Subject: [PATCH] fix: e2fsck exit codes 1-3 are non-fatal during btrfs conversion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit e2fsck returns 1 when errors are corrected and 2 when corrections require a reboot. These are expected during ext4→btrfs conversion. Only exit codes >= 4 indicate actual failure. Previously, .invoke() treated any non-zero exit as an error, causing the conversion to fail after successful filesystem repairs. --- core/src/disk/main.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/core/src/disk/main.rs b/core/src/disk/main.rs index 80ba3fa64..a88c94ab1 100644 --- a/core/src/disk/main.rs +++ b/core/src/disk/main.rs @@ -314,11 +314,30 @@ pub async fn mount_fs>( phase.start(); } tracing::info!("Running e2fsck before converting {name} from ext4 to btrfs"); - Command::new("e2fsck") + // e2fsck exit codes: 0 = no errors, 1 = errors corrected, 2 = corrected + reboot needed + // Only codes >= 4 indicate actual failure, so we can't use .invoke() which treats any + // non-zero exit as an error. + let e2fsck_output = Command::new("e2fsck") .arg("-fy") .arg(&blockdev_path) - .invoke(ErrorKind::DiskManagement) - .await?; + .kill_on_drop(true) + .stdout(std::process::Stdio::piped()) + .stderr(std::process::Stdio::piped()) + .output() + .await + .with_kind(ErrorKind::DiskManagement)?; + let e2fsck_exit = e2fsck_output.status.code().unwrap_or(4); + if e2fsck_exit >= 4 { + let msg = std::str::from_utf8( + if e2fsck_output.stderr.is_empty() { + &e2fsck_output.stdout + } else { + &e2fsck_output.stderr + }, + ) + .unwrap_or("e2fsck failed"); + return Err(Error::new(eyre!("{msg}"), ErrorKind::DiskManagement)); + } tracing::info!("Converting {name} from ext4 to btrfs"); Command::new("btrfs-convert") .arg("--no-progress")