替换为fuser_mt 使用high——level的接口进行实现。
处理好了同步和异步的code
This commit is contained in:
parent
24573524a6
commit
2f34dd807d
42
Cargo.lock
generated
42
Cargo.lock
generated
|
@ -214,10 +214,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fuser"
|
name = "fuse_mt"
|
||||||
version = "0.14.0"
|
version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2e697f6f62c20b6fad1ba0f84ae909f25971cf16e735273524e3977c94604cf8"
|
checksum = "e098b8dc4cd32e9ba31d9c8cdfef11271d8191233c64c2a671432ff19d354948"
|
||||||
|
dependencies = [
|
||||||
|
"fuser",
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"threadpool",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fuser"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "21370f84640642c8ea36dfb2a6bfc4c55941f476fcf431f6fef25a5ddcf0169b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
|
@ -454,7 +466,8 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||||
name = "lws_client"
|
name = "lws_client"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fuser",
|
"fuse_mt",
|
||||||
|
"libc",
|
||||||
"prost",
|
"prost",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -534,9 +547,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "page_size"
|
name = "page_size"
|
||||||
version = "0.6.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da"
|
checksum = "1b7663cbd190cfd818d08efa8497f6cd383076688c49a391ef7c0d03cd12b561"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"winapi",
|
"winapi",
|
||||||
|
@ -858,6 +871,15 @@ dependencies = [
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "threadpool"
|
||||||
|
version = "1.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
|
||||||
|
dependencies = [
|
||||||
|
"num_cpus",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.38.0"
|
version = "1.38.0"
|
||||||
|
@ -1213,9 +1235,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.7.35"
|
version = "0.6.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
checksum = "854e949ac82d619ee9a14c66a1b674ac730422372ccb759ce0c39cabcf2bf8e6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"zerocopy-derive",
|
"zerocopy-derive",
|
||||||
|
@ -1223,9 +1245,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy-derive"
|
name = "zerocopy-derive"
|
||||||
version = "0.7.35"
|
version = "0.6.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
@ -13,7 +13,8 @@ prost = "0.12"
|
||||||
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
|
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
fuser = "0.14.0"
|
fuse_mt = "0.6.1"
|
||||||
|
libc = "0.2"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
tonic-build = "0.11"
|
tonic-build = "0.11"
|
||||||
|
|
|
@ -76,6 +76,7 @@ message fstat {
|
||||||
message getattr {
|
message getattr {
|
||||||
string path = 1;
|
string path = 1;
|
||||||
fstat stat = 2;
|
fstat stat = 2;
|
||||||
|
file_info fi = 3;
|
||||||
int32 ret = 15;
|
int32 ret = 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
return Err(e);
|
return Err(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match lws_ins.hello().await{
|
match lws_ins.hello(){
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("lws client instance hello err {:?}", e);
|
println!("lws client instance hello err {:?}", e);
|
||||||
return Err(e);
|
return Err(e);
|
||||||
|
|
394
src/lib.rs
394
src/lib.rs
|
@ -1,16 +1,14 @@
|
||||||
use lws_client::HelloRequest;
|
use lws_client::{Getattr, HelloRequest, FileInfo};
|
||||||
|
use std::borrow::BorrowMut;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::{io::Read as _};
|
use std::{io::Read as _};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use serde_json::{self, Value};
|
use serde_json::{self, Value};
|
||||||
use lws_client::lws_vfs_client::LwsVfsClient;
|
use lws_client::lws_vfs_client::LwsVfsClient;
|
||||||
use std::os::raw::c_int;
|
use std::ffi::{OsStr, OsString};
|
||||||
|
|
||||||
use fuser::{
|
|
||||||
KernelConfig, FileAttr, FileType, Filesystem, MountOption, ReplyAttr, ReplyData, ReplyDirectory, ReplyEntry,
|
|
||||||
Request,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub mod lws_client {
|
pub mod lws_client {
|
||||||
tonic::include_proto!("lws_vfs"); //导入lws vfs proto buffer
|
tonic::include_proto!("lws_vfs"); //导入lws vfs proto buffer
|
||||||
|
@ -66,43 +64,399 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct vir_fs {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct LwsVfsIns {
|
pub struct LwsVfsIns {
|
||||||
pub config: Config,
|
pub config: Config,
|
||||||
rpc: LwsVfsClient<tonic::transport::Channel>
|
rpc: RefCell<LwsVfsClient<tonic::transport::Channel>>,
|
||||||
|
async_rt: tokio::runtime::Runtime,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Filesystem for LwsVfsIns {
|
use fuse_mt::*;
|
||||||
fn init(&mut self, _req: &Request, #[allow(unused_variables)] config: &mut KernelConfig,
|
use std::path::{Path, PathBuf};
|
||||||
) -> Result<(), c_int> {
|
use std::time::{Duration, SystemTime};
|
||||||
|
impl FilesystemMT for LwsVfsIns {
|
||||||
|
/// Called on mount, before any other function.
|
||||||
|
fn init(&self, _req: RequestInfo) -> ResultEmpty {
|
||||||
|
match self.hello() {
|
||||||
|
Ok(()) => {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
},
|
||||||
|
Err(e) =>{
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/// Called on filesystem unmount.
|
||||||
|
fn destroy(&self) {
|
||||||
|
// Nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the attributes of a filesystem entry.
|
||||||
|
///
|
||||||
|
/// * `fh`: a file handle if this is called on an open file.
|
||||||
|
fn getattr(&self, _req: RequestInfo, path: &Path, _fh: Option<u64>) -> ResultEntry {
|
||||||
|
let request = tonic::Request::new(Getattr {
|
||||||
|
path : path.to_str().unwrap().into(),
|
||||||
|
fi : FileInfo {
|
||||||
|
|
||||||
|
},
|
||||||
|
..Getattr::default()
|
||||||
|
});
|
||||||
|
let response = self.async_rt.block_on(self.rpc.borrow_mut().fgetattr(request));
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following operations in the FUSE C API are all one kernel call: setattr
|
||||||
|
// We split them out to match the C API's behavior.
|
||||||
|
|
||||||
|
/// Change the mode of a filesystem entry.
|
||||||
|
///
|
||||||
|
/// * `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::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Change the owner UID and/or group GID of a filesystem entry.
|
||||||
|
///
|
||||||
|
/// * `fh`: a file handle if this is called on an open file.
|
||||||
|
/// * `uid`: user ID to change the file's owner to. If `None`, leave the UID unchanged.
|
||||||
|
/// * `gid`: group ID to change the file's group to. If `None`, leave the GID unchanged.
|
||||||
|
fn chown(&self, _req: RequestInfo, _path: &Path, _fh: Option<u64>, _uid: Option<u32>, _gid: Option<u32>) -> ResultEmpty {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the length of a file.
|
||||||
|
///
|
||||||
|
/// * `fh`: a file handle if this is called on an open file.
|
||||||
|
/// * `size`: size in bytes to set as the file's length.
|
||||||
|
fn truncate(&self, _req: RequestInfo, _path: &Path, _fh: Option<u64>, _size: u64) -> ResultEmpty {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set timestamps of a filesystem entry.
|
||||||
|
///
|
||||||
|
/// * `fh`: a file handle if this is called on an open file.
|
||||||
|
/// * `atime`: the time of last access.
|
||||||
|
/// * `mtime`: the time of last modification.
|
||||||
|
fn utimens(&self, _req: RequestInfo, _path: &Path, _fh: Option<u64>, _atime: Option<SystemTime>, _mtime: Option<SystemTime>) -> ResultEmpty {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set timestamps of a filesystem entry (with extra options only used on MacOS).
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
fn utimens_macos(&self, _req: RequestInfo, _path: &Path, _fh: Option<u64>, _crtime: Option<SystemTime>, _chgtime: Option<SystemTime>, _bkuptime: Option<SystemTime>, _flags: Option<u32>) -> ResultEmpty {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
// END OF SETATTR FUNCTIONS
|
||||||
|
|
||||||
|
/// Read a symbolic link.
|
||||||
|
fn readlink(&self, _req: RequestInfo, _path: &Path) -> ResultData {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a special file.
|
||||||
|
///
|
||||||
|
/// * `parent`: path to the directory to make the entry under.
|
||||||
|
/// * `name`: name of the entry.
|
||||||
|
/// * `mode`: mode for the new entry.
|
||||||
|
/// * `rdev`: if mode has the bits `S_IFCHR` or `S_IFBLK` set, this is the major and minor numbers for the device file. Otherwise it should be ignored.
|
||||||
|
fn mknod(&self, _req: RequestInfo, _parent: &Path, _name: &OsStr, _mode: u32, _rdev: u32) -> ResultEntry {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a directory.
|
||||||
|
///
|
||||||
|
/// * `parent`: path to the directory to make the directory under.
|
||||||
|
/// * `name`: name of the directory.
|
||||||
|
/// * `mode`: permissions for the new directory.
|
||||||
|
fn mkdir(&self, _req: RequestInfo, _parent: &Path, _name: &OsStr, _mode: u32) -> ResultEntry {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove a file.
|
||||||
|
///
|
||||||
|
/// * `parent`: path to the directory containing the file to delete.
|
||||||
|
/// * `name`: name of the file to delete.
|
||||||
|
fn unlink(&self, _req: RequestInfo, _parent: &Path, _name: &OsStr) -> ResultEmpty {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove a directory.
|
||||||
|
///
|
||||||
|
/// * `parent`: path to the directory containing the directory to delete.
|
||||||
|
/// * `name`: name of the directory to delete.
|
||||||
|
fn rmdir(&self, _req: RequestInfo, _parent: &Path, _name: &OsStr) -> ResultEmpty {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a symbolic link.
|
||||||
|
///
|
||||||
|
/// * `parent`: path to the directory to make the link in.
|
||||||
|
/// * `name`: name of the symbolic link.
|
||||||
|
/// * `target`: path (may be relative or absolute) to the target of the link.
|
||||||
|
fn symlink(&self, _req: RequestInfo, _parent: &Path, _name: &OsStr, _target: &Path) -> ResultEntry {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Rename a filesystem entry.
|
||||||
|
///
|
||||||
|
/// * `parent`: path to the directory containing the existing entry.
|
||||||
|
/// * `name`: name of the existing entry.
|
||||||
|
/// * `newparent`: path to the directory it should be renamed into (may be the same as `parent`).
|
||||||
|
/// * `newname`: name of the new entry.
|
||||||
|
fn rename(&self, _req: RequestInfo, _parent: &Path, _name: &OsStr, _newparent: &Path, _newname: &OsStr) -> ResultEmpty {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a hard link.
|
||||||
|
///
|
||||||
|
/// * `path`: path to an existing file.
|
||||||
|
/// * `newparent`: path to the directory for the new link.
|
||||||
|
/// * `newname`: name for the new link.
|
||||||
|
fn link(&self, _req: RequestInfo, _path: &Path, _newparent: &Path, _newname: &OsStr) -> ResultEntry {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Open a file.
|
||||||
|
///
|
||||||
|
/// * `path`: path to the file.
|
||||||
|
/// * `flags`: one of `O_RDONLY`, `O_WRONLY`, or `O_RDWR`, plus maybe additional flags.
|
||||||
|
///
|
||||||
|
/// Return a tuple of (file handle, flags). The file handle will be passed to any subsequent
|
||||||
|
/// 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 {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read from a file.
|
||||||
|
///
|
||||||
|
/// Note that it is not an error for this call to request to read past the end of the file, and
|
||||||
|
/// you should only return data up to the end of the file (i.e. the number of bytes returned
|
||||||
|
/// will be fewer than requested; possibly even zero). Do not extend the file in this case.
|
||||||
|
///
|
||||||
|
/// * `path`: path to the file.
|
||||||
|
/// * `fh`: file handle returned from the `open` call.
|
||||||
|
/// * `offset`: offset into the file to stasync_rt reading.
|
||||||
|
/// * `size`: number of bytes to read.
|
||||||
|
/// * `callback`: a callback that must be invoked to return the result of the operation: either
|
||||||
|
/// the result data as a slice, or an error code.
|
||||||
|
///
|
||||||
|
/// Return the return value from the `callback` function.
|
||||||
|
fn read(&self, _req: RequestInfo, _path: &Path, _fh: u64, _offset: u64, _size: u32, callback: impl FnOnce(ResultSlice<'_>) -> CallbackResult) -> CallbackResult {
|
||||||
|
callback(Err(libc::ENOSYS))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write to a file.
|
||||||
|
///
|
||||||
|
/// * `path`: path to the file.
|
||||||
|
/// * `fh`: file handle returned from the `open` call.
|
||||||
|
/// * `offset`: offset into the file to stasync_rt writing.
|
||||||
|
/// * `data`: the data to write
|
||||||
|
/// * `flags`:
|
||||||
|
///
|
||||||
|
/// Return the number of bytes written.
|
||||||
|
fn write(&self, _req: RequestInfo, _path: &Path, _fh: u64, _offset: u64, _data: Vec<u8>, _flags: u32) -> ResultWrite {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called each time a program calls `close` on an open file.
|
||||||
|
///
|
||||||
|
/// Note that because file descriptors can be duplicated (by `dup`, `dup2`, `fork`) this may be
|
||||||
|
/// called multiple times for a given file handle. The main use of this function is if the
|
||||||
|
/// filesystem would like to return an error to the `close` call. Note that most programs
|
||||||
|
/// ignore the return value of `close`, though.
|
||||||
|
///
|
||||||
|
/// * `path`: path to the file.
|
||||||
|
/// * `fh`: file handle returned from the `open` call.
|
||||||
|
/// * `lock_owner`: if the filesystem supports locking (`setlk`, `getlk`), remove all locks
|
||||||
|
/// belonging to this lock owner.
|
||||||
|
fn flush(&self, _req: RequestInfo, _path: &Path, _fh: u64, _lock_owner: u64) -> ResultEmpty {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called when an open file is closed.
|
||||||
|
///
|
||||||
|
/// There will be one of these for each `open` call. After `release`, no more calls will be
|
||||||
|
/// made with the given file handle.
|
||||||
|
///
|
||||||
|
/// * `path`: path to the file.
|
||||||
|
/// * `fh`: file handle returned from the `open` call.
|
||||||
|
/// * `flags`: the flags passed when the file was opened.
|
||||||
|
/// * `lock_owner`: if the filesystem supports locking (`setlk`, `getlk`), remove all locks
|
||||||
|
/// belonging to this lock owner.
|
||||||
|
/// * `flush`: whether pending data must be flushed or not.
|
||||||
|
fn release(&self, _req: RequestInfo, _path: &Path, _fh: u64, _flags: u32, _lock_owner: u64, _flush: bool) -> ResultEmpty {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write out any pending changes of a file.
|
||||||
|
///
|
||||||
|
/// When this returns, data should be written to persistent storage.
|
||||||
|
///
|
||||||
|
/// * `path`: path to the file.
|
||||||
|
/// * `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::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Open a directory.
|
||||||
|
///
|
||||||
|
/// Analogous to the `opend` call.
|
||||||
|
///
|
||||||
|
/// * `path`: path to the directory.
|
||||||
|
/// * `flags`: file access flags. Will contain `O_DIRECTORY` at least.
|
||||||
|
///
|
||||||
|
/// Return a tuple of (file handle, flags). The file handle will be passed to any subsequent
|
||||||
|
/// 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 {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the entries of a directory.
|
||||||
|
///
|
||||||
|
/// * `path`: path to the directory.
|
||||||
|
/// * `fh`: file handle returned from the `opendir` call.
|
||||||
|
///
|
||||||
|
/// Return all the entries of the directory.
|
||||||
|
fn readdir(&self, _req: RequestInfo, _path: &Path, _fh: u64) -> ResultReaddir {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Close an open directory.
|
||||||
|
///
|
||||||
|
/// This will be called exactly once for each `opendir` call.
|
||||||
|
///
|
||||||
|
/// * `path`: path to the directory.
|
||||||
|
/// * `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 {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write out any pending changes to a directory.
|
||||||
|
///
|
||||||
|
/// Analogous to the `fsync` call.
|
||||||
|
fn fsyncdir(&self, _req: RequestInfo, _path: &Path, _fh: u64, _datasync: bool) -> ResultEmpty {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get filesystem statistics.
|
||||||
|
///
|
||||||
|
/// * `path`: path to some folder in the filesystem.
|
||||||
|
///
|
||||||
|
/// See the `Statfs` struct for more details.
|
||||||
|
fn statfs(&self, _req: RequestInfo, _path: &Path) -> ResultStatfs {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set a file extended attribute.
|
||||||
|
///
|
||||||
|
/// * `path`: path to the file.
|
||||||
|
/// * `name`: attribute name.
|
||||||
|
/// * `value`: the data to set the value to.
|
||||||
|
/// * `flags`: can be either `XATTR_CREATE` or `XATTR_REPLACE`.
|
||||||
|
/// * `position`: offset into the attribute value to write data.
|
||||||
|
fn setxattr(&self, _req: RequestInfo, _path: &Path, _name: &OsStr, _value: &[u8], _flags: u32, _position: u32) -> ResultEmpty {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a file extended attribute.
|
||||||
|
///
|
||||||
|
/// * `path`: path to the file
|
||||||
|
/// * `name`: attribute name.
|
||||||
|
/// * `size`: the maximum number of bytes to read.
|
||||||
|
///
|
||||||
|
/// 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::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// List extended attributes for a file.
|
||||||
|
///
|
||||||
|
/// * `path`: path to the file.
|
||||||
|
/// * `size`: maximum number of bytes to return.
|
||||||
|
///
|
||||||
|
/// If `size` is 0, return `Xattr::Size(n)` where `n` is the size required for the list of
|
||||||
|
/// attribute names.
|
||||||
|
/// 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::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove an extended attribute for a file.
|
||||||
|
///
|
||||||
|
/// * `path`: path to the file.
|
||||||
|
/// * `name`: name of the attribute to remove.
|
||||||
|
fn removexattr(&self, _req: RequestInfo, _path: &Path, _name: &OsStr) -> ResultEmpty {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check for access to a file.
|
||||||
|
///
|
||||||
|
/// * `path`: path to the file.
|
||||||
|
/// * `mask`: mode bits to check for access to.
|
||||||
|
///
|
||||||
|
/// 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 {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create and open a new file.
|
||||||
|
///
|
||||||
|
/// * `parent`: path to the directory to create the file in.
|
||||||
|
/// * `name`: name of the file to be created.
|
||||||
|
/// * `mode`: the mode to set on the new file.
|
||||||
|
/// * `flags`: flags like would be passed to `open`.
|
||||||
|
///
|
||||||
|
/// Return a `CreatedEntry` (which contains the new file's attributes as well as a file handle
|
||||||
|
/// -- see documentation on `open` for more info on that).
|
||||||
|
fn create(&self, _req: RequestInfo, _parent: &Path, _name: &OsStr, _mode: u32, _flags: u32) -> ResultCreate {
|
||||||
|
Err(libc::ENOSYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
use std::env;
|
||||||
impl LwsVfsIns {
|
impl LwsVfsIns {
|
||||||
pub async fn new(json: &str) -> Result<LwsVfsIns, Box<dyn Error>> {
|
pub async fn new(json: &str) -> Result<LwsVfsIns, Box<dyn Error>> {
|
||||||
let config = Config::new(json)?;
|
let config = Config::new(json)?;
|
||||||
let addr = format!("http://{}:{}", config.get_addr(), config.get_port());
|
let addr = format!("http://{}:{}", config.get_addr(), config.get_port());
|
||||||
//connect to server
|
//connect to server
|
||||||
let rpc = LwsVfsClient::connect(addr).await?;
|
let rpc = RefCell::new(LwsVfsClient::connect(addr).await?);
|
||||||
|
let async_rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
Ok(LwsVfsIns {
|
Ok(LwsVfsIns {
|
||||||
config,
|
config,
|
||||||
rpc,
|
rpc,
|
||||||
|
async_rt,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub async fn hello(&mut self) -> Result<(), Box<dyn Error>> {
|
pub fn hello(&self) -> Result<(), Box<dyn Error>> {
|
||||||
let request = tonic::Request::new(HelloRequest {
|
let request = tonic::Request::new(HelloRequest {
|
||||||
name: "Ekko lws hello".into(),
|
name: "Ekko lws hello".into(),
|
||||||
});
|
});
|
||||||
let response = &self.rpc.say_hello(request).await?;
|
let response = self.async_rt.block_on(self.rpc.borrow_mut().say_hello(request))?;
|
||||||
|
|
||||||
println!("RESPONSE={:?}", response);
|
println!("RESPONSE={:?}", response);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
pub fn mount<FS:Filesystem>(file_system:FS) -> Result<(), Box<dyn Error>> {
|
|
||||||
let mountpoint = "/mnt";
|
pub fn mount<F>(file_system:F) -> Result<(), Box<dyn Error>>
|
||||||
let options = vec![MountOption::RO, MountOption::FSName("lws_fs".to_string())];
|
where
|
||||||
fuser::mount2(file_system, mountpoint, &options).unwrap();
|
F: FilesystemMT + Sync + Send + 'static
|
||||||
|
{
|
||||||
|
let args: Vec<OsString> = env::args_os().collect();
|
||||||
|
let fuse_args = [OsStr::new("-o"), OsStr::new("fsname=passthrufs")];
|
||||||
|
fuse_mt::mount(fuse_mt::FuseMT::new(file_system, 1), &args[2], &fuse_args[..])?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user