From 4fbaf2410a48e8ae640fe356198c5eca21bb87d0 Mon Sep 17 00:00:00 2001 From: "ekko.bao" Date: Thu, 18 Sep 2025 21:26:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=81=9A=E4=B8=80=E8=BD=AE=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=8C=E5=A4=AA=E4=B9=85=E4=BA=86=E5=BF=98=E8=AE=B0=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.json | 0 src/disk/mod.rs | 2 +- src/fs_impl/mod.rs | 0 src/lib.rs | 308 +++++++++++++++++++----------------------- test/pattern/read.txt | 0 5 files changed, 143 insertions(+), 167 deletions(-) mode change 100755 => 100644 config.json mode change 100755 => 100644 src/disk/mod.rs mode change 100755 => 100644 src/fs_impl/mod.rs mode change 100755 => 100644 src/lib.rs mode change 100755 => 100644 test/pattern/read.txt diff --git a/config.json b/config.json old mode 100755 new mode 100644 diff --git a/src/disk/mod.rs b/src/disk/mod.rs old mode 100755 new mode 100644 index a24ecac..ad67b52 --- a/src/disk/mod.rs +++ b/src/disk/mod.rs @@ -34,7 +34,7 @@ pub fn get_disk_info(drive: &str) -> Option<(String, String, u32)> { if success != 0 { let volume_label = gbk2uft8(&volume_name); let file_system_name = gbk2uft8(&file_system_name); - log::info!("Volume Label: {}, file_system: {}, serial_number:{}\n", volume_label, file_system_name, volume_serial_number); + log::debug!("Volume Label: {}, file_system: {}, serial_number:{}\n", volume_label, file_system_name, volume_serial_number); return Some((volume_label, file_system_name, volume_serial_number)); } else { log::debug!("volume {} Failed to get volume information.\n", drive); diff --git a/src/fs_impl/mod.rs b/src/fs_impl/mod.rs old mode 100755 new mode 100644 diff --git a/src/lib.rs b/src/lib.rs old mode 100755 new mode 100644 index 042d5a8..1eb4b23 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,6 +15,8 @@ use tonic::{Request, Response, Status}; use std::collections::HashMap; extern crate log; +use std::path::{Path, PathBuf}; + mod fs_impl; mod disk; pub mod lws_vfs { @@ -61,7 +63,8 @@ impl Config { None => false, Some(_) => true, } - }).map(|(key, value)| (key.to_string(), value.to_string())).collect(); + }).map(|(key, value)| (key.to_string(), value.as_str().unwrap().to_string())).collect(); + log::debug!("mounts is {:?}", mounts); let mut volume_names = HashMap::new(); @@ -73,17 +76,18 @@ impl Config { volume_names.insert(volume, drive); } } - log::info!("local disk: {:?}", volume_names); + log::info!("local disk info: {:?}", volume_names); // 遍历配置的盘符和卷标,将配置的盘符和卷标映射到实际盘符上 for (key, value) in mounts.iter() { // 直接看下是不是盘符 if let Some((drive, _, _)) = disk::get_disk_info(&key) { - mount_map.insert(drive.to_string(), value.to_string()); + mount_map.insert(drive.to_string(), value.as_str().unwrap().to_string()); } else { // 看下是不是卷标 if let Some(drive) = volume_names.get(key.as_str()) { - mount_map.insert(drive.to_string(), value.to_string()); + // log::info!("value is {:?} {}", value, value.as_str().unwrap()); + mount_map.insert(drive.to_string(), value.as_str().unwrap().to_string()); } else { log::error!("mount volume name [{}] not found in disk list", key); return Err(Box::new(std::io::Error::new( @@ -94,6 +98,7 @@ impl Config { } } + log::info!("after local search&match: {:?}", mount_map); Ok(Config { port, mount_map }) } @@ -109,6 +114,15 @@ pub struct LwsVfsIns { pub fs: FSImpl, } +fn linux_to_windows_path(linux_path: &str) -> String { + let path: PathBuf = Path::new(linux_path) + .components() + // .filter(|component| component.as_os_str() != Component::RootDir.as_os_str()) + // .map(|component| component.as_os_str().to_string_lossy().into_owned()) + .collect(); + path.to_string_lossy().to_string() +} + impl LwsVfsIns { pub fn new(json: &str) -> Result> { Ok(LwsVfsIns { @@ -126,11 +140,34 @@ impl LwsVfsIns { break; } } - // log::trace!("path convert ret is {}", ret); - ret + linux_to_windows_path(&ret) } } +/// 将result 转换成 i32返回给rpc使用 +macro_rules! result2ret { + ($fun_name:expr, $path:expr, $ret:expr) => { + match $ret { + Ok(ret) => ret, + Err(e) => { + log::error!("{} [{}]: {:?}", $fun_name, $path, e); + if let Some(e) = e.downcast_ref::() { + e.raw_os_error().unwrap_or(-1) as i32 + } else { + -1 + } + } + } + }; +} + // match e.downcast_ref::() { + // Some(e) => match e.kind() { + // std::io::ErrorKind::NotFound => libc::ENOENT, + // std::io::ErrorKind::PermissionDenied => libc::EACCES, + // std::io::ErrorKind::AlreadyExists => libc::EEXIST, + // } + // } + #[tonic::async_trait] impl LwsVfs for LwsVfsIns { async fn say_hello( @@ -147,6 +184,7 @@ impl LwsVfs for LwsVfsIns { Ok(Response::new(reply)) } async fn get_config(&self, _req: Request) -> Result, Status> { + log::info!("{:?}",self.config); let config = serde_json::to_string(&self.config).unwrap(); log::info!("reply config: {}", config); let reply = GetConfig { @@ -160,13 +198,8 @@ impl LwsVfs for LwsVfsIns { let path = &self.lpath(&request.path); let mut fstat = Fstat::default(); let mut fi = FileInfo::default(); - let ret = match self.fs.fgetattr(path, &mut fstat, &mut fi) { - Ok(ret) => ret, - Err(e) => { - log::error!("Error getting file metadata: {:?}", e); - -1 - } - }; + let ret = self.fs.fgetattr(path, &mut fstat, &mut fi); + let ret = result2ret!("fgetattr", path, ret); let reply = Getattr { path: path.to_string(), stat: Some(fstat), @@ -183,15 +216,8 @@ impl LwsVfs for LwsVfsIns { Some(fi) => fi, None => FileInfo::default(), }; - let ret = match self.fs.fopen(path, &mut fi) { - Ok(_) => { - 0 - } - Err(e) => { - log::error!("Error open file[{}]: {:?}", path, e); - -1 - } - }; + let ret = self.fs.fopen(path, &mut fi); + let ret = result2ret!("fopen", path, ret); let reply = Open { path: path.to_string(), fi: Some(fi), @@ -207,37 +233,26 @@ impl LwsVfs for LwsVfsIns { }; let path = &self.lpath(&request.path); let mut size: usize = request.size as usize; - let offset: usize = request.offset as usize; + let mut offset: usize = request.offset as usize; let mut buff: Vec = Vec::with_capacity(size); unsafe { buff.set_len(size); } log::trace!("Got a request: fread {}, size {} offset {}", path, request.size, offset); - match self.fs.fread(path, &mut buff, &mut size, offset, &mut fi) { - Ok(ret) => { - let reply = Read { - path: request.path, - size: buff.len() as i64, - buff, - offset: offset as u64, - fi: None, - ret, - }; - Ok(Response::new(reply)) - } - Err(e) => { - log::error!("Error reading file[{}]: {:?}", path, e); - let reply = Read { - path: request.path, - buff: Vec::new(), - size: 0, - offset: 0, - fi: None, - ret: -1, - }; - Ok(Response::new(reply)) - } + let ret = self.fs.fread(path, &mut buff, &mut size, offset, &mut fi); + let ret = result2ret!("fread", path, ret); + if ret != 0 { + buff = Vec::new(); + offset = 0; } + Ok(Response::new(Read { + path: request.path, + size: buff.len() as i64, + buff, + offset: offset as u64, + fi: None, + ret, + })) } async fn fwrite(&self, request: Request) -> Result, Status> { @@ -251,13 +266,8 @@ impl LwsVfs for LwsVfsIns { let mut size = request.size as usize; let offset = request.offset as usize; log::trace!("Got a request: Write {}, size {} offset {}", path, request.size, offset); - let ret = match self.fs.fwrite(path, &buff, &mut size, offset, &mut fi) { - Ok(ret) => ret, - Err(e) => { - log::error!("Error fwrite file[{}]: {:?}", path, e); - -1 - } - }; + let ret = self.fs.fwrite(path, &buff, &mut size, offset, &mut fi); + let ret = result2ret!("fwrite", path, ret); let reply = Write { ret, path: path.to_string(), @@ -271,13 +281,8 @@ impl LwsVfs for LwsVfsIns { log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); let mask = request.mask; - let ret = match self.fs.faccess(path, mask) { - Ok(ret) => ret, - Err(e) => { - log::error!("Error access file[{}]: {:?}", path, e); - -1 - } - }; + let ret = self.fs.faccess(path, mask); + let ret = result2ret!("faccess", path, ret); let reply = Access { ret, path: path.to_string(), @@ -294,13 +299,8 @@ impl LwsVfs for LwsVfsIns { let value = request.value; let size = request.size as usize; let flags = request.flags; - let ret = match self.fs.fsetxattr(path, name, &value, size, flags) { - Ok(ret) => ret, - Err(e) => { - log::error!("Error: setxattr file[{}]: {:?}", path, e); - -1 - } - }; + let ret = self.fs.fsetxattr(path, name, &value, size, flags); + let ret = result2ret!("fsetxattr", path, ret); let reply = Setxattr { ret: ret, ..Setxattr::default() @@ -313,13 +313,8 @@ impl LwsVfs for LwsVfsIns { let path = &self.lpath(&request.path); let name = request.name.as_ref(); let size = request.size as usize; - let ret = match self.fs.fgetxattr(path, name, size) { - Ok(ret) => ret, - Err(e) => { - log::error!("Error: getxattr file[{}]: {:?}", path, e); - -1 - } - }; + let ret = self.fs.fgetxattr(path, name, size); + let ret = result2ret!("fgetxattr", path, ret); let reply = Getxattr { ret, ..Getxattr::default() @@ -338,13 +333,8 @@ impl LwsVfs for LwsVfsIns { let offset = request.offset as usize; let mut dirs = vec![]; let size = 0; - let ret = match self.fs.freaddir(path, &mut dirs, size, offset, &mut fi) { - Ok(ret) => ret, - Err(e) => { - log::error!("Error: readdir file[{}]: {:?}", path, e); - -1 - } - }; + let ret = self.fs.freaddir(path, &mut dirs, size, offset, &mut fi); + let ret = result2ret!("freaddir", path, ret); let reply = Readdir { ret, dirs, @@ -357,13 +347,8 @@ impl LwsVfs for LwsVfsIns { log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); let mode = request.mode; - let ret = match self.fs.fmkdir(&path, mode) { - Ok(ret) => ret, - Err(e) => { - log::error!("Error: mkdir [{}]: {:?}", path, e); - -1 - } - }; + let ret = self.fs.fmkdir(&path, mode); + let ret = result2ret!("fmkdir", path, ret); let reply = Mkdir { ret, ..Mkdir::default() @@ -375,13 +360,8 @@ impl LwsVfs for LwsVfsIns { log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); let size = request.size as u64; - let ret = match self.fs.ftruncate(path, size) { - Ok(ret) => ret, - Err(e) => { - log::error!("Error: truncate file[{}]: {:?}", path, e); - -1 - } - }; + let ret = self.fs.ftruncate(path, size); + let ret = result2ret!("ftruncate", path, ret); let reply = Truncate { ret, ..Truncate::default() @@ -395,13 +375,8 @@ impl LwsVfs for LwsVfsIns { let path = &self.lpath(&request.path); let a_time = vec![request.ts[0].tv_sec as u64, request.ts[0].tv_nsec as u64]; let m_time = vec![request.ts[1].tv_sec as u64, request.ts[1].tv_nsec as u64]; - let ret = match self.fs.futimens(path, &a_time, &m_time) { - Ok(ret) => ret, - Err(e) => { - log::error!("Error: futimens file[{}]: {:?}", path, e); - -1 - } - }; + let ret = self.fs.futimens(path, &a_time, &m_time); + let ret = result2ret!("futimens", path, ret); let reply = Utimens { ret, ..Utimens::default() @@ -415,13 +390,8 @@ impl LwsVfs for LwsVfsIns { let path = &self.lpath(&request.path); let uid = request.uid as u32; let gid = request.gid as u32; - let ret = match self.fs.fchown(path, uid, gid) { - Ok(ret) => ret, - Err(e) => { - log::error!("Error: chown file[{}]: {:?}", path, e); - -1 - } - }; + let ret = self.fs.fchown(path, uid, gid); + let ret = result2ret!("fchown", path, ret); let reply = Chown { ret, ..Chown::default() @@ -436,13 +406,8 @@ impl LwsVfs for LwsVfsIns { Some(fi) => fi, None => FileInfo::default(), }; - let ret = match self.fs.frelease(path, &mut fi, request.flush != 0) { - Ok(ret) => ret, - Err(e) => { - log::error!("Error: release file[{}]: {:?}", path, e); - -1 - } - }; + let ret = self.fs.frelease(path, &mut fi, request.flush != 0); + let ret = result2ret!("frelease", path, ret); let reply = Release { ret, ..Release::default() @@ -453,13 +418,8 @@ impl LwsVfs for LwsVfsIns { let request = request.into_inner(); log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); - let ret = match self.fs.frmdir(path) { - Ok(ret) => ret, - Err(e) => { - log::error!("Error: rmdir [{}]: {:?}", path, e); - -1 - } - }; + let ret = self.fs.frmdir(path); + let ret = result2ret!("frmdir", path, ret); let reply = Rmdir { ret, path: request.path, @@ -475,13 +435,8 @@ impl LwsVfs for LwsVfsIns { Some(fi) => fi, None => FileInfo::default(), }; - let ret = match self.fs.fflush(path, &mut fi) { - Ok(ret) => ret, - Err(e) => { - log::error!("Error: flush file[{}]: {:?}", path, e); - -1 - } - }; + let ret = self.fs.fflush(path, &mut fi); + let ret = result2ret!("fflush", path, ret); let reply = Flush { ret, ..Flush::default() @@ -498,13 +453,8 @@ impl LwsVfs for LwsVfsIns { Some(fi) => fi, None => FileInfo::default(), }; - let ret = match self.fs.fcreate(path, mode, &mut fi) { - Ok(ret) => ret, - Err(e) => { - log::error!("Error: create file[{}]: {:?}", path, e); - -1 - } - }; + let ret = self.fs.fcreate(path, mode, &mut fi); + let ret = result2ret!("fcreate", path, ret); let reply = Create { ret, fi:Some(fi), @@ -517,13 +467,8 @@ impl LwsVfs for LwsVfsIns { let request = request.into_inner(); log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); - let ret = match self.fs.funlink(path) { - Ok(ret) => ret, - Err(e) => { - log::error!("Error: unlink file[{}]: {:?}", path, e); - -1 - } - }; + let ret = self.fs.funlink(path); + let ret = result2ret!("funlink", path, ret); let reply = Unlink { ret, path: request.path, @@ -539,13 +484,8 @@ impl LwsVfs for LwsVfsIns { Some(fi) => fi, None => FileInfo::default(), }; - let ret = match self.fs.fopendir(path, &mut fi) { - Ok(ret) => ret, - Err(e) => { - log::error!("Error: opendir dir[{}]: {:?}", path, e); - -1 - } - }; + let ret = self.fs.fopendir(path, &mut fi); + let ret = result2ret!("fopendir", path, ret); let reply = Opendir { ret, fi: Some(fi), @@ -562,13 +502,8 @@ impl LwsVfs for LwsVfsIns { Some(fi) => fi, None => FileInfo::default(), }; - let ret = match self.fs.freleasedir(path, &mut fi) { - Ok(ret) => ret, - Err(e) => { - log::error!("Error: releasedir file[{}]: {:?}", path, e); - -1 - } - }; + let ret = self.fs.freleasedir(path, &mut fi); + let ret = result2ret!("freleasedir", path, ret); let reply = Releasedir { ret, ..Releasedir::default() @@ -581,13 +516,8 @@ impl LwsVfs for LwsVfsIns { log::trace!("Got a request: {:?}", request); let from = &self.lpath(&request.path); let to = &self.lpath(&request.new); - let ret = match self.fs.frename(from, to) { - Ok(ret) => ret, - Err(e) => { - log::error!("Error: rename file[{}]: {:?}", from, e); - -1 - } - }; + let ret = self.fs.frename(from, to); + let ret = result2ret!("frename", from, ret); let reply = Rename { ret, ..Rename::default() @@ -601,4 +531,50 @@ fn test_config_new() { env_logger::init(); let _config = Config::new("config.json").unwrap(); println!("Config: {:#?}", _config); +} + +# [cfg(test)] +mod test_macros { + use std::error::Error; + macro_rules! handle_result { + ($func:expr, $msg:expr) => { + match $func { + Ok(value) => value, + Err(e) => { + eprintln!("错误发生在函数:{},信息:{},错误:{}", stringify!($func), $msg, e); + -1 + } + } + }; + } + + + struct MyStruct; + + impl MyStruct { + fn example_function(&self, _:i32) -> Result> { + // 这里模拟一个可能的错误 + Err("模拟错误".into()) + } + } + + #[test] + fn test_() -> Result<(), Box> { + let my_struct = MyStruct; + + // 使用宏处理返回值 + assert_ne!(handle_result!(my_struct.example_function(32), "调用 example_function 时发生错误"), 32); + Ok(()) + } +} + +# [test] +fn test_path() { + env_logger::init(); + let path = linux_to_windows_path(r"p:\/test/dir/tree"); + assert_eq!(path, r"p:\test\dir\tree"); + let path = linux_to_windows_path(r"p:\/"); + assert_eq!(path, r"p:\"); + let path = linux_to_windows_path(r"p:\"); + assert_eq!(path, r"p:\"); } \ No newline at end of file diff --git a/test/pattern/read.txt b/test/pattern/read.txt old mode 100755 new mode 100644