From 51b376065ffe7cad0004a9e6a7853307f3bbaf0d Mon Sep 17 00:00:00 2001 From: Inoki Date: Sun, 31 Dec 2023 02:47:10 +0100 Subject: [PATCH] feat(ofs): implement ofs based on fuse3 (#3857) --- Cargo.lock | 82 ++++++++++++++---- bin/ofs/Cargo.toml | 5 ++ bin/ofs/src/lib.rs | 207 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 276 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0b8d6b18d8f..72cbb36da33 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -403,9 +403,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.74" +version = "0.1.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "fdf6721fb0140e4f897002dd086c06f6c27775df19cfe1fccb21181a48fd2c98" dependencies = [ "proc-macro2", "quote", @@ -1761,6 +1761,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "cstr" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8aa998c33a6d3271e3678950a22134cd7dd27cef86dee1b611b5b14207d1d90b" +dependencies = [ + "proc-macro2", + "quote", +] + [[package]] name = "ctor" version = "0.1.26" @@ -2636,6 +2646,26 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +[[package]] +name = "fuse3" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8aaac75c1369ee81ed34a8e26216258126a3c555bfc85e49eb33b5e239fd182e" +dependencies = [ + "async-trait", + "bincode", + "bytes", + "cstr", + "futures-channel", + "futures-util", + "libc", + "nix", + "serde", + "slab", + "tokio", + "tracing", +] + [[package]] name = "futures" version = "0.3.29" @@ -2653,9 +2683,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -2663,9 +2693,9 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" @@ -2680,9 +2710,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-lite" @@ -2715,9 +2745,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", @@ -2726,15 +2756,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-timer" @@ -2744,9 +2774,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -3524,9 +3554,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.150" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "libfuzzer-sys" @@ -4247,6 +4277,17 @@ dependencies = [ "tempfile", ] +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", +] + [[package]] name = "no-std-compat" version = "0.4.1" @@ -4438,6 +4479,11 @@ dependencies = [ name = "ofs" version = "0.0.1" dependencies = [ + "async-trait", + "fuse3", + "futures-util", + "libc", + "log", "opendal", ] diff --git a/bin/ofs/Cargo.toml b/bin/ofs/Cargo.toml index 03becbfa540..1829f078820 100644 --- a/bin/ofs/Cargo.toml +++ b/bin/ofs/Cargo.toml @@ -30,4 +30,9 @@ repository.workspace = true rust-version.workspace = true [dependencies] +async-trait = "0.1.75" +fuse3 = { "version" = "0.6.1", "features" = ["tokio-runtime"] } +futures-util = "0.3.30" +libc = "0.2.151" +log = "0.4.20" opendal.workspace = true diff --git a/bin/ofs/src/lib.rs b/bin/ofs/src/lib.rs index b248758bc12..bff825fb5d3 100644 --- a/bin/ofs/src/lib.rs +++ b/bin/ofs/src/lib.rs @@ -14,3 +14,210 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. + +use fuse3::path::prelude::*; +use fuse3::Result; + +use async_trait::async_trait; +use futures_util::stream::{Empty, Iter}; +use std::ffi::OsStr; +use std::vec::IntoIter; + +use opendal::Operator; + +pub struct Ofs { + pub op: Operator, +} + +#[async_trait] +impl PathFilesystem for Ofs { + type DirEntryStream = Empty>; + type DirEntryPlusStream = Iter>>; + + // Init a fuse filesystem + async fn init(&self, _req: Request) -> Result<()> { + Ok(()) + } + + // Callback when fs is being destroyed + async fn destroy(&self, _req: Request) {} + + async fn lookup(&self, _req: Request, _parent: &OsStr, _name: &OsStr) -> Result { + // TODO + Err(libc::ENOSYS.into()) + } + + async fn getattr( + &self, + _req: Request, + path: Option<&OsStr>, + _fh: Option, + _flags: u32, + ) -> Result { + // TODO + log::debug!("getattr(path={:?})", path); + + Err(libc::ENOSYS.into()) + } + + async fn read( + &self, + _req: Request, + path: Option<&OsStr>, + fh: u64, + offset: u64, + size: u32, + ) -> Result { + // TODO + log::debug!( + "read(path={:?}, fh={}, offset={}, size={})", + path, + fh, + offset, + size + ); + + Err(libc::ENOSYS.into()) + } + + async fn mkdir( + &self, + _req: Request, + parent: &OsStr, + name: &OsStr, + mode: u32, + _umask: u32, + ) -> Result { + // TODO + log::debug!( + "mkdir(parent={:?}, name={:?}, mode=0o{:o})", + parent, + name, + mode + ); + + Err(libc::ENOSYS.into()) + } + + async fn readdir( + &self, + _req: Request, + path: &OsStr, + fh: u64, + offset: i64, + ) -> Result> { + // TODO + log::debug!("readdir(path={:?}, fh={}, offset={})", path, fh, offset); + + Err(libc::ENOSYS.into()) + } + + async fn mknod( + &self, + _req: Request, + parent: &OsStr, + name: &OsStr, + mode: u32, + _rdev: u32, + ) -> Result { + // TODO + log::debug!( + "mknod(parent={:?}, name={:?}, mode=0o{:o})", + parent, + name, + mode + ); + + Err(libc::ENOSYS.into()) + } + + async fn open(&self, _req: Request, path: &OsStr, flags: u32) -> Result { + // TODO + log::debug!("open(path={:?}, flags=0x{:x})", path, flags); + + Err(libc::ENOSYS.into()) + } + + async fn setattr( + &self, + _req: Request, + path: Option<&OsStr>, + _fh: Option, + _set_attr: SetAttr, + ) -> Result { + // TODO + log::debug!("setattr(path={:?})", path); + + Err(libc::ENOSYS.into()) + } + + async fn write( + &self, + _req: Request, + path: Option<&OsStr>, + fh: u64, + offset: u64, + data: &[u8], + flags: u32, + ) -> Result { + // TODO + log::debug!( + "write(path={:?}, fh={}, offset={}, len={}, flags=0x{:x})", + path, + fh, + offset, + data.len(), + flags + ); + + Err(libc::ENOSYS.into()) + } + + async fn release( + &self, + _req: Request, + path: Option<&OsStr>, + fh: u64, + flags: u32, + _lock_owner: u64, + flush: bool, + ) -> Result<()> { + // TODO + log::debug!( + "release(path={:?}, fh={}, flags={}, flush={})", + path, + fh, + flags, + flush + ); + + Err(libc::ENOSYS.into()) + } + + async fn rename( + &self, + _req: Request, + origin_parent: &OsStr, + origin_name: &OsStr, + parent: &OsStr, + name: &OsStr, + ) -> Result<()> { + // TODO + log::debug!( + "rename(p={:?}, name={:?}, newp={:?}, newname={:?})", + origin_parent, + origin_name, + parent, + name + ); + + Err(libc::ENOSYS.into()) + } + + async fn unlink(&self, _req: Request, parent: &OsStr, name: &OsStr) -> Result<()> { + // TODO + log::debug!("unlink(parent={:?}, name={:?})", parent, name); + + Err(libc::ENOSYS.into()) + } +}