Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions src/errno.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::io::Error as IoError;
use std::os::raw::c_int;

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
/// linux errno wrap.
/// linux errno wrapper.
pub struct Errno(c_int);

impl From<Errno> for c_int {
Expand All @@ -19,7 +19,7 @@ impl From<c_int> for Errno {
}
}

/// When raw os error is undefined, will return Errno(libc::EIO)
/// When raw os error is undefined, will return `Errno(libc::EIO)`
impl From<IoError> for Errno {
fn from(err: IoError) -> Self {
if let Some(errno) = err.raw_os_error() {
Expand Down
8 changes: 4 additions & 4 deletions src/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ pub fn get_first_null_position(data: impl AsRef<[u8]>) -> Option<usize> {
data.as_ref().iter().position(|char| *char == 0)
}

// Some platforms like Linux x86_64 have mode_t = u32, and lint warns of a trivial_numeric_casts.
// But others like macOS x86_64 have mode_t = u16, requiring a typecast. So, just silence lint.
// Some platforms like Linux x86_64 have mode_t = u32, and linters warn of a trivial_numeric_casts.
// But others like macOS x86_64 have mode_t = u16, requiring a typecast. So, just silence linters.
#[cfg(target_os = "linux")]
#[allow(trivial_numeric_casts)]
/// returns the mode for a given file kind and permission
pub const fn mode_from_kind_and_perm(kind: FileType, perm: u16) -> u32 {
kind.const_into_mode_t() | perm as mode_t
}

// Some platforms like Linux x86_64 have mode_t = u32, and lint warns of a trivial_numeric_casts.
// But others like macOS x86_64 have mode_t = u16, requiring a typecast. So, just silence lint.
// Some platforms like Linux x86_64 have mode_t = u32, and linters warn of a trivial_numeric_casts.
// But others like macOS x86_64 have mode_t = u16, requiring a typecast. So, just silence linters.
#[cfg(all(
not(target_os = "linux"),
any(target_os = "freebsd", target_os = "macos")
Expand Down
28 changes: 18 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,28 @@
//! This is an improved rewrite of the FUSE user-space library to fully take advantage of Rust's
//! architecture.
//!
//! This library doesn't depend on `libfuse`, unless enable `unprivileged` feature, this feature
//! will support mount the filesystem without root permission by using `fusermount3` binary.
//! This library doesn't depend on `libfuse`, unless the `unprivileged` feature is enabled.
//! This feature adds support for mounting the filesystem without root permission by using
//! `fusermount3` binary.
//!
//! # Features:
//!
//! - `file-lock`: enable POSIX file lock feature.
//! - `async-io-runtime`: use [async_io](https://docs.rs/async-io) and
//! [async-global-executor](https://docs.rs/async-global-executor) to drive async io and task.
//! - `tokio-runtime`: use [tokio](https://docs.rs/tokio) runtime to drive async io and task.
//! - `unprivileged`: allow mount filesystem without root permission by using `fusermount3`.
//! - `async-io-runtime`: use [async_io](https://docs.rs/async-io) or
//! [async-global-executor](https://docs.rs/async-global-executor) to drive async I/O and tasks.
//! - `tokio-runtime`: use [tokio](https://docs.rs/tokio) runtime to drive async I/O and tasks.
//! - `unprivileged`: allow mounting filesystems without root permission by using `fusermount3`.
//!
//! # Notes:
//!
//! You must enable `async-io-runtime` or `tokio-runtime` feature.
//! You must enable either the `async-io-runtime` or `tokio-runtime` features, but not both
//! or the crate won't compile.
//!
//! If you are writing a library and not an executable, beware of [feature
//! unification](https://doc.rust-lang.org/cargo/reference/features.html#feature-unification)
//! which may prevents user from depending on `fuse3` via an other crate
//! if it requires a different async runtime or it requests `file-lock` and
//! your crate doesn't (or vice versa).

#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]

Expand Down Expand Up @@ -98,7 +106,7 @@ impl From<FileType> for mode_t {
}
}

/// the setattr argument.
/// the [`setattr`](crate::path::PathFilesystem::setattr) argument
#[derive(Debug, Clone, Default, Eq, PartialEq)]
pub struct SetAttr {
/// set file or directory mode.
Expand Down Expand Up @@ -127,7 +135,7 @@ pub struct SetAttr {
pub flags: Option<u32>,
}

/// Helper for constructing Timestamps from fuse_setattr_in, which sign-casts
/// Helper for constructing [`Timestamp`s](Timestamp) from fuse_setattr_in, which sign-casts
/// the seconds.
macro_rules! fsai2ts {
( $secs: expr, $nsecs: expr) => {
Expand Down Expand Up @@ -205,7 +213,7 @@ impl From<&fuse_setattr_in> for SetAttr {

/// A file's timestamp, according to FUSE.
///
/// Nearly the same as a `libc::timespec`, except for the width of the nsec
/// Nearly the same as a [`libc::timespec`], except for the width of the nsec
/// field.
// Could implement From for Duration, and/or libc::timespec, if desired
#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
Expand Down
4 changes: 2 additions & 2 deletions src/notify.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! notify kernel.
//! notify kernel of changes to data it may have in its cache

use std::ffi::OsString;
use std::os::unix::ffi::OsStrExt;
Expand All @@ -21,7 +21,7 @@ use crate::raw::abi::{
use crate::raw::FuseData;

#[derive(Debug, Clone)]
/// notify kernel there are something need to handle.
/// queue of change notifications to send to the kernel
pub struct Notify {
sender: UnboundedSender<FuseData>,
}
Expand Down
4 changes: 2 additions & 2 deletions src/path/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! path based
//!
//! it is recommend to use path based [`PathFilesystem`] first, [`PathFilesystem`] is more simple
//! than inode based [`Filesystem`][crate::raw::Filesystem]. However if you want to control the
//! it is recommend to use the path based [`PathFilesystem`] first, which is more simple
//! than the inode based [`Filesystem`][crate::raw::Filesystem]. However if you want to control the
//! inode or do the path<->inode map on yourself, use [`Filesystem`][crate::raw::Filesystem].

pub use path_filesystem::PathFilesystem;
Expand Down
76 changes: 42 additions & 34 deletions src/path/path_filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,22 @@ pub trait PathFilesystem {
Err(libc::ENOSYS.into())
}

/// forget an path. The nlookup parameter indicates the number of lookups previously
/// forget a path. The nlookup parameter indicates the number of lookups previously
/// performed on this path. If the filesystem implements path lifetimes, it is recommended
/// that paths acquire a single reference on each lookup, and lose nlookup references on each
/// forget. The filesystem may ignore forget calls, if the paths don't need to have a limited
/// lifetime. On unmount it is not guaranteed, that all referenced paths will receive a forget
/// message. When filesystem is normal(not fuseblk) and unmounting, kernel may send forget
/// request for root and this library will stop session after call forget. There is some
/// forget. The filesystem may ignore forget calls if the paths don't need to have a limited
/// lifetime. On unmount it is not guaranteed that all referenced paths will receive a forget
/// message. When filesystem is normal(not fuseblk) and unmounting, the kernel may send a forget
/// request for the root and this library will stop session after calling forget. There is some
/// discussion for this <https://github.com/bazil/fuse/issues/82#issuecomment-88126886>,
/// <https://sourceforge.net/p/fuse/mailman/message/31995737/>
/// <https://sourceforge.net/p/fuse/mailman/message/31995737/>
async fn forget(&self, req: Request, parent: &OsStr, nlookup: u64) {}

/// get file attributes. If `fh` is None, means `fh` is not set. If `path` is None, means the
/// path may be deleted.
/// get file attributes.
///
/// `fh` contains the value set by the open method, or `None` if the open method didn't set any value.
/// If `path` is None, then the file/directory at that path may have been deleted.
async fn getattr(
&self,
req: Request,
Expand All @@ -50,8 +52,9 @@ pub trait PathFilesystem {
Err(libc::ENOSYS.into())
}

/// set file attributes. If `fh` is None, means `fh` is not set. If `path` is None, means the
/// path may be deleted.
/// set file attributes.
/// `fh` contains the value set by the open method, or `None` if the open method didn't set any value.
/// If `path` is None, then the file/directory at that path may have been deleted.
async fn setattr(
&self,
req: Request,
Expand Down Expand Up @@ -137,10 +140,11 @@ pub trait PathFilesystem {
Err(libc::ENOSYS.into())
}

/// open a file. Open flags (with the exception of `O_CREAT`, `O_EXCL` and `O_NOCTTY`) are
/// available in flags. Filesystem may store an arbitrary file handle (pointer, index, etc) in
/// fh, and use this in other all other file operations (read, write, flush, release, fsync).
/// Filesystem may also implement stateless file I/O and not store anything in fh. There are
/// open a file. Open flags (with the exception of [`O_CREAT`](libc::O_CREAT),
/// [`O_EXCL`](libc::O_EXCL) and [`O_NOCTTY`](libc::O_NOCTTY)) are available as flags.
/// The PathFilesystem may store an arbitrary file handle (pointer, index, etc) in
/// `fh`, and use it in other all other file operations (read, write, flush, release, fsync).
/// The PathFilesystem may also implement stateless file I/O and not store anything in `fh`. There are
/// also some flags (`direct_io`, `keep_cache`) which the filesystem may set, to change the way
/// the file is opened. A file system need not implement this method if it
/// sets [`MountOptions::no_open_support`][crate::MountOptions::no_open_support] and if the
Expand All @@ -160,7 +164,7 @@ pub trait PathFilesystem {
/// when the file has been opened in `direct_io` mode, in which case the return value of the
/// read system call will reflect the return value of this operation. `fh` will contain the
/// value set by the open method, or will be undefined if the open method didn't set any value.
/// when `path` is None, it means the path may be deleted.
/// If `path` is None, then the file/directory at that path may have been deleted.
async fn read(
&self,
req: Request,
Expand All @@ -176,9 +180,10 @@ pub trait PathFilesystem {
/// exception to this is when the file has been opened in `direct_io` mode, in which case the
/// return value of the write system call will reflect the return value of this operation. `fh`
/// will contain the value set by the open method, or will be undefined if the open method
/// didn't set any value. When `path` is None, it means the path may be deleted. When
/// `write_flags` contains [`FUSE_WRITE_CACHE`](crate::raw::flags::FUSE_WRITE_CACHE), means the
/// write operation is a delay write.
/// didn't set any value.
/// If `path` is None, then the file/directory at that path may have been deleted.
/// When `write_flags` contains [`FUSE_WRITE_CACHE`](crate::raw::flags::FUSE_WRITE_CACHE), means
/// the write operation is a delay write.
#[allow(clippy::too_many_arguments)]
async fn write(
&self,
Expand All @@ -201,10 +206,11 @@ pub trait PathFilesystem {
/// release an open file. Release is called when there are no more references to an open file:
/// all file descriptors are closed and all memory mappings are unmapped. For every open call
/// there will be exactly one release call. The filesystem may reply with an error, but error
/// values are not returned to `close()` or `munmap()` which triggered the release. `fh` will
/// values are not returned to the `close()` or `munmap()` which triggered the release. `fh` will
/// contain the value set by the open method, or will be undefined if the open method didn't
/// set any value. `flags` will contain the same flags as for open. `flush` means flush the
/// data or not when closing file. when `path` is None, it means the path may be deleted.
/// data or not when closing file.
/// If `path` is None, then the file/directory at that path may have been deleted.
async fn release(
&self,
req: Request,
Expand All @@ -217,8 +223,9 @@ pub trait PathFilesystem {
Err(libc::ENOSYS.into())
}

/// synchronize file contents. If the `datasync` is true, then only the user data should be
/// flushed, not the metadata. when `path` is None, it means the path may be deleted.
/// synchronize file contents. If `datasync` is true, then only the user data should be
/// flushed, not the metadata.
/// If `path` is None, then the file/directory at that path may have been deleted.
async fn fsync(
&self,
req: Request,
Expand All @@ -242,8 +249,8 @@ pub trait PathFilesystem {
Err(libc::ENOSYS.into())
}

/// get an extended attribute. If size is too small, use [`ReplyXAttr::Size`] to return correct
/// size. If size is enough, use [`ReplyXAttr::Data`] to send it, or return error.
/// get an extended attribute. If `size` is too small, use [`ReplyXAttr::Size`] to return
/// the correct size. If size is enough, use [`ReplyXAttr::Data`] to send it, or return an error.
async fn getxattr(
&self,
req: Request,
Expand All @@ -254,8 +261,8 @@ pub trait PathFilesystem {
Err(libc::ENOSYS.into())
}

/// list extended attribute names. If size is too small, use [`ReplyXAttr::Size`] to return
/// correct size. If size is enough, use [`ReplyXAttr::Data`] to send it, or return error.
/// list extended attribute names. If `size` is too small, use [`ReplyXAttr::Size`] to return
/// the correct size. If size is enough, use [`ReplyXAttr::Data`] to send it, or return an error.
async fn listxattr(&self, req: Request, path: &OsStr, size: u32) -> Result<ReplyXAttr> {
Err(libc::ENOSYS.into())
}
Expand All @@ -266,11 +273,12 @@ pub trait PathFilesystem {
}

/// flush method. This is called on each `close()` of the opened file. Since file descriptors
/// can be duplicated (`dup`, `dup2`, `fork`), for one open call there may be many flush calls.
/// can be duplicated (`dup`, `dup2`, `fork`), there may be many flush calls for each `open()`
/// call.
/// Filesystems shouldn't assume that flush will always be called after some writes, or that if
/// will be called at all. `fh` will contain the value set by the open method, or will be
/// undefined if the open method didn't set any value. when `path` is None, it means the path
/// may be deleted.
/// undefined if the open method didn't set any value.
/// If `path` is None, then the file/directory at that path may have been deleted.
///
/// # Notes:
///
Expand Down Expand Up @@ -339,7 +347,7 @@ pub trait PathFilesystem {
///
/// # Notes:
///
/// this is supported on enable **`file-lock`** feature.
/// this is only supported when the **`file-lock`** feature is enabled.
#[allow(clippy::too_many_arguments)]
async fn getlk(
&self,
Expand All @@ -358,7 +366,7 @@ pub trait PathFilesystem {
///
/// # Notes:
///
/// this is supported on enable **`file-lock`** feature.
/// this is only supported when the **`file-lock`** feature is enabled.
#[allow(clippy::too_many_arguments)]
async fn setlk(
&self,
Expand Down Expand Up @@ -407,17 +415,17 @@ pub trait PathFilesystem {
Err(libc::ENOSYS.into())
}

/// handle interrupt. When a operation is interrupted, an interrupt request will send to fuse
/// server with the unique id of the operation.
/// handle interrupt. When a operation is interrupted, an interrupt request will be sent to
/// the fuse server with the unique id of the operation.
async fn interrupt(&self, req: Request, unique: u64) -> Result<()> {
Err(libc::ENOSYS.into())
}

/// map block index within file to block index within device.
/// map block index within a file to block index within a device.
///
/// # Notes:
///
/// This may not works because currently this crate doesn't support fuseblk mode yet.
/// This may not work because currently this crate doesn't support fuseblk mode yet.
async fn bmap(
&self,
req: Request,
Expand Down
Loading