From c98e63af874e4a69435f7d299b708208c5d9bea0 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Fri, 11 Feb 2022 10:07:40 -0700 Subject: [PATCH] Improve speed by not enumerating all disks when opening by UUID --- src/bin/mount.rs | 171 +++++++++++++++++++++++------------------------ 1 file changed, 82 insertions(+), 89 deletions(-) diff --git a/src/bin/mount.rs b/src/bin/mount.rs index bc75c68..3212e6b 100644 --- a/src/bin/mount.rs +++ b/src/bin/mount.rs @@ -15,7 +15,7 @@ use std::io::{Read, Write}; use std::os::unix::io::{FromRawFd, RawFd}; use std::process; -use redoxfs::{mount, DiskCache, DiskFile}; +use redoxfs::{mount, DiskCache, DiskFile, FileSystem}; use uuid::Uuid; #[cfg(target_os = "redox")] @@ -85,14 +85,37 @@ enum DiskId { Uuid(Uuid), } +fn filesystem_by_path(path: &str, block_opt: Option<u64>) -> Option<(String, FileSystem<DiskCache<DiskFile>>)> { + println!("redoxfs: opening {}", path); + match DiskFile::open(&path).map(|image| DiskCache::new(image)) { + Ok(disk) => match redoxfs::FileSystem::open(disk, block_opt) { + Ok(filesystem) => { + println!( + "redoxfs: opened filesystem on {} with uuid {}", + path, + Uuid::from_bytes(&filesystem.header.1.uuid) + .unwrap() + .hyphenated() + ); + + return Some((path.to_string(), filesystem)); + } + Err(err) => println!("redoxfs: failed to open filesystem {}: {}", path, err), + }, + Err(err) => println!("redoxfs: failed to open image {}: {}", path, err), + } + None +} + #[cfg(not(target_os = "redox"))] -fn disk_paths(_paths: &mut Vec<String>) {} +fn filesystem_by_uuid(_uuid: &Uuid, _block_opt: Option<u64>) -> Option<(String, FileSystem<DiskCache<DiskFile>>)> { + None +} #[cfg(target_os = "redox")] -fn disk_paths(paths: &mut Vec<String>) { +fn filesystem_by_uuid(uuid: &Uuid, block_opt: Option<u64>) -> Option<(String, FileSystem<DiskCache<DiskFile>>)> { use std::fs; - let mut schemes = vec![]; match fs::read_dir(":") { Ok(entries) => { for entry_res in entries { @@ -101,7 +124,36 @@ fn disk_paths(paths: &mut Vec<String>) { let scheme = path.trim_start_matches(':').trim_matches('/'); if scheme.starts_with("disk") { println!("redoxfs: found scheme {}", scheme); - schemes.push(format!("{}:", scheme)); + match fs::read_dir(&format!("{}:", scheme)) { + Ok(entries) => { + for entry_res in entries { + if let Ok(entry) = entry_res { + if let Ok(path) = entry.path().into_os_string().into_string() { + println!("redoxfs: found path {}", path); + if let Some((path, filesystem)) = filesystem_by_path(&path, block_opt) { + if &filesystem.header.1.uuid == uuid.as_bytes() { + println!( + "redoxfs: filesystem on {} matches uuid {}", + path, + uuid.hyphenated() + ); + return Some((path, filesystem)) + } else { + println!( + "redoxfs: filesystem on {} does not match uuid {}", + path, + uuid.hyphenated() + ); + } + } + } + } + } + } + Err(err) => { + println!("redoxfs: failed to list '{}': {}", scheme, err); + } + } } } } @@ -112,100 +164,41 @@ fn disk_paths(paths: &mut Vec<String>) { } } - for scheme in schemes { - match fs::read_dir(&scheme) { - Ok(entries) => { - for entry_res in entries { - if let Ok(entry) = entry_res { - if let Ok(path) = entry.path().into_os_string().into_string() { - println!("redoxfs: found path {}", path); - paths.push(path); - } - } - } - } - Err(err) => { - println!("redoxfs: failed to list '{}': {}", scheme, err); - } - } - } + None } fn daemon(disk_id: &DiskId, mountpoint: &str, block_opt: Option<u64>, mut write: File) -> ! { setsig(); - let mut paths = vec![]; - let mut uuid_opt = None; - - match *disk_id { + let filesystem_opt = match *disk_id { DiskId::Path(ref path) => { - paths.push(path.clone()); + filesystem_by_path(path, block_opt) } DiskId::Uuid(ref uuid) => { - disk_paths(&mut paths); - uuid_opt = Some(uuid.clone()); + filesystem_by_uuid(uuid, block_opt) } - } + }; - for path in paths { - println!("redoxfs: opening {}", path); - match DiskFile::open(&path).map(|image| DiskCache::new(image)) { - Ok(disk) => match redoxfs::FileSystem::open(disk, block_opt) { - Ok(filesystem) => { - println!( - "redoxfs: opened filesystem on {} with uuid {}", - path, - Uuid::from_bytes(&filesystem.header.1.uuid) - .unwrap() - .hyphenated() - ); - - let matches = if let Some(uuid) = uuid_opt { - if &filesystem.header.1.uuid == uuid.as_bytes() { - println!( - "redoxfs: filesystem on {} matches uuid {}", - path, - uuid.hyphenated() - ); - true - } else { - println!( - "redoxfs: filesystem on {} does not match uuid {}", - path, - uuid.hyphenated() - ); - false - } - } else { - true - }; - - if matches { - match mount(filesystem, &mountpoint, |mounted_path| { - capability_mode(); - - println!( - "redoxfs: mounted filesystem on {} to {}", - path, - mounted_path.display() - ); - let _ = write.write(&[0]); - }) { - Ok(()) => { - process::exit(0); - } - Err(err) => { - println!( - "redoxfs: failed to mount {} to {}: {}", - path, mountpoint, err - ); - } - } - } - } - Err(err) => println!("redoxfs: failed to open filesystem {}: {}", path, err), - }, - Err(err) => println!("redoxfs: failed to open image {}: {}", path, err), + if let Some((path, filesystem)) = filesystem_opt { + match mount(filesystem, &mountpoint, |mounted_path| { + capability_mode(); + + println!( + "redoxfs: mounted filesystem on {} to {}", + path, + mounted_path.display() + ); + let _ = write.write(&[0]); + }) { + Ok(()) => { + process::exit(0); + } + Err(err) => { + println!( + "redoxfs: failed to mount {} to {}: {}", + path, mountpoint, err + ); + } } } -- GitLab