1. 目前已基础功能可用: 挂载,进入目录,拷贝文件,编辑文件等

2. 解决虚拟根目录匹配的做法有点问题,现在使用固定匹配/的方式,而不是逐层的匹配。
3. 存在性能问题,获取某个文件的attr的时候会逐一的获取其他父级目录的attr。使用起来反应较慢
This commit is contained in:
Ekko.bao 2024-07-31 08:44:52 +08:00
parent d9368d250d
commit f92393ae35
3 changed files with 102 additions and 43 deletions

View File

@ -97,12 +97,16 @@ fn get_file_mode_mask(path: &str) -> u32 {
let attributes = metadata.file_attributes();
// let permissions = metadata.permissions();
if attributes & FILE_ATTRIBUTE_READONLY != 0 {
permissions |= 0o222;
permissions |= 0o0444;
} else {
permissions |= 0o444 | 0o222;
permissions |= 0o0444 | 0o0222;
}
// add executeable
permissions |= 0o0111;
if metadata.is_dir() {
permissions |= 0o111;
permissions |= libc::S_IFDIR as u32;
} else {
permissions |= libc::S_IFREG as u32;
}
permissions
}
@ -122,14 +126,18 @@ impl FSImpl {
let metadata = fs::metadata(path)?;
from_metadata(sta, &metadata)?;
let perm = get_file_mode_mask(path);
sta.fst_mode = perm as u64;
println!("file mode is Oct:{:o}", perm);
sta.fst_mode = perm.into();
Ok(0)
}
pub fn fopen(&self, path: &String, fi: &mut FileInfo) -> Result<i32, Box<dyn Error>> {
let flag = fi.flags & (0xff);
let read = flag == libc::O_RDONLY as u32 || flag == libc::O_RDWR as u32;
let write = flag == libc::O_WRONLY as u32 || flag == libc::O_RDWR as u32;
let f = File::options()
.read(fi.flags & libc::O_RDONLY as u32 != 0)
.write(fi.flags & libc::O_WRONLY as u32 != 0).open(path)?;
.read(read)
.write(write).open(path)?;
let fd = self.file_fds.lock().unwrap().push(FileHandle::FILE(f))?;
fi.fh = fd;
return Ok(0);
@ -154,11 +162,11 @@ impl FSImpl {
};
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(_) => {
@ -329,8 +337,12 @@ impl FSImpl {
pub fn faccess(&self, path: &String, mask: u32) -> Result<i32, Box<dyn Error>> {
let permissions = get_file_mode_mask(path);
if mask == 0 && permissions != 0 {
Ok(0)
} else {
Ok(if permissions & mask != 0 { 0 } else { -1 })
}
}
pub fn frmdir(&self, path: &String) -> Result<i32, Box<dyn Error>> {
fs::remove_dir(path)?;

View File

@ -84,6 +84,7 @@ impl LwsVfsIns {
}
fn lpath(&self, path: &String) -> String {
let mut ret = String::new();
// println!("try to convert {}", path);
// /l0e -> w:
for (k, v) in &self.config.mount_map {
if path.starts_with(v) {
@ -91,6 +92,7 @@ impl LwsVfsIns {
break;
}
}
// println!("path convert ret is {}", ret);
ret
}
}
@ -101,18 +103,18 @@ impl LwsVfs for LwsVfsIns {
&self,
request: Request<HelloRequest>,
) -> Result<Response<HelloReply>, Status> {
let request = request.into_inner();
println!("Got a request: {:?}", request);
let reply = HelloReply {
message: format!("Hello {}!", request.into_inner().name),
message: format!("Hello {}!", request.name),
};
Ok(Response::new(reply))
}
async fn fgetattr(&self, request: Request<Getattr>) -> Result<Response<Getattr>, Status> {
println!("Got a request: {:?}", request);
let request = request.into_inner();
println!("Got a request: {:?}", request);
let path = &self.lpath(&request.path);
let mut fstat = Fstat::default();
let mut fi = FileInfo::default();
@ -132,16 +134,19 @@ impl LwsVfs for LwsVfsIns {
Ok(Response::new(reply))
}
async fn fopen(&self, request: Request<Open>) -> Result<Response<Open>, Status> {
println!("Got a request: {:?}", request);
let request = request.into_inner();
println!("Got a request: {:?}", request);
let path = &self.lpath(&request.path);
let mut fi = request.fi.unwrap();
let mut fi = match request.fi{
Some(fi) => fi,
None => FileInfo::default(),
};
let ret = match self.fs.fopen(path, &mut fi) {
Ok(_) => {
0
}
Err(e) => {
println!("Error opening file[{}]: {:?}", path, e);
println!("Error open file[{}]: {:?}", path, e);
-1
}
};
@ -153,12 +158,15 @@ impl LwsVfs for LwsVfsIns {
Ok(Response::new(reply))
}
async fn fread(&self, request: Request<Read>) -> Result<Response<Read>, Status> {
println!("Got a request: {:?}", request);
let request = request.into_inner();
let mut fi = request.fi.unwrap();
println!("Got a request: {:?}", request);
let mut fi = match request.fi{
Some(fi) => fi,
None => FileInfo::default(),
};
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 size: usize = request.size as usize;
let offset: usize = request.offset as usize;
let mut buff: Vec<u8> = Vec::with_capacity(size);
unsafe {
buff.set_len(size);
@ -170,7 +178,7 @@ impl LwsVfs for LwsVfsIns {
size: buff.len() as i64,
buff,
offset: offset as u64,
fi: Some(fi),
fi: None,
ret,
};
Ok(Response::new(reply))
@ -182,7 +190,7 @@ impl LwsVfs for LwsVfsIns {
buff: Vec::new(),
size: 0,
offset: 0,
fi: Some(fi),
fi: None,
ret: -1,
};
Ok(Response::new(reply))
@ -191,11 +199,15 @@ impl LwsVfs for LwsVfsIns {
}
async fn fwrite(&self, request: Request<Write>) -> Result<Response<Write>, Status> {
let request = request.into_inner();
let mut fi = request.fi.unwrap();
let mut fi = match request.fi{
Some(fi) => fi,
None => FileInfo::default(),
};
let path = &self.lpath(&request.path);
let buff = request.buff;
let mut size = request.size as usize;
let offset = request.offset as usize;
println!("Got a fwrite request: size {} offset {}", request.size, offset);
let ret = match self.fs.fwrite(path, &buff, &mut size, offset, &mut fi) {
Ok(ret) => ret,
Err(e) => {
@ -212,6 +224,7 @@ impl LwsVfs for LwsVfsIns {
}
async fn faccess(&self, request: Request<Access>) -> Result<Response<Access>, Status> {
let request = request.into_inner();
println!("Got a request: {:?}", request);
let path = &self.lpath(&request.path);
let mask = request.mask;
let ret = match self.fs.faccess(path, mask) {
@ -230,12 +243,13 @@ impl LwsVfs for LwsVfsIns {
}
async fn fsetxattr(&self, request: Request<Setxattr>) -> Result<Response<Setxattr>, Status> {
let req = request.into_inner();
let path = &self.lpath(&req.path);
let name = req.name.as_ref();
let value = req.value;
let size = req.size as usize;
let flags = req.flags;
let request = request.into_inner();
println!("Got a request: {:?}", request);
let path = &self.lpath(&request.path);
let name = request.name.as_ref();
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) => {
@ -250,10 +264,11 @@ impl LwsVfs for LwsVfsIns {
Ok(Response::new(reply))
}
async fn fgetxattr(&self, request: Request<Getxattr>) -> Result<Response<Getxattr>, Status> {
let req = request.into_inner();
let path = &self.lpath(&req.path);
let name = req.name.as_ref();
let size = req.size as usize;
let request = request.into_inner();
println!("Got a request: {:?}", request);
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) => {
@ -270,7 +285,11 @@ impl LwsVfs for LwsVfsIns {
async fn freaddir(&self, request: Request<Readdir>) -> Result<Response<Readdir>, Status> {
let request = request.into_inner();
let mut fi = request.fi.unwrap();
println!("Got a request: {:?}", request);
let mut fi = match request.fi{
Some(fi) => fi,
None => FileInfo::default(),
};
let path = &self.lpath(&request.path);
let offset = request.offset as usize;
let mut dirs = vec![];
@ -291,6 +310,7 @@ impl LwsVfs for LwsVfsIns {
}
async fn fmkdir(&self, request: Request<Mkdir>) -> Result<Response<Mkdir>, Status> {
let request = request.into_inner();
println!("Got a request: {:?}", request);
let path = &self.lpath(&request.path);
let mode = request.mode;
let ret = match self.fs.fmkdir(&path, mode) {
@ -308,6 +328,7 @@ impl LwsVfs for LwsVfsIns {
}
async fn ftruncate(&self, request: Request<Truncate>) -> Result<Response<Truncate>, Status> {
let request = request.into_inner();
println!("Got a request: {:?}", request);
let path = &self.lpath(&request.path);
let size = request.size as u64;
let ret = match self.fs.ftruncate(path, size) {
@ -326,6 +347,7 @@ impl LwsVfs for LwsVfsIns {
async fn futimens(&self, request: Request<Utimens>) -> Result<Response<Utimens>, Status> {
let request = request.into_inner();
println!("Got a request: {:?}", request);
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];
@ -345,6 +367,7 @@ impl LwsVfs for LwsVfsIns {
async fn fchown(&self, request: Request<Chown>) -> Result<Response<Chown>, Status> {
let request = request.into_inner();
println!("Got a request: {:?}", request);
let path = &self.lpath(&request.path);
let uid = request.uid as u32;
let gid = request.gid as u32;
@ -363,8 +386,12 @@ impl LwsVfs for LwsVfsIns {
}
async fn frelease(&self, request: Request<Release>) -> Result<Response<Release>, Status> {
let request = request.into_inner();
println!("Got a request: {:?}", request);
let path = &self.lpath(&request.path);
let mut fi = request.fi.unwrap();
let mut fi = match request.fi{
Some(fi) => fi,
None => FileInfo::default(),
};
let ret = match self.fs.frelease(path, &mut fi, request.flush != 0) {
Ok(ret) => ret,
Err(e) => {
@ -380,6 +407,7 @@ impl LwsVfs for LwsVfsIns {
}
async fn frmdir(&self, request: Request<Rmdir>) -> Result<Response<Rmdir>, Status> {
let request = request.into_inner();
println!("Got a request: {:?}", request);
let path = &self.lpath(&request.path);
let ret = match self.fs.frmdir(path) {
Ok(ret) => ret,
@ -397,8 +425,12 @@ impl LwsVfs for LwsVfsIns {
async fn fflush(&self, request: Request<Flush>) -> Result<Response<Flush>, Status> {
let request = request.into_inner();
println!("Got a request: {:?}", request);
let path = &self.lpath(&request.path);
let mut fi = request.fi.unwrap();
let mut fi = match request.fi{
Some(fi) => fi,
None => FileInfo::default(),
};
let ret = match self.fs.fflush(path, &mut fi) {
Ok(ret) => ret,
Err(e) => {
@ -415,9 +447,13 @@ impl LwsVfs for LwsVfsIns {
async fn fcreate(&self, request: Request<Create>) -> Result<Response<Create>, Status> {
let request = request.into_inner();
println!("Got a request: {:?}", request);
let path = &self.lpath(&request.path);
let mode = request.mode as u32;
let mut fi = request.fi.unwrap();
let mut fi = match request.fi{
Some(fi) => fi,
None => FileInfo::default(),
};
let ret = match self.fs.fcreate(path, mode, &mut fi) {
Ok(ret) => ret,
Err(e) => {
@ -434,6 +470,7 @@ impl LwsVfs for LwsVfsIns {
async fn funlink(&self, request: Request<Unlink>) -> Result<Response<Unlink>, Status> {
let request = request.into_inner();
println!("Got a request: {:?}", request);
let path = &self.lpath(&request.path);
let ret = match self.fs.funlink(path) {
Ok(ret) => ret,
@ -451,17 +488,22 @@ impl LwsVfs for LwsVfsIns {
async fn fopendir(&self,request: Request<Opendir>) -> Result<Response<Opendir>, Status> {
let request = request.into_inner();
println!("Got a request: {:?}", request);
let path = &self.lpath(&request.path);
let mut fi = request.fi.unwrap();
let mut fi = match request.fi{
Some(fi) => fi,
None => FileInfo::default(),
};
let ret = match self.fs.fopendir(path, &mut fi) {
Ok(ret) => ret,
Err(e) => {
println!("Error: opendir file[{}]: {:?}", path, e);
println!("Error: opendir dir[{}]: {:?}", path, e);
-1
}
};
let reply = Opendir {
ret,
fi: Some(fi),
..Opendir::default()
};
Ok(Response::new(reply))
@ -469,8 +511,12 @@ impl LwsVfs for LwsVfsIns {
async fn freleasedir(&self, request: Request<Releasedir>) -> Result<Response<Releasedir>, Status> {
let request = request.into_inner();
println!("Got a request: {:?}", request);
let path = &self.lpath(&request.path);
let mut fi = request.fi.unwrap();
let mut fi = match request.fi{
Some(fi) => fi,
None => FileInfo::default(),
};
let ret = match self.fs.freleasedir(path, &mut fi) {
Ok(ret) => ret,
Err(e) => {
@ -487,6 +533,7 @@ impl LwsVfs for LwsVfsIns {
async fn frename(&self, request: Request<Rename>) -> Result<Response<Rename>, Status> {
let request = request.into_inner();
println!("Got a request: {:?}", request);
let from = &self.lpath(&request.path);
let to = &self.lpath(&request.new);
let ret = match self.fs.frename(from, to) {

View File

@ -23,7 +23,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
return Err(e);
}
};
let addr = format!("192.168.0.110:{}", instance.config.get_port());
let addr = format!("0.0.0.0:{}", instance.config.get_port());
println!("Listening on {}", addr);
transport::Server::builder()
.add_service(LwsVfsServer::new(instance))