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

View File

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