Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ef45e76
fix: do not remove inode until forgotten
khanhtranngoccva Dec 4, 2025
8079dd0
Merge branch 'devel'
khanhtranngoccva Dec 4, 2025
06ea2c8
fix: child inode should be present when moved inside an empty inode
khanhtranngoccva Dec 4, 2025
4f27059
Merge pull request #66 from Alogani/devel
Alogani Dec 17, 2025
ca67063
Merge branch 'Alogani:main' into main
khanhtranngoccva Dec 18, 2025
2f57612
test: add test for preventing premature inode removals
khanhtranngoccva Dec 18, 2025
4573fa0
feat: add resolver to support persistent hard links
khanhtranngoccva Jan 13, 2026
469c9eb
misc: remove extraneous todo
khanhtranngoccva Jan 13, 2026
90b7ec4
fix: orphaned inodes should be acknowledged
khanhtranngoccva Jan 13, 2026
e7393e8
fix: revert to old behavior in path and component resolver
khanhtranngoccva Jan 13, 2026
82e57d4
fix: reduce output when using debug trait on hybrid id
khanhtranngoccva Jan 14, 2026
8d6f838
fix: specifying a new backing ID should always resolve to a new inode
khanhtranngoccva Jan 14, 2026
a85505c
misc: remove debug assertions
khanhtranngoccva Jan 14, 2026
26712e7
feat: deterministically compute inode depending on backing ID
khanhtranngoccva Jan 15, 2026
e3cbab1
feat: separate thread pool for processing FUSE replies
khanhtranngoccva Jan 16, 2026
8041fca
Merge branch 'devel' of https://github.com/khanhtranngoccva/easy_fuse…
khanhtranngoccva Jan 16, 2026
933f5ac
breaking-feat: passthrough API
khanhtranngoccva Jan 16, 2026
abdece6
fix: remove extra incompatible backing ID import
khanhtranngoccva Jan 16, 2026
08f6d23
fix: repair gated features
khanhtranngoccva Jan 16, 2026
8e73e9e
Merge branch 'hard-link-support' into devel
khanhtranngoccva Jan 16, 2026
4f8032a
Merge branch 'reply-thread-pool' into devel
khanhtranngoccva Jan 16, 2026
02de10e
misc: merge conflict fix
khanhtranngoccva Jan 16, 2026
20d98c0
fix: minor dead code suppressions
khanhtranngoccva Jan 16, 2026
3290118
Merge branch 'passthrough' into devel
khanhtranngoccva Jan 16, 2026
1454b2f
feat: enable passthrough for file creates
khanhtranngoccva Jan 20, 2026
7c7dfdc
misc: merge async reply with passthrough feature
khanhtranngoccva Jan 20, 2026
52d5590
feat: add weak variant for passthrough backing IDs to allow reuse
khanhtranngoccva Jan 20, 2026
881fe4a
Merge branch 'passthrough' into devel
khanhtranngoccva Jan 20, 2026
4218af5
Merge branch 'devel' of https://github.com/Alogani/easy_fuser
khanhtranngoccva Jan 20, 2026
dbaf2e2
feat: Add comparison traits to flags
khanhtranngoccva Jan 20, 2026
35fbeef
Merge branch 'flag-cmp-hash' into bleeding-edge
khanhtranngoccva Jan 20, 2026
ff2d063
feat: add stub weak pointer for parity with weak api
khanhtranngoccva Jan 20, 2026
bb29fa5
Merge branch 'passthrough' into bleeding-edge
khanhtranngoccva Jan 20, 2026
8cd1605
fix: add API parity
khanhtranngoccva Jan 21, 2026
9b22171
example: example fixes for new bleeding edge API
khanhtranngoccva Jan 22, 2026
a5b09dd
doc: add kernel caveat to passthrough ID
khanhtranngoccva Jan 26, 2026
6be8204
fix: minor doc and ide flag fixes
khanhtranngoccva Jan 26, 2026
8ca3ccf
fix: open_backing should not require object ownership
khanhtranngoccva Jan 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"rust-analyzer.cargo.features": ["serial"]
"rust-analyzer.cargo.features": ["serial", "passthrough"]
}
9 changes: 7 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ serial = []
parallel = ["dep:threadpool"]
async = ["dep:async-trait", "dep:tokio"]
deadlock_detection = ["parallel", "dep:parking_lot"]

passthrough = ["fuser/abi-7-40"]

[dependencies]
# Core dependencies
log = "0.4"
libc = "0.2"
fuser = "0.16"
fuser = { version = "0.16" }
bitflags = "2.10"

# Parallel dependencies
Expand All @@ -32,10 +32,15 @@ parking_lot = { version = "0.12", features = ["deadlock_detection"], optional =
# easy_fuser_async_macro = { path = "./easy_fuser_async_macro", optional = true }
tokio = { version = "1.48", features = ["full"], optional = true }
async-trait = { version = "0.1.89", optional = true }
bimap = { version = "0.6.3", features = ["std"] }

[dev-dependencies]
tempfile = "3.23"
env_logger = "0.11"

[package.metadata.docs.rs]
features = ["parallel"]

[patch.crates-io]
# Bleeding edge patch for FUSE create() passthrough, will be removed when patch is merged
fuser = { git = "https://github.com/khanhtranngoccva/fuser", branch = "passthrough" }
6 changes: 5 additions & 1 deletion examples/ftp_fs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ tempfile = "3.2"
libunftp = "0.20"
unftp-sbe-fs = "0.2"
async-trait = "0.1.68"
tokio = { version = "1.42", features = ["full"] }
tokio = { version = "1.42", features = ["full"] }

[patch.crates-io]
# Bleeding edge patch for FUSE create() passthrough, will be removed when patch is merged
fuser = { git = "https://github.com/khanhtranngoccva/fuser", branch = "passthrough" }
5 changes: 3 additions & 2 deletions examples/ftp_fs/src/filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,9 @@ impl FuseHandler<PathBuf> for FtpFs {
_file_handle: BorrowedFileHandle,
offset: SeekFrom,
size: u32,
_flags: FUSEOpenFlags,
_lock_owner: Option<u64>,
_read_flags: FUSEReadFlags,
_flags: OpenFlags,
_lock_owner: Option<LockOwner>,
) -> FuseResult<Vec<u8>> {
self.with_ftp(|ftp| {
let mut cursor = ftp.retr_as_buffer(file_id.to_str().unwrap())?;
Expand Down
6 changes: 5 additions & 1 deletion examples/hello_fs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ logging = ["dep:env_logger", "dep:log"]
[dependencies]
easy_fuser = { path = "../..", features = ["serial"] }
log = { version = "0.4", optional = true }
env_logger = { version = "0.11", optional = true }
env_logger = { version = "0.11", optional = true }

[patch.crates-io]
# Bleeding edge patch for FUSE create() passthrough, will be removed when patch is merged
fuser = { git = "https://github.com/khanhtranngoccva/fuser", branch = "passthrough" }
7 changes: 4 additions & 3 deletions examples/hello_fs/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const HELLO_DIR_ATTR: (Inode, FileAttribute) = (
const HELLO_TXT_CONTENT: &str = "Hello World!\n";

const HELLO_TXT_ATTR: (Inode, FileAttribute) = (
Inode::from(2),
Inode::new(2),
FileAttribute {
size: 13,
blocks: 1,
Expand Down Expand Up @@ -110,8 +110,9 @@ impl FuseHandler<Inode> for HelloFS {
_file_handle: BorrowedFileHandle,
seek: SeekFrom,
size: u32,
_flags: FUSEOpenFlags,
_lock_owner: Option<u64>,
_read_flags: FUSEReadFlags,
_flags: OpenFlags,
_lock_owner: Option<LockOwner>,
) -> FuseResult<Vec<u8>> {
if file_id == HELLO_TXT_ATTR.0 {
let offset = match seek {
Expand Down
6 changes: 5 additions & 1 deletion examples/in_memory_fs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,8 @@ logging = ["dep:env_logger", "dep:log"]
[dependencies]
easy_fuser = { path = "../..", features = ["parallel"] }
log = { version = "0.4", optional = true }
env_logger = { version = "0.11", optional = true }
env_logger = { version = "0.11", optional = true }

[patch.crates-io]
# Bleeding edge patch for FUSE create() passthrough, will be removed when patch is merged
fuser = { git = "https://github.com/khanhtranngoccva/fuser", branch = "passthrough" }
12 changes: 8 additions & 4 deletions examples/in_memory_fs/src/filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,13 @@ impl FuseHandler<Inode> for InMemoryFS {
mode: u32,
_umask: u32,
_flags: OpenFlags,
_helper: CreateHelper<'_>,
) -> Result<
(
OwnedFileHandle,
(Inode, FileAttribute),
FUSEOpenResponseFlags,
Option<PassthroughBackingId>,
),
PosixError,
> {
Expand Down Expand Up @@ -204,6 +206,7 @@ impl FuseHandler<Inode> for InMemoryFS {
unsafe { OwnedFileHandle::from_raw(0) },
(new_inode.clone(), attr),
FUSEOpenResponseFlags::empty(),
None,
))
} else {
Err(ErrorKind::FileNotFound.to_error(""))
Expand Down Expand Up @@ -260,7 +263,7 @@ impl FuseHandler<Inode> for InMemoryFS {
_req: &RequestInfo,
_file_id: Inode,
_file_handle: BorrowedFileHandle,
_lock_owner: u64,
_lock_owner: LockOwner,
) -> FuseResult<()> {
Ok(())
}
Expand Down Expand Up @@ -363,8 +366,9 @@ impl FuseHandler<Inode> for InMemoryFS {
_fh: BorrowedFileHandle,
offset: SeekFrom,
size: u32,
_flags: FUSEOpenFlags,
_lock_owner: Option<u64>,
_read_flags: FUSEReadFlags,
_flags: OpenFlags,
_lock_owner: Option<LockOwner>,
) -> FuseResult<Vec<u8>> {
self.access(req, ino.clone(), AccessMask::CAN_READ)?;
let fs = self.fs.lock().unwrap();
Expand Down Expand Up @@ -579,7 +583,7 @@ impl FuseHandler<Inode> for InMemoryFS {
data: Vec<u8>,
_write_flags: FUSEWriteFlags,
_flags: OpenFlags,
_lock_owner: Option<u64>,
_lock_owner: Option<LockOwner>,
) -> FuseResult<u32> {
self.access(req, ino.clone(), AccessMask::CAN_WRITE)?;
let mut fs = self.fs.lock().unwrap();
Expand Down
49 changes: 15 additions & 34 deletions examples/in_memory_fs/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#![doc = include_str!("../README.md")]

use easy_fuser::prelude::*;
use std::ffi::OsStr;
use std::fs::File;
use std::io::Write;
use std::path::Path;

const README_CONTENT: &[u8] = include_bytes!("../README.md") as &[u8];
Expand All @@ -11,38 +12,8 @@ pub use filesystem::InMemoryFS;

fn create_memory_fs() -> InMemoryFS {
let memoryfs = InMemoryFS::new();
#[cfg(feature = "readme")]
{
// An example of interacting directly with the filesystem
let request_info = RequestInfo {
id: 0,
uid: 0,
gid: 0,
pid: 0,
}; // dummy RequestInfo
let (fd, (inode, _), _) = memoryfs
.create(
&request_info,
ROOT_INODE,
OsStr::new("README.md"),
0o755,
0,
OpenFlags::empty(),
)
.unwrap();
let _ = memoryfs
.write(
&request_info,
inode,
fd.borrow(),
SeekFrom::Start(0),
README_CONTENT.to_vec(),
FUSEWriteFlags::empty(),
OpenFlags::empty(),
None,
)
.unwrap();
}
// NOTE: manual call example here is removed because the [`CreateHelper`]
// parameter is not supported
memoryfs
}

Expand All @@ -66,5 +37,15 @@ fn main() {
let memoryfs = create_memory_fs();

println!("Mounting filesystem...");
easy_fuser::mount(memoryfs, Path::new(&mountpoint), &options, 1).unwrap();
let session = easy_fuser::spawn_mount(memoryfs, Path::new(&mountpoint), &options, 1).unwrap();
// Insert the readme here
#[cfg(feature = "readme")]
File::create(Path::new(&mountpoint).join("README.md"))
.unwrap()
.write_all(README_CONTENT)
.unwrap();
let mut wait_string = String::new();
println!("Press Enter to unmount...");
std::io::stdin().read_line(&mut wait_string).unwrap();
session.unmount_and_join().unwrap();
}
6 changes: 5 additions & 1 deletion examples/passthrough_fs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@ description = "A FUSE passthrough filesystem example using easy_fuser"
[dependencies]
easy_fuser = { path = "../..", features = ["parallel"] }
clap = { version = "4.5", features = ["derive"] }
ctrlc = "3.4"
ctrlc = "3.4"

[patch.crates-io]
# Bleeding edge patch for FUSE create() passthrough, will be removed when patch is merged
fuser = { git = "https://github.com/khanhtranngoccva/fuser", branch = "passthrough" }
4 changes: 4 additions & 0 deletions examples/random_fs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ edition = "2021"
[dependencies]
easy_fuser = { path = "../..", features = ["parallel"] }
rand = "0.8.5"

[patch.crates-io]
# Bleeding edge patch for FUSE create() passthrough, will be removed when patch is merged
fuser = { git = "https://github.com/khanhtranngoccva/fuser", branch = "passthrough" }
10 changes: 7 additions & 3 deletions examples/random_fs/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,13 @@ impl FuseHandler<Inode> for RandomFS {
_mode: u32,
_umask: u32,
_flags: OpenFlags,
_helper: CreateHelper<'_>,
) -> Result<
(
OwnedFileHandle,
(Inode, FileAttribute),
FUSEOpenResponseFlags,
Option<PassthroughBackingId>,
),
PosixError,
> {
Expand All @@ -93,6 +95,7 @@ impl FuseHandler<Inode> for RandomFS {
unsafe { OwnedFileHandle::from_raw(0) },
(ino, attr),
FUSEOpenResponseFlags::empty(),
None,
))
}

Expand Down Expand Up @@ -171,8 +174,9 @@ impl FuseHandler<Inode> for RandomFS {
_fh: BorrowedFileHandle,
offset: SeekFrom,
size: u32,
_flags: FUSEOpenFlags,
_lock_owner: Option<u64>,
_read_flags: FUSEReadFlags,
_flags: OpenFlags,
_lock_owner: Option<LockOwner>,
) -> FuseResult<Vec<u8>> {
let mut rng = rand::thread_rng();
let lines = rng.gen_range(0..81);
Expand Down Expand Up @@ -238,7 +242,7 @@ impl FuseHandler<Inode> for RandomFS {
data: Vec<u8>,
_write_flags: FUSEWriteFlags,
_flags: OpenFlags,
_lock_owner: Option<u64>,
_lock_owner: Option<LockOwner>,
) -> FuseResult<u32> {
Ok(data.len() as u32)
}
Expand Down
4 changes: 4 additions & 0 deletions examples/zip_fs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ ctrlc = "3.4"

[dev-dependencies]
tempfile = "3.2"

[patch.crates-io]
# Bleeding edge patch for FUSE create() passthrough, will be removed when patch is merged
fuser = { git = "https://github.com/khanhtranngoccva/fuser", branch = "passthrough" }
5 changes: 3 additions & 2 deletions examples/zip_fs/src/filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,9 @@ impl FuseHandler<Inode> for ZipFs {
_file_handle: BorrowedFileHandle,
seek: SeekFrom,
size: u32,
_flags: FUSEOpenFlags,
_lock_owner: Option<u64>,
_read_flags: FUSEReadFlags,
_flags: OpenFlags,
_lock_owner: Option<LockOwner>,
) -> FuseResult<Vec<u8>> {
let InodeInfo {
parent: _,
Expand Down
Loading