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

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

View File

@ -5,5 +5,5 @@
"f:\\": "/l0e"
},
"port": 7412,
"addr": "192.168.0.110"
}
"addr": "192.168.0.111"
}

View File

@ -141,10 +141,10 @@ impl RpcPool {
let timeout = Duration::from_millis(100);
let (_unused, timeout_res) = cond.wait_timeout(mutex.lock().unwrap(), timeout).unwrap();
if timeout_res.timed_out() {
println!("Timed out!");
break;
}
}
println!("get free rpc client time out");
Err(Box::new(IoError::new(
ErrorKind::Other,
"get free rpc client time out",
@ -169,7 +169,7 @@ impl RpcPool {
}
struct VirFs {
name: String,
_name: String,
stat: lws_client::Fstat,
sub: HashMap<String, VirFs>,
is_root: bool,
@ -185,7 +185,7 @@ impl VirFs {
.unwrap()
.as_nanos() as u64;
VirFs {
name: name.to_string(),
_name: name.to_string(),
stat: lws_client::Fstat {
fst_mode: 0o0755 | {
if is_dir {
@ -221,6 +221,10 @@ impl VirFs {
where
T: ToString,
{
let name = name.to_string();
let ret = name.split('/').filter(|x| x.len() > 0).map(|y| y).collect::<Vec<&str>>();
let name = ret[0];
println!("add fs {}", name);
let mut node = VirFs::create(name.to_string(), true);
node.is_root = false;
self.sub.insert(name.to_string(), node);
@ -232,17 +236,12 @@ impl VirFs {
{
let name = name.to_string();
let mut vname = name.split('/').filter(|x| x.len() > 0);
println!("try match {:?}", vname);
if let Some(current) = vname.next() {
if self.name == current {
self.match_path(&mut vname)
} else {
None
}
} else {
None
//println!("try match {}", name);
if let Some(_curr) = vname.next() {
return None;
}
Some(self)
//self.match_path(&mut vname)
}
pub fn match_path<'a>(&self, name_list: &mut impl Iterator<Item = &'a str>) -> Option<&VirFs> {
@ -269,6 +268,7 @@ impl VirFs {
for name in self.sub.keys() {
ret.push(name.to_string());
}
println!("readdir: {:?}", ret);
ret
}
}
@ -290,7 +290,7 @@ fn mode_to_filetype(mode: libc::mode_t) -> FileType {
libc::S_IFIFO => FileType::NamedPipe,
libc::S_IFSOCK => FileType::Socket,
_ => {
panic!("unknown file type");
panic!("unknown file type {}", mode);
}
}
}
@ -343,12 +343,16 @@ impl FilesystemMT for LwsVfsIns {
rdev: fst.fst_rdev as u32,
flags: 0,
};
let path = path.to_str().unwrap();
if let Some(node) = self.vir_root.find(path) {
return Ok((Duration::new(0, 0), file_attr(&node.stat)));
// println!("getattr {:?}", path);
// let path = ;
if let Some(node) = path.to_str() {
if let Some(node) = self.vir_root.find(node) {
return Ok((Duration::new(0, 0), file_attr(&node.stat)));
}
}
let request = tonic::Request::new(Getattr {
path: path.into(),
path: path.to_string_lossy().into_owned(),
fi: Some(FileInfo {
fh: match fh {
Some(f) => f,
@ -361,7 +365,7 @@ impl FilesystemMT for LwsVfsIns {
let (rpc, resp) = {
let client = match self.rpcs.get() {
Ok(c) => c,
Err(_) => return Err(libc::ENOMSG),
Err(_) => return Err(libc::EAGAIN),
};
let mut rpc = client.write().unwrap();
let resp = self.async_rt.block_on(rpc.client.fgetattr(request));
@ -375,7 +379,8 @@ impl FilesystemMT for LwsVfsIns {
return Err(libc::ENOMSG);
}
};
if resp.ret != 0 {
println!("get resp: {:?}", resp);
if resp.ret != 0 {
return Err(libc::ENOMSG);
}
Ok((Duration::new(0, 0), file_attr(&resp.stat.unwrap())))
@ -389,7 +394,7 @@ impl FilesystemMT for LwsVfsIns {
/// * `fh`: a file handle if this is called on an open file.
/// * `mode`: the mode to change the file to.
fn chmod(&self, _req: RequestInfo, _path: &Path, _fh: Option<u64>, _mode: u32) -> ResultEmpty {
Err(libc::ENOMSG)
Ok(())
}
/// Change the owner UID and/or group GID of a filesystem entry.
@ -405,7 +410,7 @@ impl FilesystemMT for LwsVfsIns {
_uid: Option<u32>,
_gid: Option<u32>,
) -> ResultEmpty {
Err(libc::ENOMSG)
Ok(())
}
/// Set the length of a file.
@ -421,7 +426,7 @@ impl FilesystemMT for LwsVfsIns {
let (rpc, resp) = {
let client = match self.rpcs.get() {
Ok(c) => c,
Err(_) => return Err(libc::ENOMSG),
Err(_) => return Err(libc::EAGAIN),
};
let mut rpc = client.write().unwrap();
let resp = self.async_rt.block_on(rpc.client.ftruncate(request));
@ -435,7 +440,8 @@ impl FilesystemMT for LwsVfsIns {
return Err(libc::ENOMSG);
}
};
if resp.ret != 0 {
println!("get resp: {:?}", resp);
if resp.ret != 0 {
return Err(libc::ENOMSG);
}
Ok(())
@ -478,7 +484,7 @@ impl FilesystemMT for LwsVfsIns {
let (rpc, resp) = {
let client = match self.rpcs.get() {
Ok(c) => c,
Err(_) => return Err(libc::ENOMSG),
Err(_) => return Err(libc::EAGAIN),
};
let mut rpc = client.write().unwrap();
let resp = self.async_rt.block_on(rpc.client.futimens(request));
@ -492,7 +498,8 @@ impl FilesystemMT for LwsVfsIns {
return Err(libc::ENOMSG);
}
};
if resp.ret != 0 {
println!("get resp: {:?}", resp);
if resp.ret != 0 {
return Err(libc::ENOMSG);
}
Ok(())
@ -502,7 +509,7 @@ impl FilesystemMT for LwsVfsIns {
/// Read a symbolic link.
fn readlink(&self, _req: RequestInfo, _path: &Path) -> ResultData {
Err(libc::ENOMSG)
Err(libc::ENOSYS)
}
/// Create a special file.
@ -519,7 +526,7 @@ impl FilesystemMT for LwsVfsIns {
_mode: u32,
_rdev: u32,
) -> ResultEntry {
Err(libc::ENOMSG)
Err(libc::ENOSYS)
}
/// Create a directory.
@ -530,7 +537,7 @@ impl FilesystemMT for LwsVfsIns {
fn mkdir(&self, req: RequestInfo, parent: &Path, name: &OsStr, mode: u32) -> ResultEntry {
let path = format!("{}/{}", parent.to_str().unwrap(), name.to_str().unwrap());
if let Some(_unused) = self.vir_root.find(&path) {
return Err(libc::ENOMSG);
return Err(libc::ENOSYS)
}
let request = tonic::Request::new(Mkdir {
path: path.to_string(),
@ -540,7 +547,7 @@ impl FilesystemMT for LwsVfsIns {
let (rpc, resp) = {
let client = match self.rpcs.get() {
Ok(c) => c,
Err(_) => return Err(libc::ENOMSG),
Err(_) => return Err(libc::EAGAIN),
};
let mut rpc = client.write().unwrap();
let resp = self.async_rt.block_on(rpc.client.fmkdir(request));
@ -554,7 +561,8 @@ impl FilesystemMT for LwsVfsIns {
return Err(libc::ENOMSG);
}
};
if resp.ret != 0 {
println!("get resp: {:?}", resp);
if resp.ret != 0 {
return Err(libc::ENOMSG);
}
self.getattr(req, Path::new(&path), None)
@ -573,7 +581,7 @@ impl FilesystemMT for LwsVfsIns {
let (rpc, resp) = {
let client = match self.rpcs.get() {
Ok(c) => c,
Err(_) => return Err(libc::ENOMSG),
Err(_) => return Err(libc::EAGAIN),
};
let mut rpc = client.write().unwrap();
let resp = self.async_rt.block_on(rpc.client.funlink(request));
@ -587,7 +595,8 @@ impl FilesystemMT for LwsVfsIns {
return Err(libc::ENOMSG);
}
};
if resp.ret != 0 {
println!("get resp: {:?}", resp);
if resp.ret != 0 {
return Err(libc::ENOMSG);
}
Ok(())
@ -609,7 +618,7 @@ impl FilesystemMT for LwsVfsIns {
let (rpc, resp) = {
let client = match self.rpcs.get() {
Ok(c) => c,
Err(_) => return Err(libc::ENOMSG),
Err(_) => return Err(libc::EAGAIN),
};
let mut rpc = client.write().unwrap();
let resp = self.async_rt.block_on(rpc.client.frmdir(request));
@ -623,7 +632,8 @@ impl FilesystemMT for LwsVfsIns {
return Err(libc::ENOMSG);
}
};
if resp.ret != 0 {
println!("get resp: {:?}", resp);
if resp.ret != 0 {
return Err(libc::ENOMSG);
}
Ok(())
@ -641,7 +651,7 @@ impl FilesystemMT for LwsVfsIns {
_name: &OsStr,
_target: &Path,
) -> ResultEntry {
Err(libc::ENOMSG)
Err(libc::ENOSYS)
}
/// Rename a filesystem entry.
@ -669,7 +679,7 @@ impl FilesystemMT for LwsVfsIns {
let (rpc, resp) = {
let client = match self.rpcs.get() {
Ok(c) => c,
Err(_) => return Err(libc::ENOMSG),
Err(_) => return Err(libc::EAGAIN),
};
let mut rpc = client.write().unwrap();
let resp = self.async_rt.block_on(rpc.client.frename(request));
@ -683,7 +693,8 @@ impl FilesystemMT for LwsVfsIns {
return Err(libc::ENOMSG);
}
};
if resp.ret != 0 {
println!("get resp: {:?}", resp);
if resp.ret != 0 {
return Err(libc::ENOMSG);
}
Ok(())
@ -701,7 +712,7 @@ impl FilesystemMT for LwsVfsIns {
_newparent: &Path,
_newname: &OsStr,
) -> ResultEntry {
Err(libc::ENOMSG)
Err(libc::ENOSYS)
}
/// Open a file.
@ -713,6 +724,7 @@ impl FilesystemMT for LwsVfsIns {
/// calls that operate on the file, and can be any value you choose, though it should allow
/// your filesystem to identify the file opened even without any path info.
fn open(&self, _req: RequestInfo, path: &Path, flags: u32) -> ResultOpen {
println!("open flags is {}", flags);
let request = tonic::Request::new(Open {
path: path.to_str().unwrap().to_string(),
fi: Some(FileInfo {
@ -724,7 +736,7 @@ impl FilesystemMT for LwsVfsIns {
let (rpc, resp) = {
let client = match self.rpcs.get() {
Ok(c) => c,
Err(_) => return Err(libc::ENOMSG),
Err(_) => return Err(libc::EAGAIN),
};
let mut rpc = client.write().unwrap();
let resp = self.async_rt.block_on(rpc.client.fopen(request));
@ -738,7 +750,8 @@ impl FilesystemMT for LwsVfsIns {
return Err(libc::ENOMSG);
}
};
if resp.ret != 0 {
println!("get resp: {:?}", resp);
if resp.ret != 0 {
return Err(libc::ENOMSG);
}
let fi = resp.fi.unwrap();
@ -765,7 +778,7 @@ impl FilesystemMT for LwsVfsIns {
path: &Path,
fh: u64,
offset: u64,
_size: u32,
size: u32,
callback: impl FnOnce(ResultSlice<'_>) -> CallbackResult,
) -> CallbackResult {
let request = tonic::Request::new(Read {
@ -774,6 +787,7 @@ impl FilesystemMT for LwsVfsIns {
fh,
..FileInfo::default()
}),
size: size.into(),
offset,
..Read::default()
});
@ -794,7 +808,8 @@ impl FilesystemMT for LwsVfsIns {
return callback(Err(libc::ENOMSG));
}
};
if resp.ret != 0 {
println!("get resp: {:?}", resp);
if resp.ret != 0 {
return callback(Err(libc::ENOMSG));
}
callback(Ok(&resp.buff))
@ -832,7 +847,7 @@ impl FilesystemMT for LwsVfsIns {
let (rpc, resp) = {
let client = match self.rpcs.get() {
Ok(c) => c,
Err(_) => return Err(libc::ENOMSG),
Err(_) => return Err(libc::EAGAIN),
};
let mut rpc = client.write().unwrap();
let resp = self.async_rt.block_on(rpc.client.fwrite(request));
@ -846,10 +861,11 @@ impl FilesystemMT for LwsVfsIns {
return Err(libc::ENOMSG);
}
};
println!("get resp: {:?}", resp);
if resp.ret != 0 {
return Err(libc::ENOMSG);
}
Ok(resp.buff.len() as u32)
Ok(resp.size as u32)
}
/// Called each time a program calls `close` on an open file.
@ -875,7 +891,7 @@ impl FilesystemMT for LwsVfsIns {
let (rpc, resp) = {
let client = match self.rpcs.get() {
Ok(c) => c,
Err(_) => return Err(libc::ENOMSG),
Err(_) => return Err(libc::EAGAIN),
};
let mut rpc = client.write().unwrap();
let resp = self.async_rt.block_on(rpc.client.fflush(request));
@ -889,7 +905,8 @@ impl FilesystemMT for LwsVfsIns {
return Err(libc::ENOMSG);
}
};
if resp.ret != 0 {
println!("get resp: {:?}", resp);
if resp.ret != 0 {
return Err(libc::ENOMSG);
}
Ok(())
@ -927,7 +944,7 @@ impl FilesystemMT for LwsVfsIns {
let (rpc, resp) = {
let client = match self.rpcs.get() {
Ok(c) => c,
Err(_) => return Err(libc::ENOMSG),
Err(_) => return Err(libc::EAGAIN),
};
let mut rpc = client.write().unwrap();
let resp = self.async_rt.block_on(rpc.client.frelease(request));
@ -941,7 +958,8 @@ impl FilesystemMT for LwsVfsIns {
return Err(libc::ENOMSG);
}
};
if resp.ret != 0 {
println!("get resp: {:?}", resp);
if resp.ret != 0 {
return Err(libc::ENOMSG);
}
Ok(())
@ -955,7 +973,7 @@ impl FilesystemMT for LwsVfsIns {
/// * `fh`: file handle returned from the `open` call.
/// * `datasync`: if `false`, also write metadata, otherwise just write file data.
fn fsync(&self, _req: RequestInfo, _path: &Path, _fh: u64, _datasync: bool) -> ResultEmpty {
Err(libc::ENOMSG)
Err(libc::ENOSYS)
}
/// Open a directory.
@ -969,14 +987,18 @@ impl FilesystemMT for LwsVfsIns {
/// calls that operate on the directory, and can be any value you choose, though it should
/// allow your filesystem to identify the directory opened even without any path info.
fn opendir(&self, _req: RequestInfo, path: &Path, flags: u32) -> ResultOpen {
let path = path.to_str().unwrap();
if let Some(_node) = self.vir_root.find(&path) {
return Ok((6666, flags))
}
let request = tonic::Request::new(Opendir {
path: path.to_str().unwrap().to_string(),
path: path.to_string(),
..Opendir::default()
});
let (rpc, resp) = {
let client = match self.rpcs.get() {
Ok(c) => c,
Err(_) => return Err(libc::ENOMSG),
Err(_) => return Err(libc::EAGAIN),
};
let mut rpc = client.write().unwrap();
let resp = self.async_rt.block_on(rpc.client.fopendir(request));
@ -990,7 +1012,8 @@ impl FilesystemMT for LwsVfsIns {
return Err(libc::ENOMSG);
}
};
if resp.ret != 0 {
println!("get resp: {:?}", resp);
if resp.ret != 0 {
return Err(libc::ENOMSG);
}
Ok((resp.fi.unwrap().fh, flags))
@ -1038,7 +1061,7 @@ impl FilesystemMT for LwsVfsIns {
let (rpc, resp) = {
let client = match self.rpcs.get() {
Ok(c) => c,
Err(_) => return Err(libc::ENOMSG),
Err(_) => return Err(libc::EAGAIN),
};
let mut rpc = client.write().unwrap();
let resp = self.async_rt.block_on(rpc.client.freaddir(request));
@ -1052,7 +1075,8 @@ impl FilesystemMT for LwsVfsIns {
return Err(libc::ENOMSG);
}
};
if resp.ret != 0 {
println!("get resp: {:?}", resp);
if resp.ret != 0 {
return Err(libc::ENOMSG);
}
let mut dirs = vec![];
@ -1073,6 +1097,9 @@ impl FilesystemMT for LwsVfsIns {
/// * `fh`: file handle returned from the `opendir` call.
/// * `flags`: the file access flags passed to the `opendir` call.
fn releasedir(&self, _req: RequestInfo, path: &Path, fh: u64, _flags: u32) -> ResultEmpty {
if fh == 6666 {
return Ok(())
}
let request = tonic::Request::new(Releasedir {
path: path.to_str().unwrap().to_string(),
fi: Some(FileInfo {
@ -1084,7 +1111,7 @@ impl FilesystemMT for LwsVfsIns {
let (rpc, resp) = {
let client = match self.rpcs.get() {
Ok(c) => c,
Err(_) => return Err(libc::ENOMSG),
Err(_) => return Err(libc::EAGAIN),
};
let mut rpc = client.write().unwrap();
let resp = self.async_rt.block_on(rpc.client.freleasedir(request));
@ -1098,7 +1125,8 @@ impl FilesystemMT for LwsVfsIns {
return Err(libc::ENOMSG);
}
};
if resp.ret != 0 {
println!("get resp: {:?}", resp);
if resp.ret != 0 {
return Err(libc::ENOMSG);
}
Ok(())
@ -1108,7 +1136,7 @@ impl FilesystemMT for LwsVfsIns {
///
/// Analogous to the `fsync` call.
fn fsyncdir(&self, _req: RequestInfo, _path: &Path, _fh: u64, _datasync: bool) -> ResultEmpty {
Err(libc::ENOMSG)
Err(libc::ENOSYS)
}
/// Get filesystem statistics.
@ -1117,7 +1145,7 @@ impl FilesystemMT for LwsVfsIns {
///
/// See the `Statfs` struct for more details.
fn statfs(&self, _req: RequestInfo, _path: &Path) -> ResultStatfs {
Err(libc::ENOMSG)
Err(libc::ENOSYS)
}
/// Set a file extended attribute.
@ -1136,7 +1164,7 @@ impl FilesystemMT for LwsVfsIns {
_flags: u32,
_position: u32,
) -> ResultEmpty {
Err(libc::ENOMSG)
Err(libc::ENOSYS)
}
/// Get a file extended attribute.
@ -1148,7 +1176,7 @@ impl FilesystemMT for LwsVfsIns {
/// If `size` is 0, return `Xattr::Size(n)` where `n` is the size of the attribute data.
/// Otherwise, return `Xattr::Data(data)` with the requested data.
fn getxattr(&self, _req: RequestInfo, _path: &Path, _name: &OsStr, _size: u32) -> ResultXattr {
Err(libc::ENOMSG)
Err(libc::ENOSYS)
}
/// List extended attributes for a file.
@ -1161,7 +1189,7 @@ impl FilesystemMT for LwsVfsIns {
/// Otherwise, return `Xattr::Data(data)` where `data` is all the null-terminated attribute
/// names.
fn listxattr(&self, _req: RequestInfo, _path: &Path, _size: u32) -> ResultXattr {
Err(libc::ENOMSG)
Err(libc::ENOSYS)
}
/// Remove an extended attribute for a file.
@ -1169,7 +1197,7 @@ impl FilesystemMT for LwsVfsIns {
/// * `path`: path to the file.
/// * `name`: name of the attribute to remove.
fn removexattr(&self, _req: RequestInfo, _path: &Path, _name: &OsStr) -> ResultEmpty {
Err(libc::ENOMSG)
Err(libc::ENOSYS)
}
/// Check for access to a file.
@ -1180,15 +1208,31 @@ impl FilesystemMT for LwsVfsIns {
/// Return `Ok(())` if all requested permissions are allowed, otherwise return `Err(EACCES)`
/// or other error code as appropriate (e.g. `ENOENT` if the file doesn't exist).
fn access(&self, _req: RequestInfo, path: &Path, mask: u32) -> ResultEmpty {
fn mask2mode(mask: i32) -> u32 {
let mut mode = 0;
if mask & libc::F_OK != 0 {
mode = 0;
}
if mask & libc::X_OK != 0 {
mode |= 0o0111;
}
if mask & libc::W_OK != 0 {
mode |= 0o222;
}
if mask & libc::R_OK != 0 {
mode |= 0o444;
}
mode as u32
}
let request = tonic::Request::new(Access {
path: path.to_str().unwrap().to_string(),
mask,
mask: mask2mode(mask as i32),
..Access::default()
});
let (rpc, resp) = {
let client = match self.rpcs.get() {
Ok(c) => c,
Err(_) => return Err(libc::ENOMSG),
Err(_) => return Err(libc::EAGAIN),
};
let mut rpc = client.write().unwrap();
let resp = self.async_rt.block_on(rpc.client.faccess(request));
@ -1202,8 +1246,9 @@ impl FilesystemMT for LwsVfsIns {
return Err(libc::ENOMSG);
}
};
if resp.ret != 0 {
return Err(libc::ENOMSG);
println!("get resp: {:?}", resp);
if resp.ret != 0 {
return Err(libc::EACCES);
}
Ok(())
}
@ -1237,7 +1282,7 @@ impl FilesystemMT for LwsVfsIns {
let (rpc, resp) = {
let client = match self.rpcs.get() {
Ok(c) => c,
Err(_) => return Err(libc::ENOMSG),
Err(_) => return Err(libc::EAGAIN),
};
let mut rpc = client.write().unwrap();
let resp = self.async_rt.block_on(rpc.client.fcreate(request));
@ -1251,7 +1296,8 @@ impl FilesystemMT for LwsVfsIns {
return Err(libc::ENOMSG);
}
};
if resp.ret != 0 {
println!("get resp: {:?}", resp);
if resp.ret != 0 {
return Err(libc::ENOMSG);
}
let fi = resp.fi.unwrap();

1
third_party/fuse-mt vendored Submodule

@ -0,0 +1 @@
Subproject commit ee9d91d9003e5aa72877ca39b614ff7d84149f02