1. 目前已基础功能可用: 挂载,进入目录,拷贝文件,编辑文件等
2. 解决虚拟根目录匹配的做法有点问题,现在使用固定匹配/的方式,而不是逐层的匹配。 3. 存在性能问题,获取某个文件的attr的时候会逐一的获取其他父级目录的attr。使用起来反应较慢
This commit is contained in:
parent
d9368d250d
commit
f92393ae35
|
@ -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,7 +337,11 @@ impl FSImpl {
|
|||
|
||||
pub fn faccess(&self, path: &String, mask: u32) -> Result<i32, Box<dyn Error>> {
|
||||
let permissions = get_file_mode_mask(path);
|
||||
Ok(if permissions & mask != 0 { 0 } else { -1 })
|
||||
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>> {
|
||||
|
|
107
src/lib.rs
107
src/lib.rs
|
@ -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) {
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue
Block a user