From b1e6d1ced265b3b19cf2648c506013bdf2b75a13 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Sat, 12 Oct 2024 14:02:51 -0400 Subject: [PATCH] cmd_mount: Change error message on -EBUSY to match util-linux This causes xfstests generic/741 to pass Signed-off-by: Kent Overstreet --- src/bcachefs.rs | 2 +- src/commands/mount.rs | 35 ++++++++++++++++++++++++----------- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/bcachefs.rs b/src/bcachefs.rs index de44bf8e..417cb01e 100644 --- a/src/bcachefs.rs +++ b/src/bcachefs.rs @@ -109,7 +109,7 @@ fn main() -> ExitCode { ExitCode::SUCCESS } "list" => commands::list(args[1..].to_vec()).report(), - "mount" => commands::mount(args, symlink_cmd).report(), + "mount" => commands::mount(args, symlink_cmd), "subvolume" => commands::subvolume(args[1..].to_vec()).report(), _ => { let r = handle_c_command(args, symlink_cmd); diff --git a/src/commands/mount.rs b/src/commands/mount.rs index 5411f1d7..fe69bf57 100644 --- a/src/commands/mount.rs +++ b/src/commands/mount.rs @@ -20,20 +20,20 @@ use crate::{ fn mount_inner( src: String, - target: impl AsRef, + target: &std::path::Path, fstype: &str, mut mountflags: libc::c_ulong, data: Option, ) -> anyhow::Result<()> { // bind the CStrings to keep them alive - let src = CString::new(src)?; - let target = path_to_cstr(target); + let c_src = CString::new(src.clone())?; + let c_target = path_to_cstr(target); let data = data.map(CString::new).transpose()?; let fstype = CString::new(fstype)?; // convert to pointers for ffi - let src = src.as_ptr(); - let target = target.as_ptr(); + let c_src = c_src.as_ptr(); + let c_target = c_target.as_ptr(); let data_ptr = data.as_ref().map_or(ptr::null(), |data| data.as_ptr().cast()); let fstype = fstype.as_ptr(); @@ -42,7 +42,7 @@ fn mount_inner( ret = { info!("mounting filesystem"); // REQUIRES: CAP_SYS_ADMIN - unsafe { libc::mount(src, target, fstype, mountflags, data_ptr) } + unsafe { libc::mount(c_src, c_target, fstype, mountflags, data_ptr) } }; let err = errno::errno().0; @@ -60,9 +60,19 @@ fn mount_inner( drop(data); - match ret { - 0 => Ok(()), - _ => Err(crate::ErrnoError(errno::errno()).into()), + if ret != 0 { + let err = errno::errno(); + let e = crate::ErrnoError(err); + + if err.0 == libc::EBUSY { + eprintln!("mount: {}: {} already mounted or mount point busy", target.to_string_lossy(), src); + } else { + eprintln!("mount: {}: {}", src, e); + } + + Err(e.into()) + } else { + Ok(()) } } @@ -360,7 +370,7 @@ pub struct Cli { verbose: u8, } -pub fn mount(mut argv: Vec, symlink_cmd: Option<&str>) -> Result<()> { +pub fn mount(mut argv: Vec, symlink_cmd: Option<&str>) -> std::process::ExitCode { // If the bcachefs tool is being called as "bcachefs mount dev ..." (as opposed to via a // symlink like "/usr/sbin/mount.bcachefs dev ...", then we need to pop the 0th argument // ("bcachefs") since the CLI parser here expects the device at position 1. @@ -373,5 +383,8 @@ pub fn mount(mut argv: Vec, symlink_cmd: Option<&str>) -> Result<()> { // TODO: centralize this on the top level CLI logging::setup(cli.verbose, cli.colorize); - cmd_mount_inner(&cli) + match cmd_mount_inner(&cli) { + Ok(_) => std::process::ExitCode::SUCCESS, + Err(_) => std::process::ExitCode::FAILURE, + } }