diff --git a/proto/lws.proto b/proto/lws.proto index 39a804c..20f10b3 100644 --- a/proto/lws.proto +++ b/proto/lws.proto @@ -33,6 +33,12 @@ service LwsVfs { rpc fchown(chown) returns (chown) {} rpc frelease(release) returns (release) {} rpc fmkdir(mkdir) returns (mkdir) {} + rpc frmdir(rmdir) returns (rmdir) {} + rpc fflush(flush) returns (flush) {} + rpc fopendir(opendir) returns (opendir) {} + rpc freleasedir(releasedir) returns (releasedir) {} + rpc fcreate (create) returns (create) {} + rpc funlink(unlink) returns (unlink) {} } // The request message containing the user's name. @@ -161,3 +167,38 @@ message mkdir { uint32 mode = 3; int32 ret = 15; } + +message rmdir { + string path = 1; + int32 ret = 15; +} + +message flush { + string path = 1; + file_info fi = 2; + int32 ret = 15; +} + +message opendir{ + string path = 1; + file_info fi = 2; + int32 ret = 15; +} + +message releasedir{ + string path = 1; + file_info fi = 2; + int32 ret = 15; +} + +message create{ + string path = 1; + uint32 mode = 2; + file_info fi = 3; + int32 ret = 15; +} + +message unlink{ + string path = 1; + int32 ret = 15; +} \ No newline at end of file diff --git a/src/fs_impl/mod.rs b/src/fs_impl/mod.rs index c401d3f..95d50a2 100644 --- a/src/fs_impl/mod.rs +++ b/src/fs_impl/mod.rs @@ -1,13 +1,14 @@ use std::fs; use std::error::Error; -use std::io::{self, Seek as ioSeek}; +use std::io::{self, ErrorKind, Seek as ioSeek, SeekFrom}; use crate::lws_vfs::{FileInfo, Fstat}; +use std::sync::{Arc, Mutex}; +use std::collections::HashMap; + extern crate winapi; -use fs::remove_file; -use io::Write; use std::os::windows::fs::MetadataExt; use std::os::windows::prelude::*; use winapi::um::winnt::FILE_ATTRIBUTE_READONLY; @@ -22,7 +23,56 @@ fn from_metadata(sta: &mut Fstat, metadata: &fs::Metadata) -> Result<(), Box Result> { + + +#[derive(Debug, Default)] +struct FileFdMgnt { + // key is fd, value is FileHandle + files: HashMap, + curr_fd: u64, +} + +impl FileFdMgnt { + pub fn new() -> FileFdMgnt { + FileFdMgnt { + curr_fd: 3, + files: HashMap::new(), + } + } + fn gen_fd(&mut self) -> Result> { + let refd = self.curr_fd; + loop { + self.curr_fd += 1; + match self.files.get(&self.curr_fd) { + Some(_) => {} + None => { + break; + } + } + if refd == self.curr_fd { + return Err(Box::new(std::io::Error::new( + std::io::ErrorKind::Other, + "no fd", + ))); + } + } + Ok(self.curr_fd) + } + pub fn push(&mut self, handle: File) -> Result> { + let fd = self.gen_fd()?; + self.files.insert(fd, handle); + Ok(fd) + } + pub fn pop(&mut self, fd: u64) -> Option { + self.files.remove(&fd) + } +} +pub struct FSImpl{ + file_fds: Arc>, +} + +impl FSImpl { +pub fn fgetattr(&self, path: &String, sta: &mut Fstat, _fi: &mut FileInfo) -> Result> { let metadata = fs::metadata(path)?; from_metadata(sta, &metadata)?; let perm = get_file_mode_mask(path); @@ -30,12 +80,12 @@ pub fn fgetattr(path: &String, sta: &mut Fstat, _fi: &mut FileInfo) -> Result Result> { +pub fn fopen(&self, path: &String, _fi: &mut FileInfo) -> Result> { return Ok(fs::File::open(path)?); } pub fn fread( - path: &String, + &self, path: &String, buffer: &mut Vec, _size: &mut usize, offsize: usize, @@ -44,7 +94,11 @@ pub fn fread( let mut file = fs::File::open(path)?; match file.seek_read(buffer, offsize as u64) { Ok(size) => { - println!("size is:{}, buffer is {}", size, String::from_utf8(buffer.to_vec()).unwrap()); + println!( + "size is:{}, buffer is {}", + size, + String::from_utf8(buffer.to_vec()).unwrap() + ); buffer.resize(size, 0) } Err(_) => { @@ -54,9 +108,14 @@ pub fn fread( Ok(0) } -pub fn fwrite(path: &String, buffer: &Vec, size: &mut usize, offsize: usize, _fi: &mut FileInfo, +pub fn fwrite( + &self, path: &String, + buffer: &Vec, + size: &mut usize, + offsize: usize, + _fi: &mut FileInfo, ) -> Result> { - let mut file = fs::File::options().write(true).create(true).open(path)?; + let mut file = fs::File::options().write(true).create(true).open(path)?; match file.seek_write(buffer, offsize as u64) { Ok(written) => { *size = written as usize; @@ -68,7 +127,7 @@ pub fn fwrite(path: &String, buffer: &Vec, size: &mut usize, offsize: usize, Ok(0) } pub fn freaddir( - path: &String, + &self, path: &String, buffer: &mut Vec, _size: usize, _offset: usize, @@ -91,37 +150,37 @@ pub fn freaddir( } Ok(0) } -pub fn fmkdir(path: &String, _mode: u32) -> Result> { +pub fn fmkdir(&self, path: &String, _mode: u32) -> Result> { fs::create_dir(path)?; Ok(0) } -pub fn fchown(_path: &String, _uid: u32, _gid: u32) -> Result> { +pub fn fchown(&self, _path: &String, _uid: u32, _gid: u32) -> Result> { Ok(-1) } -pub fn ftruncate(path: &String, _size: usize) -> Result> { - fs::OpenOptions::new() - .write(true) +pub fn ftruncate(&self, path: &String, size: u64) -> Result> { + let mut file = fs::File::options().write(true) .truncate(true) .open(path)?; + file.seek(SeekFrom::Start(size))?; + file.set_len(size)?; Ok(0) } -use std::fs::OpenOptions; -use std::ptr::null_mut; -use winapi::ctypes::c_void; -use winapi::shared::minwindef::DWORD; -use winapi::shared::minwindef::FILETIME; -use winapi::um::fileapi::SetFileTime; -fn system_time_to_file_time(seconds: u64, nanoseconds: u32) -> FILETIME { - let total_nanoseconds = (seconds * 1_000_000_000) + nanoseconds as u64; - let total_100_nanoseconds = total_nanoseconds / 100; - FILETIME { - dwLowDateTime: total_100_nanoseconds as DWORD, - dwHighDateTime: (total_100_nanoseconds >> 32) as DWORD, +pub fn futimens(&self, path: &String, a: &Vec, m: &Vec) -> Result> { + use std::ptr::null_mut; + use winapi::ctypes::c_void; + use winapi::shared::minwindef::DWORD; + use winapi::shared::minwindef::FILETIME; + use winapi::um::fileapi::SetFileTime; + fn system_time_to_file_time(seconds: u64, nanoseconds: u32) -> FILETIME { + let total_nanoseconds = (seconds * 1_000_000_000) + nanoseconds as u64; + let total_100_nanoseconds = total_nanoseconds / 100; + FILETIME { + dwLowDateTime: total_100_nanoseconds as DWORD, + dwHighDateTime: (total_100_nanoseconds >> 32) as DWORD, + } } -} -pub fn futimens(path: &String, a: &Vec, m: &Vec) -> Result> { - let file = OpenOptions::new().write(true).open(path)?; + let file = fs::File::options().write(true).open(path)?; let handle = file.as_raw_handle(); let atime = system_time_to_file_time(a[0], a[1] as u32); @@ -135,11 +194,16 @@ pub fn futimens(path: &String, a: &Vec, m: &Vec) -> Result Result> { - Ok(0) +pub fn frelease(&self, _path: &String, _fi: &mut FileInfo) -> Result> { + if let Some(fh) == self.file_fds.lock().unwrap().pop(fi.fh){ + drop(fh); + Ok(0) + } else { + Ok(-1) + } } pub fn fsetxattr( - _path: &String, + &self, _path: &String, _name: &str, _value: &Vec, _size: usize, @@ -147,7 +211,7 @@ pub fn fsetxattr( ) -> Result> { Ok(-1) } -pub fn fgetxattr(_path: &String, _name: &str, _size: usize) -> Result> { +pub fn fgetxattr(&self, _path: &String, _name: &str, _size: usize) -> Result> { Ok(-1) } @@ -172,16 +236,26 @@ fn get_file_mode_mask(path: &str) -> u32 { } permissions } -pub fn faccess(path: &String, mask: u32) -> Result> { +pub fn faccess(&self, path: &String, mask: u32) -> Result> { let permissions = get_file_mode_mask(path); Ok(if permissions & mask != 0 { 0 } else { -1 }) } +pub fn frmdir(&self, path: &String) -> Result> { + fs::remove_dir(path)?; + Ok(0) +} +} + #[test] fn test_fread() { use crate::fs_impl::*; let path = String::from("test_fread.txt"); - let file: fs::File = fs::File::options().write(true).create(true).open(&path).unwrap(); + let file: fs::File = fs::File::options() + .write(true) + .create(true) + .open(&path) + .unwrap(); let ref_buffer = b"This is a test file."; let _ = file.seek_write(ref_buffer, 0); @@ -244,26 +318,48 @@ fn test_fwrite() { // cleanup //let _ = fs::remove_file(path); } - // let result = fwrite(&path, &buffer, &mut size, offsize, &mut fi); - // println!("result: {:?}", result); - // println!("size: {:?}", size); - // println!("buffer: {:?}", buffer); - // let result = freaddir(&path, &mut vec![], 0, 0, &mut fi); - // println!("result: {:?}", result); - // println!("buffer: {:?}", buffer); - // let result = fmkdir(&path, 0); - // println!("result: {:?}", result); - // let result = fchown(&path, 0, 0); - // println!("result: {:?}", result); - // let result = ftruncate(&path, 100); - // println!("result: {:?}", result); - // let result = futimens(&path, &vec![100, 0], &vec![100, 0]); - // println!("result: {:?}", result); - // let result = frelease(&path, &mut fi); - // println!("result: {:?}", result); - // let result = fsetxattr(&path, "test", &vec![1,2,3], 3, 0); - // println!("result: {:?}", result); - // let result = fgetxattr(&path, "test", 100); - // println!("result: {:?}", result); - // let result = faccess(&path, 0o777); - // println!("result: {:?}", result); +#[test] +fn test_dir() { + use std::path::Path; + let path = String::from("test_dir"); + let sub_path = String::from("test_dir/test_sub_dir"); + //创建父目录 + let _ = fmkdir(&path, 0); + //创建子目录 + let _ = fmkdir(&sub_path, 0); + assert_eq!(true, Path::new(&sub_path).is_dir()); + assert_eq!(true, Path::new(&path).is_dir()); + //一次性创建多级目录 + let ret = fmkdir(&String::from("patent/child"), 0); + assert_ne!( + match ret { + Ok(ret) => ret, + Err(_) => -1, + }, + 0 + ); + fs::remove_dir_all(path); +} +// let result = fwrite(&path, &buffer, &mut size, offsize, &mut fi); +// println!("result: {:?}", result); +// println!("size: {:?}", size); +// println!("buffer: {:?}", buffer); +// let result = freaddir(&path, &mut vec![], 0, 0, &mut fi); +// println!("result: {:?}", result); +// println!("buffer: {:?}", buffer); +// let result = fmkdir(&path, 0); +// println!("result: {:?}", result); +// let result = fchown(&path, 0, 0); +// println!("result: {:?}", result); +// let result = ftruncate(&path, 100); +// println!("result: {:?}", result); +// let result = futimens(&path, &vec![100, 0], &vec![100, 0]); +// println!("result: {:?}", result); +// let result = frelease(&path, &mut fi); +// println!("result: {:?}", result); +// let result = fsetxattr(&path, "test", &vec![1,2,3], 3, 0); +// println!("result: {:?}", result); +// let result = fgetxattr(&path, "test", 100); +// println!("result: {:?}", result); +// let result = faccess(&path, 0o777); +// println!("result: {:?}", result); diff --git a/src/lib.rs b/src/lib.rs index 534b2d9..a815016 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,13 @@ use lws_vfs::lws_vfs_server::LwsVfs; -use lws_vfs::{HelloReply, HelloRequest, Getattr, Setxattr, Access, Readdir, Read, Open,Write,Getxattr,Truncate,Utimens,Chown, Release, Fstat, FileInfo, Mkdir}; -use tonic::{Request, Response, Status}; +use lws_vfs::{ + Access, Chown, FileInfo, Flush, Fstat, Getattr, Getxattr, HelloReply, HelloRequest, Mkdir, + Open, Read, Readdir, Release, Rmdir, Setxattr, Truncate, Utimens, Write, Flush, +}; use serde_json::{self, Value}; +use std::error::Error; use std::fs::File; use std::io::{BufReader, Read as _}; -use std::error::Error; -use std::collections::HashMap; -use std::sync::{Arc,Mutex}; +use tonic::{Request, Response, Status}; mod fs_impl; pub mod lws_vfs { tonic::include_proto!("lws_vfs"); @@ -24,35 +25,39 @@ pub mod lws_vfs { // } // #[derive(Debug, Default)] -pub struct Config{ - port:u16, - mount_map:HashMap, +pub struct Config { + port: u16, + mount_map: HashMap, } -impl Config{ - pub fn new(json:&str) -> Result> { +impl Config { + pub fn new(json: &str) -> Result> { let mut file = File::open(json)?; let mut buffer = String::new(); file.read_to_string(&mut buffer)?; - let json:Value = serde_json::from_str(buffer.as_ref())?; - let port:u16 = match json.get("port"){ + let json: Value = serde_json::from_str(buffer.as_ref())?; + let port: u16 = match json.get("port") { Some(port) => port.as_u64().expect("expect port is a number but its not") as u16, - None => { - 5001 - } + None => 5001, }; - let mounts = match json.get("mount"){ + let mounts = match json.get("mount") { Some(mounts) => mounts.as_object().unwrap(), None => { - return Err(Box::new(std::io::Error::new(std::io::ErrorKind::Other, "no mount map"))) + return Err(Box::new(std::io::Error::new( + std::io::ErrorKind::Other, + "no mount map", + ))) } }; - let mount_map = mounts.iter().map(|(key,value)|{ - (key.as_str().to_string(),value.as_str().unwrap().to_string()) - }).collect(); - Ok(Config{ - port, - mount_map - }) + let mount_map = mounts + .iter() + .map(|(key, value)| { + ( + key.as_str().to_string(), + value.as_str().unwrap().to_string(), + ) + }) + .collect(); + Ok(Config { port, mount_map }) } pub fn get_port(&self) -> u16 { @@ -60,51 +65,6 @@ impl Config{ } } -#[derive(Debug, Default)] -struct FileFdMgnt { - // key is fd, value is FileHandle - files:HashMap, - curr_fd:u64, -} - -impl FileFdMgnt { - pub fn new() -> FileFdMgnt { - FileFdMgnt{ - curr_fd:3, - files:HashMap::new() - } - } - fn gen_fd(&mut self) -> Result> { - let refd = self.curr_fd; - loop{ - self.curr_fd += 1; - match self.files.get(&self.curr_fd){ - Some(_) => {} - None => { - break; - } - } - if refd == self.curr_fd { - return Err(Box::new(std::io::Error::new(std::io::ErrorKind::Other, "no fd"))) - } - } - Ok(self.curr_fd) - } - pub fn push(&mut self, handle:File) -> Result> { - let fd = self.gen_fd()?; - self.files.insert(fd, handle); - Ok(fd) - } - pub fn pop(&mut self, fd:u64){ - if let Some(handle) = self.files.remove(&fd){ - drop(handle); - } - else{ - println!("not found fd:{}", fd); - } - } -} - /// server 的基础结构 #[derive(Debug, Default)] pub struct LwsVfsIns { @@ -113,16 +73,16 @@ pub struct LwsVfsIns { } impl LwsVfsIns { - pub fn new(json:&str) -> Result> { - Ok(LwsVfsIns{ - config:Config::new(json)?, - file_fds:Arc::new(Mutex::new(FileFdMgnt::new())), + pub fn new(json: &str) -> Result> { + Ok(LwsVfsIns { + config: Config::new(json)?, + file_fds: Arc::new(Mutex::new(FileFdMgnt::new())), }) } - fn lpath(&self, path:&String) -> String { + fn lpath(&self, path: &String) -> String { let mut ret = String::new(); - for (k,v) in &self.config.mount_map{ - if path.starts_with(v){ + for (k, v) in &self.config.mount_map { + if path.starts_with(v) { ret = path.replace(v, k); break; } @@ -133,7 +93,10 @@ impl LwsVfsIns { #[tonic::async_trait] impl LwsVfs for LwsVfsIns { - async fn say_hello(&self, request: Request) -> Result, Status> { + async fn say_hello( + &self, + request: Request, + ) -> Result, Status> { println!("Got a request: {:?}", request); let reply = HelloReply { @@ -146,10 +109,10 @@ impl LwsVfs for LwsVfsIns { println!("Got a request: {:?}", request); let request = request.into_inner(); - let path = &self.lpath(&request.path); + let path = &self.lpath(&request.path); let mut fstat = Fstat::default(); let mut fi = FileInfo::default(); - let ret = match fs_impl::fgetattr(path, & mut fstat, &mut fi){ + let ret = match fs_impl::fgetattr(path, &mut fstat, &mut fi) { Ok(ret) => ret, Err(e) => { println!("Error getting file metadata: {:?}", e); @@ -157,8 +120,8 @@ impl LwsVfs for LwsVfsIns { } }; let reply = Getattr { - path:path.to_string(), - stat:Some(fstat), + path: path.to_string(), + stat: Some(fstat), ret, }; Ok(Response::new(reply)) @@ -166,11 +129,11 @@ impl LwsVfs for LwsVfsIns { async fn fopen(&self, request: Request) -> Result, Status> { println!("Got a request: {:?}", request); let request = request.into_inner(); - let path = &self.lpath(&request.path); - let mut fi =request.fi.unwrap(); - let ret = match fs_impl::fopen(path, &mut fi){ + let path = &self.lpath(&request.path); + let mut fi = request.fi.unwrap(); + let ret = match fs_impl::fopen(path, &mut fi) { Ok(file) => { - match self.file_fds.lock().unwrap().push(file){ + match self.file_fds.lock().unwrap().push(file) { Ok(fd) => fi.fh = fd, Err(e) => { println!("Error pushing file[{}]: {:?}", path, e); @@ -185,7 +148,7 @@ impl LwsVfs for LwsVfsIns { }; let reply = Open { path: path.to_string(), - fi:Some(fi), + fi: Some(fi), ret, }; Ok(Response::new(reply)) @@ -193,13 +156,15 @@ impl LwsVfs for LwsVfsIns { async fn fread(&self, request: Request) -> Result, Status> { println!("Got a request: {:?}", request); let request = request.into_inner(); - let mut fi = request.fi.unwrap(); - let path = &self.lpath(&request.path); - let mut size:usize = request.size.try_into().unwrap(); - let offset:usize = request.offset.try_into().unwrap(); - let mut buff: Vec = Vec::with_capacity(size); - unsafe { buff.set_len(size); } - match fs_impl::fread(path, &mut buff, &mut size, offset, &mut fi){ + let mut fi = request.fi.unwrap(); + let path = &self.lpath(&request.path); + let mut size: usize = request.size.try_into().unwrap(); + let offset: usize = request.offset.try_into().unwrap(); + let mut buff: Vec = Vec::with_capacity(size); + unsafe { + buff.set_len(size); + } + match fs_impl::fread(path, &mut buff, &mut size, offset, &mut fi) { Ok(ret) => { let reply = Read { path: request.path, @@ -210,7 +175,7 @@ impl LwsVfs for LwsVfsIns { ret, }; Ok(Response::new(reply)) - }, + } Err(e) => { println!("Error reading file[{}]: {:?}", path, e); let reply = Read { @@ -227,15 +192,13 @@ impl LwsVfs for LwsVfsIns { } async fn fwrite(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - let mut fi = request.fi.unwrap(); - let path = &self.lpath(&request.path); + let mut fi = request.fi.unwrap(); + let path = &self.lpath(&request.path); let buff = request.buff; let mut size = request.size as usize; let offset = request.offset as usize; let ret = match fs_impl::fwrite(path, &buff, &mut size, offset, &mut fi) { - Ok(ret) => { - ret - }, + Ok(ret) => ret, Err(e) => { println!("Error fwrite file[{}]: {:?}", path, e); -1 @@ -243,20 +206,17 @@ impl LwsVfs for LwsVfsIns { }; let reply = Write { ret, - size:size as i64, + size: size as i64, ..Default::default() }; Ok(Response::new(reply)) - } - async fn faccess( &self, request: Request,) -> Result, Status> { + async fn faccess(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - let path = &self.lpath(&request.path); + let path = &self.lpath(&request.path); let mask = request.mask; let ret = match fs_impl::faccess(path, mask) { - Ok(ret) => { - ret - }, + Ok(ret) => ret, Err(e) => { println!("Error access file[{}]: {:?}", path, e); -1 @@ -264,7 +224,7 @@ impl LwsVfs for LwsVfsIns { }; let reply = Access { ret, - path:path.to_string(), + path: path.to_string(), mask, }; Ok(Response::new(reply)) @@ -282,9 +242,9 @@ impl LwsVfs for LwsVfsIns { Err(e) => { println!("Error: setxattr file[{}]: {:?}", path, e); -1 - }, + } }; - let reply = Setxattr{ + let reply = Setxattr { ret: ret, ..Setxattr::default() }; @@ -302,16 +262,16 @@ impl LwsVfs for LwsVfsIns { -1 } }; - let reply = Getxattr{ + let reply = Getxattr { ret, ..Getxattr::default() - }; + }; Ok(Response::new(reply)) } async fn freaddir(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - let mut fi = request.fi.unwrap(); + let mut fi = request.fi.unwrap(); let path = &self.lpath(&request.path); let offset = request.offset as usize; let mut dirs: Vec = Vec::new(); @@ -323,7 +283,7 @@ impl LwsVfs for LwsVfsIns { -1 } }; - let reply = Readdir{ + let reply = Readdir { ret, dirs, ..Readdir::default() @@ -341,16 +301,16 @@ impl LwsVfs for LwsVfsIns { -1 } }; - let reply = Mkdir{ + let reply = Mkdir { ret, ..Mkdir::default() }; Ok(Response::new(reply)) } async fn ftruncate(&self, request: Request) -> Result, Status> { - let request= request.into_inner(); + let request = request.into_inner(); let path = &self.lpath(&request.path); - let size = request.size as usize; + let size = request.size as u64; let ret = match fs_impl::ftruncate(path, size) { Ok(ret) => ret, Err(e) => { @@ -358,10 +318,10 @@ impl LwsVfs for LwsVfsIns { -1 } }; - let reply = Truncate{ + let reply = Truncate { ret, ..Truncate::default() - }; + }; Ok(Response::new(reply)) } @@ -369,7 +329,7 @@ impl LwsVfs for LwsVfsIns { let request = request.into_inner(); 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 m_time = vec![request.ts[1].tv_sec as u64, request.ts[1].tv_nsec as u64]; let ret = match fs_impl::futimens(path, &a_time, &m_time) { Ok(ret) => ret, Err(e) => { @@ -377,7 +337,7 @@ impl LwsVfs for LwsVfsIns { -1 } }; - let reply = Utimens{ + let reply = Utimens { ret, ..Utimens::default() }; @@ -396,7 +356,7 @@ impl LwsVfs for LwsVfsIns { -1 } }; - let reply = Chown{ + let reply = Chown { ret, ..Chown::default() }; @@ -405,19 +365,42 @@ impl LwsVfs for LwsVfsIns { async fn frelease(&self, request: Request) -> Result, Status> { let request = request.into_inner(); let path = &self.lpath(&request.path); - let mut fi = request.fi.unwrap(); + let mut fi = request.fi.unwrap(); self.file_fds.lock().unwrap().pop(fi.fh); let ret = match fs_impl::frelease(path, &mut fi) { Ok(ret) => ret, Err(e) => { println!("Error: release file[{}]: {:?}", path, e); -1 - } + } }; - let reply = Release{ + let reply = Release { ret, ..Release::default() - }; + }; Ok(Response::new(reply)) } + async fn frmdir(&self, request: Request) -> Result, Status> { + let request = request.into_inner(); + let path = &self.lpath(&request.path); + let ret = match fs_impl::frmdir(path) { + Ok(ret) => ret, + Err(e) => { + println!("Error: rmdir [{}]: {:?}", path, e); + -1 + } + }; + let reply = Rmdir { + ret, + path: request.path, + }; + Ok(Response::new(reply)) + } + + async fn fflush(&self, request: Request) -> Result, Status> { + let request = request.into_inner(); + let path = &self.lpath(&request.path); + let mut fi = request.fi.unwrap(); + self.file_fds.lock().unwrap().pop(fi.fh); + } }