修改fd管理的层级,将其放到fs impl里面去。尚未改完,同步code
This commit is contained in:
parent
77ae3e7bac
commit
82960cfe31
|
@ -33,6 +33,12 @@ service LwsVfs {
|
||||||
rpc fchown(chown) returns (chown) {}
|
rpc fchown(chown) returns (chown) {}
|
||||||
rpc frelease(release) returns (release) {}
|
rpc frelease(release) returns (release) {}
|
||||||
rpc fmkdir(mkdir) returns (mkdir) {}
|
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.
|
// The request message containing the user's name.
|
||||||
|
@ -161,3 +167,38 @@ message mkdir {
|
||||||
uint32 mode = 3;
|
uint32 mode = 3;
|
||||||
int32 ret = 15;
|
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;
|
||||||
|
}
|
|
@ -1,13 +1,14 @@
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
use std::error::Error;
|
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 crate::lws_vfs::{FileInfo, Fstat};
|
||||||
|
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
extern crate winapi;
|
extern crate winapi;
|
||||||
use fs::remove_file;
|
|
||||||
use io::Write;
|
|
||||||
use std::os::windows::fs::MetadataExt;
|
use std::os::windows::fs::MetadataExt;
|
||||||
use std::os::windows::prelude::*;
|
use std::os::windows::prelude::*;
|
||||||
use winapi::um::winnt::FILE_ATTRIBUTE_READONLY;
|
use winapi::um::winnt::FILE_ATTRIBUTE_READONLY;
|
||||||
|
@ -22,7 +23,56 @@ fn from_metadata(sta: &mut Fstat, metadata: &fs::Metadata) -> Result<(), Box<dyn
|
||||||
sta.fst_atime = metadata.last_access_time();
|
sta.fst_atime = metadata.last_access_time();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
pub fn fgetattr(path: &String, sta: &mut Fstat, _fi: &mut FileInfo) -> Result<i32, Box<dyn Error>> {
|
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
struct FileFdMgnt {
|
||||||
|
// key is fd, value is FileHandle
|
||||||
|
files: HashMap<u64, File>,
|
||||||
|
curr_fd: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FileFdMgnt {
|
||||||
|
pub fn new() -> FileFdMgnt {
|
||||||
|
FileFdMgnt {
|
||||||
|
curr_fd: 3,
|
||||||
|
files: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn gen_fd(&mut self) -> Result<u64, Box<dyn Error>> {
|
||||||
|
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<u64, Box<dyn Error>> {
|
||||||
|
let fd = self.gen_fd()?;
|
||||||
|
self.files.insert(fd, handle);
|
||||||
|
Ok(fd)
|
||||||
|
}
|
||||||
|
pub fn pop(&mut self, fd: u64) -> Option<File> {
|
||||||
|
self.files.remove(&fd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub struct FSImpl{
|
||||||
|
file_fds: Arc<Mutex<FileFdMgnt>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FSImpl {
|
||||||
|
pub fn fgetattr(&self, path: &String, sta: &mut Fstat, _fi: &mut FileInfo) -> Result<i32, Box<dyn Error>> {
|
||||||
let metadata = fs::metadata(path)?;
|
let metadata = fs::metadata(path)?;
|
||||||
from_metadata(sta, &metadata)?;
|
from_metadata(sta, &metadata)?;
|
||||||
let perm = get_file_mode_mask(path);
|
let perm = get_file_mode_mask(path);
|
||||||
|
@ -30,12 +80,12 @@ pub fn fgetattr(path: &String, sta: &mut Fstat, _fi: &mut FileInfo) -> Result<i3
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fopen(path: &String, _fi: &mut FileInfo) -> Result<fs::File, Box<dyn Error>> {
|
pub fn fopen(&self, path: &String, _fi: &mut FileInfo) -> Result<fs::File, Box<dyn Error>> {
|
||||||
return Ok(fs::File::open(path)?);
|
return Ok(fs::File::open(path)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fread(
|
pub fn fread(
|
||||||
path: &String,
|
&self, path: &String,
|
||||||
buffer: &mut Vec<u8>,
|
buffer: &mut Vec<u8>,
|
||||||
_size: &mut usize,
|
_size: &mut usize,
|
||||||
offsize: usize,
|
offsize: usize,
|
||||||
|
@ -44,7 +94,11 @@ pub fn fread(
|
||||||
let mut file = fs::File::open(path)?;
|
let mut file = fs::File::open(path)?;
|
||||||
match file.seek_read(buffer, offsize as u64) {
|
match file.seek_read(buffer, offsize as u64) {
|
||||||
Ok(size) => {
|
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)
|
buffer.resize(size, 0)
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
@ -54,7 +108,12 @@ pub fn fread(
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fwrite(path: &String, buffer: &Vec<u8>, size: &mut usize, offsize: usize, _fi: &mut FileInfo,
|
pub fn fwrite(
|
||||||
|
&self, path: &String,
|
||||||
|
buffer: &Vec<u8>,
|
||||||
|
size: &mut usize,
|
||||||
|
offsize: usize,
|
||||||
|
_fi: &mut FileInfo,
|
||||||
) -> Result<i32, Box<dyn Error>> {
|
) -> Result<i32, Box<dyn Error>> {
|
||||||
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) {
|
match file.seek_write(buffer, offsize as u64) {
|
||||||
|
@ -68,7 +127,7 @@ pub fn fwrite(path: &String, buffer: &Vec<u8>, size: &mut usize, offsize: usize,
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
pub fn freaddir(
|
pub fn freaddir(
|
||||||
path: &String,
|
&self, path: &String,
|
||||||
buffer: &mut Vec<String>,
|
buffer: &mut Vec<String>,
|
||||||
_size: usize,
|
_size: usize,
|
||||||
_offset: usize,
|
_offset: usize,
|
||||||
|
@ -91,37 +150,37 @@ pub fn freaddir(
|
||||||
}
|
}
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
pub fn fmkdir(path: &String, _mode: u32) -> Result<i32, Box<dyn Error>> {
|
pub fn fmkdir(&self, path: &String, _mode: u32) -> Result<i32, Box<dyn Error>> {
|
||||||
fs::create_dir(path)?;
|
fs::create_dir(path)?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
pub fn fchown(_path: &String, _uid: u32, _gid: u32) -> Result<i32, Box<dyn Error>> {
|
pub fn fchown(&self, _path: &String, _uid: u32, _gid: u32) -> Result<i32, Box<dyn Error>> {
|
||||||
Ok(-1)
|
Ok(-1)
|
||||||
}
|
}
|
||||||
pub fn ftruncate(path: &String, _size: usize) -> Result<i32, Box<dyn Error>> {
|
pub fn ftruncate(&self, path: &String, size: u64) -> Result<i32, Box<dyn Error>> {
|
||||||
fs::OpenOptions::new()
|
let mut file = fs::File::options().write(true)
|
||||||
.write(true)
|
|
||||||
.truncate(true)
|
.truncate(true)
|
||||||
.open(path)?;
|
.open(path)?;
|
||||||
|
file.seek(SeekFrom::Start(size))?;
|
||||||
|
file.set_len(size)?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
use std::fs::OpenOptions;
|
pub fn futimens(&self, path: &String, a: &Vec<u64>, m: &Vec<u64>) -> Result<i32, Box<dyn Error>> {
|
||||||
use std::ptr::null_mut;
|
use std::ptr::null_mut;
|
||||||
use winapi::ctypes::c_void;
|
use winapi::ctypes::c_void;
|
||||||
use winapi::shared::minwindef::DWORD;
|
use winapi::shared::minwindef::DWORD;
|
||||||
use winapi::shared::minwindef::FILETIME;
|
use winapi::shared::minwindef::FILETIME;
|
||||||
use winapi::um::fileapi::SetFileTime;
|
use winapi::um::fileapi::SetFileTime;
|
||||||
fn system_time_to_file_time(seconds: u64, nanoseconds: u32) -> FILETIME {
|
fn system_time_to_file_time(seconds: u64, nanoseconds: u32) -> FILETIME {
|
||||||
let total_nanoseconds = (seconds * 1_000_000_000) + nanoseconds as u64;
|
let total_nanoseconds = (seconds * 1_000_000_000) + nanoseconds as u64;
|
||||||
let total_100_nanoseconds = total_nanoseconds / 100;
|
let total_100_nanoseconds = total_nanoseconds / 100;
|
||||||
FILETIME {
|
FILETIME {
|
||||||
dwLowDateTime: total_100_nanoseconds as DWORD,
|
dwLowDateTime: total_100_nanoseconds as DWORD,
|
||||||
dwHighDateTime: (total_100_nanoseconds >> 32) as DWORD,
|
dwHighDateTime: (total_100_nanoseconds >> 32) as DWORD,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn futimens(path: &String, a: &Vec<u64>, m: &Vec<u64>) -> Result<i32, Box<dyn Error>> {
|
let file = fs::File::options().write(true).open(path)?;
|
||||||
let file = OpenOptions::new().write(true).open(path)?;
|
|
||||||
let handle = file.as_raw_handle();
|
let handle = file.as_raw_handle();
|
||||||
|
|
||||||
let atime = system_time_to_file_time(a[0], a[1] as u32);
|
let atime = system_time_to_file_time(a[0], a[1] as u32);
|
||||||
|
@ -135,11 +194,16 @@ pub fn futimens(path: &String, a: &Vec<u64>, m: &Vec<u64>) -> Result<i32, Box<dy
|
||||||
Err(Box::new(io::Error::last_os_error()))
|
Err(Box::new(io::Error::last_os_error()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn frelease(_path: &String, _fi: &mut FileInfo) -> Result<i32, Box<dyn Error>> {
|
pub fn frelease(&self, _path: &String, _fi: &mut FileInfo) -> Result<i32, Box<dyn Error>> {
|
||||||
|
if let Some(fh) == self.file_fds.lock().unwrap().pop(fi.fh){
|
||||||
|
drop(fh);
|
||||||
Ok(0)
|
Ok(0)
|
||||||
|
} else {
|
||||||
|
Ok(-1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub fn fsetxattr(
|
pub fn fsetxattr(
|
||||||
_path: &String,
|
&self, _path: &String,
|
||||||
_name: &str,
|
_name: &str,
|
||||||
_value: &Vec<u8>,
|
_value: &Vec<u8>,
|
||||||
_size: usize,
|
_size: usize,
|
||||||
|
@ -147,7 +211,7 @@ pub fn fsetxattr(
|
||||||
) -> Result<i32, Box<dyn Error>> {
|
) -> Result<i32, Box<dyn Error>> {
|
||||||
Ok(-1)
|
Ok(-1)
|
||||||
}
|
}
|
||||||
pub fn fgetxattr(_path: &String, _name: &str, _size: usize) -> Result<i32, Box<dyn Error>> {
|
pub fn fgetxattr(&self, _path: &String, _name: &str, _size: usize) -> Result<i32, Box<dyn Error>> {
|
||||||
Ok(-1)
|
Ok(-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,16 +236,26 @@ fn get_file_mode_mask(path: &str) -> u32 {
|
||||||
}
|
}
|
||||||
permissions
|
permissions
|
||||||
}
|
}
|
||||||
pub fn faccess(path: &String, mask: u32) -> Result<i32, Box<dyn Error>> {
|
pub fn faccess(&self, path: &String, mask: u32) -> Result<i32, Box<dyn Error>> {
|
||||||
let permissions = get_file_mode_mask(path);
|
let permissions = get_file_mode_mask(path);
|
||||||
Ok(if permissions & mask != 0 { 0 } else { -1 })
|
Ok(if permissions & mask != 0 { 0 } else { -1 })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn frmdir(&self, path: &String) -> Result<i32, Box<dyn Error>> {
|
||||||
|
fs::remove_dir(path)?;
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fread() {
|
fn test_fread() {
|
||||||
use crate::fs_impl::*;
|
use crate::fs_impl::*;
|
||||||
let path = String::from("test_fread.txt");
|
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 ref_buffer = b"This is a test file.";
|
||||||
let _ = file.seek_write(ref_buffer, 0);
|
let _ = file.seek_write(ref_buffer, 0);
|
||||||
|
@ -244,26 +318,48 @@ fn test_fwrite() {
|
||||||
// cleanup
|
// cleanup
|
||||||
//let _ = fs::remove_file(path);
|
//let _ = fs::remove_file(path);
|
||||||
}
|
}
|
||||||
// let result = fwrite(&path, &buffer, &mut size, offsize, &mut fi);
|
#[test]
|
||||||
// println!("result: {:?}", result);
|
fn test_dir() {
|
||||||
// println!("size: {:?}", size);
|
use std::path::Path;
|
||||||
// println!("buffer: {:?}", buffer);
|
let path = String::from("test_dir");
|
||||||
// let result = freaddir(&path, &mut vec![], 0, 0, &mut fi);
|
let sub_path = String::from("test_dir/test_sub_dir");
|
||||||
// println!("result: {:?}", result);
|
//创建父目录
|
||||||
// println!("buffer: {:?}", buffer);
|
let _ = fmkdir(&path, 0);
|
||||||
// let result = fmkdir(&path, 0);
|
//创建子目录
|
||||||
// println!("result: {:?}", result);
|
let _ = fmkdir(&sub_path, 0);
|
||||||
// let result = fchown(&path, 0, 0);
|
assert_eq!(true, Path::new(&sub_path).is_dir());
|
||||||
// println!("result: {:?}", result);
|
assert_eq!(true, Path::new(&path).is_dir());
|
||||||
// let result = ftruncate(&path, 100);
|
//一次性创建多级目录
|
||||||
// println!("result: {:?}", result);
|
let ret = fmkdir(&String::from("patent/child"), 0);
|
||||||
// let result = futimens(&path, &vec![100, 0], &vec![100, 0]);
|
assert_ne!(
|
||||||
// println!("result: {:?}", result);
|
match ret {
|
||||||
// let result = frelease(&path, &mut fi);
|
Ok(ret) => ret,
|
||||||
// println!("result: {:?}", result);
|
Err(_) => -1,
|
||||||
// let result = fsetxattr(&path, "test", &vec![1,2,3], 3, 0);
|
},
|
||||||
// println!("result: {:?}", result);
|
0
|
||||||
// let result = fgetxattr(&path, "test", 100);
|
);
|
||||||
// println!("result: {:?}", result);
|
fs::remove_dir_all(path);
|
||||||
// let result = faccess(&path, 0o777);
|
}
|
||||||
// println!("result: {:?}", result);
|
// 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);
|
||||||
|
|
201
src/lib.rs
201
src/lib.rs
|
@ -1,12 +1,13 @@
|
||||||
use lws_vfs::lws_vfs_server::LwsVfs;
|
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 lws_vfs::{
|
||||||
use tonic::{Request, Response, Status};
|
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 serde_json::{self, Value};
|
||||||
|
use std::error::Error;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufReader, Read as _};
|
use std::io::{BufReader, Read as _};
|
||||||
use std::error::Error;
|
use tonic::{Request, Response, Status};
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::sync::{Arc,Mutex};
|
|
||||||
mod fs_impl;
|
mod fs_impl;
|
||||||
pub mod lws_vfs {
|
pub mod lws_vfs {
|
||||||
tonic::include_proto!("lws_vfs");
|
tonic::include_proto!("lws_vfs");
|
||||||
|
@ -24,35 +25,39 @@ pub mod lws_vfs {
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Config{
|
pub struct Config {
|
||||||
port:u16,
|
port: u16,
|
||||||
mount_map:HashMap<String,String>,
|
mount_map: HashMap<String, String>,
|
||||||
}
|
}
|
||||||
impl Config{
|
impl Config {
|
||||||
pub fn new(json:&str) -> Result<Config, Box<dyn Error>> {
|
pub fn new(json: &str) -> Result<Config, Box<dyn Error>> {
|
||||||
let mut file = File::open(json)?;
|
let mut file = File::open(json)?;
|
||||||
let mut buffer = String::new();
|
let mut buffer = String::new();
|
||||||
file.read_to_string(&mut buffer)?;
|
file.read_to_string(&mut buffer)?;
|
||||||
let json:Value = serde_json::from_str(buffer.as_ref())?;
|
let json: Value = serde_json::from_str(buffer.as_ref())?;
|
||||||
let port:u16 = match json.get("port"){
|
let port: u16 = match json.get("port") {
|
||||||
Some(port) => port.as_u64().expect("expect port is a number but its not") as u16,
|
Some(port) => port.as_u64().expect("expect port is a number but its not") as u16,
|
||||||
None => {
|
None => 5001,
|
||||||
5001
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let mounts = match json.get("mount"){
|
let mounts = match json.get("mount") {
|
||||||
Some(mounts) => mounts.as_object().unwrap(),
|
Some(mounts) => mounts.as_object().unwrap(),
|
||||||
None => {
|
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)|{
|
let mount_map = mounts
|
||||||
(key.as_str().to_string(),value.as_str().unwrap().to_string())
|
.iter()
|
||||||
}).collect();
|
.map(|(key, value)| {
|
||||||
Ok(Config{
|
(
|
||||||
port,
|
key.as_str().to_string(),
|
||||||
mount_map
|
value.as_str().unwrap().to_string(),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
.collect();
|
||||||
|
Ok(Config { port, mount_map })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_port(&self) -> u16 {
|
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<u64,File>,
|
|
||||||
curr_fd:u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FileFdMgnt {
|
|
||||||
pub fn new() -> FileFdMgnt {
|
|
||||||
FileFdMgnt{
|
|
||||||
curr_fd:3,
|
|
||||||
files:HashMap::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn gen_fd(&mut self) -> Result<u64, Box<dyn Error>> {
|
|
||||||
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<u64, Box<dyn Error>> {
|
|
||||||
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 的基础结构
|
/// server 的基础结构
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct LwsVfsIns {
|
pub struct LwsVfsIns {
|
||||||
|
@ -113,16 +73,16 @@ pub struct LwsVfsIns {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LwsVfsIns {
|
impl LwsVfsIns {
|
||||||
pub fn new(json:&str) -> Result<LwsVfsIns, Box<dyn Error>> {
|
pub fn new(json: &str) -> Result<LwsVfsIns, Box<dyn Error>> {
|
||||||
Ok(LwsVfsIns{
|
Ok(LwsVfsIns {
|
||||||
config:Config::new(json)?,
|
config: Config::new(json)?,
|
||||||
file_fds:Arc::new(Mutex::new(FileFdMgnt::new())),
|
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();
|
let mut ret = String::new();
|
||||||
for (k,v) in &self.config.mount_map{
|
for (k, v) in &self.config.mount_map {
|
||||||
if path.starts_with(v){
|
if path.starts_with(v) {
|
||||||
ret = path.replace(v, k);
|
ret = path.replace(v, k);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -133,7 +93,10 @@ impl LwsVfsIns {
|
||||||
|
|
||||||
#[tonic::async_trait]
|
#[tonic::async_trait]
|
||||||
impl LwsVfs for LwsVfsIns {
|
impl LwsVfs for LwsVfsIns {
|
||||||
async fn say_hello(&self, request: Request<HelloRequest>) -> Result<Response<HelloReply>, Status> {
|
async fn say_hello(
|
||||||
|
&self,
|
||||||
|
request: Request<HelloRequest>,
|
||||||
|
) -> Result<Response<HelloReply>, Status> {
|
||||||
println!("Got a request: {:?}", request);
|
println!("Got a request: {:?}", request);
|
||||||
|
|
||||||
let reply = HelloReply {
|
let reply = HelloReply {
|
||||||
|
@ -149,7 +112,7 @@ impl LwsVfs for LwsVfsIns {
|
||||||
let path = &self.lpath(&request.path);
|
let path = &self.lpath(&request.path);
|
||||||
let mut fstat = Fstat::default();
|
let mut fstat = Fstat::default();
|
||||||
let mut fi = FileInfo::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,
|
Ok(ret) => ret,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("Error getting file metadata: {:?}", e);
|
println!("Error getting file metadata: {:?}", e);
|
||||||
|
@ -157,8 +120,8 @@ impl LwsVfs for LwsVfsIns {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let reply = Getattr {
|
let reply = Getattr {
|
||||||
path:path.to_string(),
|
path: path.to_string(),
|
||||||
stat:Some(fstat),
|
stat: Some(fstat),
|
||||||
ret,
|
ret,
|
||||||
};
|
};
|
||||||
Ok(Response::new(reply))
|
Ok(Response::new(reply))
|
||||||
|
@ -167,10 +130,10 @@ impl LwsVfs for LwsVfsIns {
|
||||||
println!("Got a request: {:?}", request);
|
println!("Got a request: {:?}", request);
|
||||||
let request = request.into_inner();
|
let request = request.into_inner();
|
||||||
let path = &self.lpath(&request.path);
|
let path = &self.lpath(&request.path);
|
||||||
let mut fi =request.fi.unwrap();
|
let mut fi = request.fi.unwrap();
|
||||||
let ret = match fs_impl::fopen(path, &mut fi){
|
let ret = match fs_impl::fopen(path, &mut fi) {
|
||||||
Ok(file) => {
|
Ok(file) => {
|
||||||
match self.file_fds.lock().unwrap().push(file){
|
match self.file_fds.lock().unwrap().push(file) {
|
||||||
Ok(fd) => fi.fh = fd,
|
Ok(fd) => fi.fh = fd,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("Error pushing file[{}]: {:?}", path, e);
|
println!("Error pushing file[{}]: {:?}", path, e);
|
||||||
|
@ -185,7 +148,7 @@ impl LwsVfs for LwsVfsIns {
|
||||||
};
|
};
|
||||||
let reply = Open {
|
let reply = Open {
|
||||||
path: path.to_string(),
|
path: path.to_string(),
|
||||||
fi:Some(fi),
|
fi: Some(fi),
|
||||||
ret,
|
ret,
|
||||||
};
|
};
|
||||||
Ok(Response::new(reply))
|
Ok(Response::new(reply))
|
||||||
|
@ -195,11 +158,13 @@ impl LwsVfs for LwsVfsIns {
|
||||||
let request = request.into_inner();
|
let request = request.into_inner();
|
||||||
let mut fi = request.fi.unwrap();
|
let mut fi = request.fi.unwrap();
|
||||||
let path = &self.lpath(&request.path);
|
let path = &self.lpath(&request.path);
|
||||||
let mut size:usize = request.size.try_into().unwrap();
|
let mut size: usize = request.size.try_into().unwrap();
|
||||||
let offset:usize = request.offset.try_into().unwrap();
|
let offset: usize = request.offset.try_into().unwrap();
|
||||||
let mut buff: Vec<u8> = Vec::with_capacity(size);
|
let mut buff: Vec<u8> = Vec::with_capacity(size);
|
||||||
unsafe { buff.set_len(size); }
|
unsafe {
|
||||||
match fs_impl::fread(path, &mut buff, &mut size, offset, &mut fi){
|
buff.set_len(size);
|
||||||
|
}
|
||||||
|
match fs_impl::fread(path, &mut buff, &mut size, offset, &mut fi) {
|
||||||
Ok(ret) => {
|
Ok(ret) => {
|
||||||
let reply = Read {
|
let reply = Read {
|
||||||
path: request.path,
|
path: request.path,
|
||||||
|
@ -210,7 +175,7 @@ impl LwsVfs for LwsVfsIns {
|
||||||
ret,
|
ret,
|
||||||
};
|
};
|
||||||
Ok(Response::new(reply))
|
Ok(Response::new(reply))
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("Error reading file[{}]: {:?}", path, e);
|
println!("Error reading file[{}]: {:?}", path, e);
|
||||||
let reply = Read {
|
let reply = Read {
|
||||||
|
@ -233,9 +198,7 @@ impl LwsVfs for LwsVfsIns {
|
||||||
let mut size = request.size as usize;
|
let mut size = request.size as usize;
|
||||||
let offset = request.offset as usize;
|
let offset = request.offset as usize;
|
||||||
let ret = match fs_impl::fwrite(path, &buff, &mut size, offset, &mut fi) {
|
let ret = match fs_impl::fwrite(path, &buff, &mut size, offset, &mut fi) {
|
||||||
Ok(ret) => {
|
Ok(ret) => ret,
|
||||||
ret
|
|
||||||
},
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("Error fwrite file[{}]: {:?}", path, e);
|
println!("Error fwrite file[{}]: {:?}", path, e);
|
||||||
-1
|
-1
|
||||||
|
@ -243,20 +206,17 @@ impl LwsVfs for LwsVfsIns {
|
||||||
};
|
};
|
||||||
let reply = Write {
|
let reply = Write {
|
||||||
ret,
|
ret,
|
||||||
size:size as i64,
|
size: size as i64,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
Ok(Response::new(reply))
|
Ok(Response::new(reply))
|
||||||
|
|
||||||
}
|
}
|
||||||
async fn faccess( &self, request: Request<Access>,) -> Result<Response<Access>, Status> {
|
async fn faccess(&self, request: Request<Access>) -> Result<Response<Access>, Status> {
|
||||||
let request = request.into_inner();
|
let request = request.into_inner();
|
||||||
let path = &self.lpath(&request.path);
|
let path = &self.lpath(&request.path);
|
||||||
let mask = request.mask;
|
let mask = request.mask;
|
||||||
let ret = match fs_impl::faccess(path, mask) {
|
let ret = match fs_impl::faccess(path, mask) {
|
||||||
Ok(ret) => {
|
Ok(ret) => ret,
|
||||||
ret
|
|
||||||
},
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("Error access file[{}]: {:?}", path, e);
|
println!("Error access file[{}]: {:?}", path, e);
|
||||||
-1
|
-1
|
||||||
|
@ -264,7 +224,7 @@ impl LwsVfs for LwsVfsIns {
|
||||||
};
|
};
|
||||||
let reply = Access {
|
let reply = Access {
|
||||||
ret,
|
ret,
|
||||||
path:path.to_string(),
|
path: path.to_string(),
|
||||||
mask,
|
mask,
|
||||||
};
|
};
|
||||||
Ok(Response::new(reply))
|
Ok(Response::new(reply))
|
||||||
|
@ -282,9 +242,9 @@ impl LwsVfs for LwsVfsIns {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("Error: setxattr file[{}]: {:?}", path, e);
|
println!("Error: setxattr file[{}]: {:?}", path, e);
|
||||||
-1
|
-1
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
let reply = Setxattr{
|
let reply = Setxattr {
|
||||||
ret: ret,
|
ret: ret,
|
||||||
..Setxattr::default()
|
..Setxattr::default()
|
||||||
};
|
};
|
||||||
|
@ -302,7 +262,7 @@ impl LwsVfs for LwsVfsIns {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let reply = Getxattr{
|
let reply = Getxattr {
|
||||||
ret,
|
ret,
|
||||||
..Getxattr::default()
|
..Getxattr::default()
|
||||||
};
|
};
|
||||||
|
@ -323,7 +283,7 @@ impl LwsVfs for LwsVfsIns {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let reply = Readdir{
|
let reply = Readdir {
|
||||||
ret,
|
ret,
|
||||||
dirs,
|
dirs,
|
||||||
..Readdir::default()
|
..Readdir::default()
|
||||||
|
@ -341,16 +301,16 @@ impl LwsVfs for LwsVfsIns {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let reply = Mkdir{
|
let reply = Mkdir {
|
||||||
ret,
|
ret,
|
||||||
..Mkdir::default()
|
..Mkdir::default()
|
||||||
};
|
};
|
||||||
Ok(Response::new(reply))
|
Ok(Response::new(reply))
|
||||||
}
|
}
|
||||||
async fn ftruncate(&self, request: Request<Truncate>) -> Result<Response<Truncate>, Status> {
|
async fn ftruncate(&self, request: Request<Truncate>) -> Result<Response<Truncate>, Status> {
|
||||||
let request= request.into_inner();
|
let request = request.into_inner();
|
||||||
let path = &self.lpath(&request.path);
|
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) {
|
let ret = match fs_impl::ftruncate(path, size) {
|
||||||
Ok(ret) => ret,
|
Ok(ret) => ret,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -358,7 +318,7 @@ impl LwsVfs for LwsVfsIns {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let reply = Truncate{
|
let reply = Truncate {
|
||||||
ret,
|
ret,
|
||||||
..Truncate::default()
|
..Truncate::default()
|
||||||
};
|
};
|
||||||
|
@ -377,7 +337,7 @@ impl LwsVfs for LwsVfsIns {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let reply = Utimens{
|
let reply = Utimens {
|
||||||
ret,
|
ret,
|
||||||
..Utimens::default()
|
..Utimens::default()
|
||||||
};
|
};
|
||||||
|
@ -396,7 +356,7 @@ impl LwsVfs for LwsVfsIns {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let reply = Chown{
|
let reply = Chown {
|
||||||
ret,
|
ret,
|
||||||
..Chown::default()
|
..Chown::default()
|
||||||
};
|
};
|
||||||
|
@ -414,10 +374,33 @@ impl LwsVfs for LwsVfsIns {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let reply = Release{
|
let reply = Release {
|
||||||
ret,
|
ret,
|
||||||
..Release::default()
|
..Release::default()
|
||||||
};
|
};
|
||||||
Ok(Response::new(reply))
|
Ok(Response::new(reply))
|
||||||
}
|
}
|
||||||
|
async fn frmdir(&self, request: Request<Rmdir>) -> Result<Response<Rmdir>, 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<Flush>) -> Result<Response<Flush>, 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user