From 166c245ee76b4da0a1a84861db15d4ebe7c55930 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Sun, 30 Nov 2025 15:28:45 -0500 Subject: [PATCH] device_scan: Clean up udev code Signed-off-by: Kent Overstreet --- src/device_scan.rs | 93 +++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 51 deletions(-) diff --git a/src/device_scan.rs b/src/device_scan.rs index 4c4dd64d..396f23a1 100644 --- a/src/device_scan.rs +++ b/src/device_scan.rs @@ -38,33 +38,25 @@ fn device_property_map(dev: &udev::Device) -> HashMap { rc } -fn udev_bcachefs_info() -> anyhow::Result>> { - let mut info = HashMap::new(); - - if env::var("BCACHEFS_BLOCK_SCAN").is_ok() { - debug!("Checking all block devices for bcachefs super block!"); - return Ok(info); - } - - let mut udev = udev::Enumerator::new()?; - +fn get_devices_by_uuid_udev(uuid: Uuid) -> anyhow::Result> { debug!("Walking udev db!"); + let mut udev = udev::Enumerator::new()?; udev.match_subsystem("block")?; udev.match_property("ID_FS_TYPE", "bcachefs")?; - for m in udev + let uuid = uuid.to_string(); + + Ok(udev .scan_devices()? .filter(udev::Device::is_initialized) .map(|dev| device_property_map(&dev)) - .filter(|m| m.contains_key("ID_FS_UUID") && m.contains_key("DEVNAME")) { - let fs_uuid = m["ID_FS_UUID"].clone(); - let dev_node = m["DEVNAME"].clone(); - info.insert(dev_node.clone(), vec![fs_uuid.clone()]); - info.entry(fs_uuid).or_insert(vec![]).push(dev_node.clone()); - } - - Ok(info) + .filter(|m| + m.contains_key("ID_FS_UUID") && + m["ID_FS_UUID"] == uuid && + m.contains_key("DEVNAME")) + .map(|m| m["DEVNAME"].clone()) + .collect::>()) } fn get_all_block_devnodes() -> anyhow::Result> { @@ -84,29 +76,7 @@ fn get_all_block_devnodes() -> anyhow::Result> { Ok(devices) } -fn get_devices_by_uuid( - uuid: Uuid, - opts: &bch_opts -) -> anyhow::Result> { - let udev_bcachefs = udev_bcachefs_info()?; - - let devices = { - if !udev_bcachefs.is_empty() { - let uuid_string = uuid.hyphenated().to_string(); - if let Some(devices) = udev_bcachefs.get(&uuid_string) { - devices.clone() - } else { - Vec::new() - } - } else { - get_all_block_devnodes()? - } - }; - - Ok(get_super_blocks(uuid, &devices, opts)) -} - -fn get_super_blocks(uuid: Uuid, devices: &[String], opts: &bch_opts) -> Vec<(PathBuf, bch_sb_handle)> { +fn read_sbs_matching_uuid(uuid: Uuid, devices: &[String], opts: &bch_opts) -> Vec<(PathBuf, bch_sb_handle)> { devices .iter() .filter_map(|dev| { @@ -118,9 +88,26 @@ fn get_super_blocks(uuid: Uuid, devices: &[String], opts: &bch_opts) -> Vec<(Pat .collect::>() } +fn get_devices_by_uuid( + uuid: Uuid, + opts: &bch_opts, + use_udev: bool +) -> anyhow::Result> { + let devs_from_udev = get_devices_by_uuid_udev(uuid)?; + + let devices = if use_udev && !devs_from_udev.is_empty() { + devs_from_udev + } else { + get_all_block_devnodes()? + }; + + Ok(read_sbs_matching_uuid(uuid, &devices, opts)) +} + fn devs_str_sbs_from_device( device: &Path, - opts: &bch_opts + opts: &bch_opts, + use_udev: bool ) -> anyhow::Result> { if let Ok(metadata) = fs::metadata(device) { if metadata.is_dir() { @@ -133,16 +120,12 @@ fn devs_str_sbs_from_device( if dev_sb.sb().number_of_devices() == 1 { Ok(vec![(device.to_path_buf(), dev_sb)]) } else { - get_devices_by_uuid(dev_sb.sb().uuid(), opts) + get_devices_by_uuid(dev_sb.sb().uuid(), opts, use_udev) } } pub fn scan_sbs(device: &String, opts: &bch_opts) -> Result> { - if let Some(("UUID" | "OLD_BLKID_UUID", uuid)) = device.split_once('=') { - let uuid = Uuid::parse_str(uuid)?; - - get_devices_by_uuid(uuid, opts) - } else if device.contains(':') { + if device.contains(':') { let mut opts = *opts; opt_set!(opts, noexcl, 1); opt_set!(opts, no_version_check, 1); @@ -153,14 +136,22 @@ pub fn scan_sbs(device: &String, opts: &bch_opts) -> Result>>() + } + + let udev = !env::var("BCACHEFS_BLOCK_SCAN").is_ok(); + + if let Some(("UUID" | "OLD_BLKID_UUID", uuid)) = device.split_once('=') { + let uuid = Uuid::parse_str(uuid)?; + + get_devices_by_uuid(uuid, opts, udev) } else { - devs_str_sbs_from_device(Path::new(device), opts) + devs_str_sbs_from_device(Path::new(device), opts, udev) } }