| Crates.io | easy_fuser |
| lib.rs | easy_fuser |
| version | 0.4.2 |
| created_at | 2024-12-25 22:49:37.221719+00 |
| updated_at | 2025-09-14 16:56:17.581292+00 |
| description | A flexible and idiomatic Fuse implementation for Rust |
| homepage | https://github.com/Alogani/easy_fuser |
| repository | https://github.com/Alogani/easy_fuser |
| max_upload_size | |
| id | 1495258 |
| size | 329,230 |
easy_fuser is a high-level, ergonomic wrapper around the fuser crate, designed to simplify
the process of implementing FUSE (Filesystem in Userspace) filesystems in Rust. It abstracts away
many of the complexities, offering a more intuitive and Rust-idiomatic approach to filesystem development.
Simplified API: Provides a higher-level interface compared to fuser, reducing boilerplate
and making filesystem implementation more straightforward.
Flexible Concurrency Models: Offers three distinct concurrency models to suit different use cases and performance requirements.
Flexible File Identification: Supports both path-based and inode-based operations,
allowing you to choose between Inode, PathBuf, or Vec<OsString> as your file identifier type. This
offers flexibility in how you represent and manage file identities, suitable for different
filesystem structures and performance requirements.
Error Handling: Provides a structured error handling system, facilitating the management of filesystem-specific errors.
Composable Templates and Examples: Includes pre-built, composable templates and a comprehensive examples folder to help you get started quickly, understand various implementation patterns, and easily combine different filesystem behaviors. These templates are designed to be mixed and matched, allowing for flexible and modular filesystem creation.
easy_fuser supports two main approaches for file identification:
You can choose the approach that best fits your filesystem's needs and switch between them as necessary.
To use easy_fuser, follow these steps:
FuseHandler trait for your filesystem structure.mount or spawn_mount functions to start your filesystem.Here's a basic example:
use easy_fuser::prelude::*;
use easy_fuser::templates::DefaultFuseHandler;
use std::path::{Path, PathBuf};
struct MyFS {
inner: Box<DefaultFuseHandler>,
}
impl FuseHandler<PathBuf> for MyFS {
fn get_inner(&self) -> &dyn FuseHandler<PathBuf> {
self.inner.as_ref()
}
}
fn main() -> std::io::Result<()> {
let fs = MyFS { inner: Box::new(DefaultFuseHandler::new()) };
#[cfg(feature="serial")]
easy_fuser::mount(fs, Path::new("/mnt/myfs"), &[])?;
#[cfg(not(feature="serial"))]
easy_fuser::mount(fs, Path::new("/mnt/myfs"), &[], 4)?;
Ok(())
}
This crate provides three mutually exclusive feature flags for different concurrency models:
serial: Enables single-threaded operation. Use this for simplicity and when concurrent
access is not required. When this feature is enabled, num_threads must be set to 1.
parallel: Enables multi-threaded operation using a thread pool. This is suitable for
scenarios where you want to handle multiple filesystem operations concurrently on separate
threads. It can improve performance on multi-core systems.
async: This is not yet implemented Enables asynchronous operation. This is ideal for high-concurrency scenarios and
when you want to integrate the filesystem with asynchronous Rust code. It allows for
efficient handling of many concurrent operations without the overhead of threads.
You must enable exactly one of these features when using this crate. The choice depends on your specific use case and performance requirements.
Example usage in Cargo.toml:
[dependencies]
easy_fuser = { version = "0.1.0", features = ["parallel"] }
By leveraging easy_fuser, you can focus more on your filesystem's logic and less on the
intricacies of FUSE implementation, making it easier to create robust, efficient, and
maintainable filesystem solutions in Rust.
easy_fuser provides a set of templates to help you get started quickly:
These templates serve as composable building blocks, allowing you to mix and match functionalities to create custom, complex filesystem implementations with ease. You can use them as starting points, extend them, or combine multiple templates to achieve the desired behavior for your filesystem.
Please check the README inside the examples folder for additional details and references.
When working with these examples, be aware of the following:
To properly unmount the filesystem and stop the program (or to resolve a bad state after a crash), use the following command:
fusermount -u <mountpoint>
This is the preferred method for both unmounting and resolving any issues with the mountpoint. You will find more information at the documentation of mount and spawn_mount
libfuse and by extension fuser contains a lot of flags as arguments. I tried to identify them as much of possible, but cannot guarantee it due to the lack of clear documentation on this subject.