diff --git a/Cargo.lock b/Cargo.lock index 22199e4..3e2561b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -433,6 +433,7 @@ checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" name = "lws_vfs" version = "0.1.0" dependencies = [ + "libc", "prost", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index 9adbd63..b9c97a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ winapi = { version = "0.3", features = [ windows = "0.28" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +libc = "0.2" [build-dependencies] tonic-build = "0.11" diff --git a/config.json b/config.json new file mode 100755 index 0000000..bf50163 --- /dev/null +++ b/config.json @@ -0,0 +1,9 @@ +{ + "mount": { + "c:\\": "/l3c", + "d:\\": "/l0d", + "f:\\": "/l0e" + }, + "port":7412, + "addr":"192.168.0.110" +} diff --git a/proto/lws.proto b/proto/lws.proto index ef8942b..0181575 100644 --- a/proto/lws.proto +++ b/proto/lws.proto @@ -49,7 +49,7 @@ message HelloRequest { string name = 1; } message HelloReply { string message = 1; } message file_info { - int32 flags = 1; + uint32 flags = 1; uint32 fh_old = 2; bool direct_io = 3; uint64 fh = 10; @@ -76,6 +76,7 @@ message fstat { message getattr { string path = 1; fstat stat = 2; + file_info fi = 3; int32 ret = 15; } @@ -101,9 +102,14 @@ message access { int32 ret = 15; } +message direntry { + string name = 1; + uint32 kind = 2; +} + message readdir { string path = 1; - repeated string dirs = 2; + repeated direntry dirs = 2; uint32 offset = 3; file_info fi = 4; int32 ret = 15; @@ -119,7 +125,7 @@ message read { string path = 1; bytes buff = 2; int64 size = 3; - int64 offset = 4; + uint64 offset = 4; file_info fi = 5; int32 ret = 15; } @@ -127,8 +133,8 @@ message read { message write { string path = 1; bytes buff = 2; - int64 size = 3; - int64 offset = 4; + uint64 size = 3; + uint64 offset = 4; file_info fi = 5; int32 ret = 15; } @@ -159,6 +165,7 @@ message chown { message release { string path = 1; file_info fi = 2; + uint32 flush = 3; int32 ret = 15; } diff --git a/src/fs_impl/mod.rs b/src/fs_impl/mod.rs index 3d3c125..36747d5 100755 --- a/src/fs_impl/mod.rs +++ b/src/fs_impl/mod.rs @@ -1,17 +1,18 @@ -use std::fs::{self, File, ReadDir}; +use std::fs::{self, File, ReadDir, FileType}; use std::error::Error; use std::io::{self, Seek as ioSeek, SeekFrom, Write}; -use crate::lws_vfs::{FileInfo, Fstat}; +use crate::lws_vfs::{FileInfo, Fstat, Direntry}; use std::sync::{Arc, Mutex}; use std::collections::HashMap; extern crate winapi; -use std::os::windows::fs::MetadataExt; +use std::os::windows::fs::{MetadataExt}; use std::os::windows::prelude::*; use winapi::um::winnt::FILE_ATTRIBUTE_READONLY; +use libc; fn from_metadata(sta: &mut Fstat, metadata: &fs::Metadata) -> Result<(), Box> { sta.fst_size = metadata.len(); @@ -126,7 +127,9 @@ impl FSImpl { } pub fn fopen(&self, path: &String, fi: &mut FileInfo) -> Result> { - let f = fs::File::open(path)?; + let f = File::options() + .read(fi.flags & libc::O_RDONLY as u32 != 0) + .write(fi.flags & libc::O_WRONLY as u32 != 0).open(path)?; let fd = self.file_fds.lock().unwrap().push(FileHandle::FILE(f))?; fi.fh = fd; return Ok(0); @@ -212,15 +215,26 @@ impl FSImpl { * * Introduced in version 2.3 */ - pub fn freaddir(&self, path: &String, buffer: &mut Vec, _size: usize, _offset: usize, fi: &mut FileInfo, + pub fn freaddir(&self, path: &String, buffer: &mut Vec, _size: usize, _offset: usize, fi: &mut FileInfo, ) -> Result> { + fn file_type(t: FileType) -> u32{ + if t.is_dir() { + return 1; + } + if t.is_symlink() { + return 2; + } + return 0; + } let mut fh = self.file_fds.lock().unwrap(); let mut collect = move |entry:&mut ReadDir| -> Result> { loop { match entry.next() { Some(Ok(entry)) => { - let name = entry.file_name().into_string().unwrap(); - buffer.push(name); + buffer.push(Direntry { + name: entry.file_name().into_string().unwrap(), + kind: file_type(entry.file_type().unwrap()), + }); } Some(Err(e)) => { return Err(Box::new(e)); @@ -289,8 +303,11 @@ impl FSImpl { Err(Box::new(io::Error::last_os_error())) } } - pub fn frelease(&self, _path: &String, fi: &mut FileInfo) -> Result> { + pub fn frelease(&self, path: &String, fi: &mut FileInfo, flush:bool) -> Result> { if let Some(fh) = self.file_fds.lock().unwrap().pop(fi.fh) { + if flush { + let _unused = self.fflush(path, fi); + } drop(fh); Ok(0) } else { @@ -626,9 +643,9 @@ fn test_read_a_file_flow() { assert_eq!(get_ret(ret), 0); assert_eq!(buffer, Vec::from("abcde")); - let ret = fs.frelease(&path, &mut fi[0]); + let ret = fs.frelease(&path, &mut fi[0], false); assert_eq!(get_ret(ret), 0); - let ret = fs.frelease(&path, &mut fi[1]); + let ret = fs.frelease(&path, &mut fi[1], false); assert_eq!(get_ret(ret), 0); } @@ -638,7 +655,7 @@ fn test_read_a_dir_flow() { let path = String::from("./src"); let fs = FSImpl::new(); let size = 0; - let mut buffer: Vec = vec![]; + let mut buffer = vec![]; let offset = 0; let mut fi = vec![FileInfo::default(), FileInfo::default()]; let get_ret = |ret: Result> | match ret { diff --git a/src/lib.rs b/src/lib.rs index 09f00a4..fd37ac2 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,7 +17,7 @@ pub mod lws_vfs { } // config -// + // { // "mount": { // "c:\\": "/l3c", @@ -26,7 +26,7 @@ pub mod lws_vfs { // }, // "port":5001 // } -// + #[derive(Debug, Default)] pub struct Config { port: u16, @@ -84,6 +84,7 @@ impl LwsVfsIns { } fn lpath(&self, path: &String) -> String { let mut ret = String::new(); + // /l0e -> w: for (k, v) in &self.config.mount_map { if path.starts_with(v) { ret = path.replace(v, k); @@ -126,6 +127,7 @@ impl LwsVfs for LwsVfsIns { path: path.to_string(), stat: Some(fstat), ret, + ..Getattr::default() }; Ok(Response::new(reply)) } @@ -167,7 +169,7 @@ impl LwsVfs for LwsVfsIns { path: request.path, size: buff.len() as i64, buff, - offset: offset as i64, + offset: offset as u64, fi: Some(fi), ret, }; @@ -203,7 +205,7 @@ impl LwsVfs for LwsVfsIns { }; let reply = Write { ret, - size: size as i64, + size: size as u64, ..Default::default() }; Ok(Response::new(reply)) @@ -271,7 +273,7 @@ impl LwsVfs for LwsVfsIns { let mut fi = request.fi.unwrap(); let path = &self.lpath(&request.path); let offset = request.offset as usize; - let mut dirs: Vec = Vec::new(); + let mut dirs = vec![]; let size = 0; let ret = match self.fs.freaddir(path, &mut dirs, size, offset, &mut fi) { Ok(ret) => ret, @@ -363,7 +365,7 @@ impl LwsVfs for LwsVfsIns { let request = request.into_inner(); let path = &self.lpath(&request.path); let mut fi = request.fi.unwrap(); - let ret = match self.fs.frelease(path, &mut fi) { + let ret = match self.fs.frelease(path, &mut fi, request.flush != 0) { Ok(ret) => ret, Err(e) => { println!("Error: release file[{}]: {:?}", path, e);