mount, device_scan: Convert to OsString

We're not guaranteed valid UTF-8 here, OsString is correct.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2025-11-30 11:57:14 -05:00
parent f249100bf9
commit e1674f3b12
2 changed files with 18 additions and 14 deletions

View File

@ -1,6 +1,7 @@
use std::{ use std::{
ffi::CString, ffi::{CString, OsString},
io::{stdout, IsTerminal}, io::{stdout, IsTerminal},
os::unix::ffi::OsStringExt,
path::{Path, PathBuf}, path::{Path, PathBuf},
ptr, str, ptr, str,
}; };
@ -17,14 +18,14 @@ use crate::{
}; };
fn mount_inner( fn mount_inner(
src: String, src: OsString,
target: &std::path::Path, target: &std::path::Path,
fstype: &str, fstype: &str,
mut mountflags: libc::c_ulong, mut mountflags: libc::c_ulong,
data: Option<String>, data: Option<String>,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
// bind the CStrings to keep them alive // bind the CStrings to keep them alive
let c_src = CString::new(src.clone())?; let c_src = CString::new(src.clone().into_vec())?;
let c_target = path_to_cstr(target); let c_target = path_to_cstr(target);
let data = data.map(CString::new).transpose()?; let data = data.map(CString::new).transpose()?;
let fstype = CString::new(fstype)?; let fstype = CString::new(fstype)?;
@ -63,9 +64,9 @@ fn mount_inner(
let e = crate::ErrnoError(err); let e = crate::ErrnoError(err);
if err.0 == libc::EBUSY { if err.0 == libc::EBUSY {
eprintln!("mount: {}: {} already mounted or mount point busy", target.to_string_lossy(), src); eprintln!("mount: {}: {:?} already mounted or mount point busy", target.to_string_lossy(), src);
} else { } else {
eprintln!("mount: {}: {}", src, e); eprintln!("mount: {:?}: {}", src, e);
} }
Err(e.into()) Err(e.into())
@ -160,7 +161,7 @@ fn cmd_mount_inner(cli: &Cli) -> Result<()> {
if let Some(mountpoint) = cli.mountpoint.as_deref() { if let Some(mountpoint) = cli.mountpoint.as_deref() {
info!( info!(
"mounting with params: device: {}, target: {}, options: {}", "mounting with params: device: {:?}, target: {}, options: {}",
devices, devices,
mountpoint.to_string_lossy(), mountpoint.to_string_lossy(),
&cli.options &cli.options
@ -169,7 +170,7 @@ fn cmd_mount_inner(cli: &Cli) -> Result<()> {
mount_inner(devices, mountpoint, "bcachefs", mountflags, optstr) mount_inner(devices, mountpoint, "bcachefs", mountflags, optstr)
} else { } else {
info!( info!(
"would mount with params: device: {}, options: {}", "would mount with params: device: {:?}, options: {}",
devices, &cli.options devices, &cli.options
); );

View File

@ -1,8 +1,9 @@
use std::{ use std::{
ffi::{CStr, CString, c_char, c_int}, ffi::{CStr, CString, c_char, c_int, OsString, OsStr},
collections::HashMap, collections::HashMap,
env, env,
fs, fs,
os::unix::ffi::OsStringExt,
path::{Path, PathBuf}, path::{Path, PathBuf},
str, str,
}; };
@ -179,14 +180,14 @@ pub fn scan_sbs(device: &String, opts: &bch_opts) -> Result<Vec<(PathBuf, bch_sb
} }
} }
pub fn joined_device_str(sbs: &Vec<(PathBuf, bch_sb_handle)>) -> String { pub fn joined_device_str(sbs: &Vec<(PathBuf, bch_sb_handle)>) -> OsString {
sbs.iter() sbs.iter()
.map(|sb| sb.0.clone().into_os_string().into_string().unwrap()) .map(|sb| sb.0.clone().into_os_string())
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(":") .join(OsStr::new(":"))
} }
pub fn scan_devices(device: &String, opts: &bch_opts) -> Result<String> { pub fn scan_devices(device: &String, opts: &bch_opts) -> Result<OsString> {
let mut sbs = scan_sbs(device, opts)?; let mut sbs = scan_sbs(device, opts)?;
for sb in &mut sbs { for sb in &mut sbs {
@ -236,8 +237,10 @@ pub extern "C" fn bch2_scan_devices(device: *const c_char) -> *mut c_char {
// how to initialize to default/empty? // how to initialize to default/empty?
let opts = bch_bindgen::opts::parse_mount_opts(None, None, true).unwrap_or_default(); let opts = bch_bindgen::opts::parse_mount_opts(None, None, true).unwrap_or_default();
CString::new(scan_devices(&device, &opts).unwrap_or_else(|e| { let devs = scan_devices(&device, &opts).unwrap_or_else(|e| {
eprintln!("bcachefs ({}): error reading superblock: {}", device, e); eprintln!("bcachefs ({}): error reading superblock: {}", device, e);
std::process::exit(-1); std::process::exit(-1);
})).unwrap().into_raw() });
CString::new(devs.into_vec()).unwrap().into_raw()
} }