初版完成。等待调试

This commit is contained in:
Ekko.bao 2024-07-23 08:51:09 +08:00
parent 53d62dc0a9
commit c05420a395
6 changed files with 59 additions and 22 deletions

1
Cargo.lock generated
View File

@ -433,6 +433,7 @@ checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
name = "lws_vfs"
version = "0.1.0"
dependencies = [
"libc",
"prost",
"serde",
"serde_json",

View File

@ -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"

9
config.json Executable file
View File

@ -0,0 +1,9 @@
{
"mount": {
"c:\\": "/l3c",
"d:\\": "/l0d",
"f:\\": "/l0e"
},
"port":7412,
"addr":"192.168.0.110"
}

View File

@ -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;
}

View File

@ -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<dyn Error>> {
sta.fst_size = metadata.len();
@ -126,7 +127,9 @@ impl FSImpl {
}
pub fn fopen(&self, path: &String, fi: &mut FileInfo) -> Result<i32, Box<dyn Error>> {
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<String>, _size: usize, _offset: usize, fi: &mut FileInfo,
pub fn freaddir(&self, path: &String, buffer: &mut Vec<Direntry>, _size: usize, _offset: usize, fi: &mut FileInfo,
) -> Result<i32, Box<dyn Error>> {
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<i32, Box<dyn Error>> {
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<i32, Box<dyn Error>> {
pub fn frelease(&self, path: &String, fi: &mut FileInfo, flush:bool) -> Result<i32, Box<dyn Error>> {
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<String> = vec![];
let mut buffer = vec![];
let offset = 0;
let mut fi = vec![FileInfo::default(), FileInfo::default()];
let get_ret = |ret: Result<i32, Box<dyn Error>> | match ret {

View File

@ -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<String> = 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);