Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add build cfg for FUSE mounting implementation to fuser #1106

Open
wants to merge 10 commits into
base: fuser/fork
Choose a base branch
from
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
This is a fork of the excellent [`fuser`](https://github.com/cberner/fuser) Rust crate for FUSE bindings, with some Mountpoint-specific changes to improve performance of concurrent operations. We'll be working to upstream these changes soon.

---

# FUSE (Filesystem in Userspace) for Rust

![CI](https://github.com/cberner/fuser/actions/workflows/ci.yml/badge.svg)
Expand Down
23 changes: 14 additions & 9 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,46 +1,51 @@
fn main() {
// Register rustc cfg for switching between mount implementations.
// When fuser MSRV is updated to v1.77 or above, we should switch from 'cargo:' to 'cargo::' syntax.
println!("cargo:rustc-check-cfg=cfg(fuser_mount_impl, values(\"pure-rust\", \"libfuse2\", \"libfuse3\"))");

#[cfg(all(not(feature = "libfuse"), not(target_os = "linux")))]
unimplemented!("Building without libfuse is only supported on Linux");

#[cfg(not(feature = "libfuse"))]
{
println!("cargo:rustc-cfg=fuser_mount_impl=\"pure-rust\"");
}
#[cfg(feature = "libfuse")]
{
#[cfg(target_os = "macos")]
{
if cfg!(target_os = "macos") {
if pkg_config::Config::new()
.atleast_version("2.6.0")
.probe("fuse") // for macFUSE 4.x
.map_err(|e| eprintln!("{}", e))
.is_ok()
{
println!("cargo:rustc-cfg=feature=\"libfuse2\"");
println!("cargo:rustc-cfg=fuser_mount_impl=\"libfuse2\"");
println!("cargo:rustc-cfg=feature=\"macfuse-4-compat\"");
} else {
pkg_config::Config::new()
.atleast_version("2.6.0")
.probe("osxfuse") // for osxfuse 3.x
.map_err(|e| eprintln!("{}", e))
.unwrap();
println!("cargo:rustc-cfg=feature=\"libfuse2\"");
println!("cargo:rustc-cfg=fuser_mount_impl=\"libfuse2\"");
}
}
#[cfg(not(target_os = "macos"))]
{
} else {
// First try to link with libfuse3
if pkg_config::Config::new()
.atleast_version("3.0.0")
.probe("fuse3")
.map_err(|e| eprintln!("{e}"))
.is_ok()
{
println!("cargo:rustc-cfg=feature=\"libfuse3\"");
println!("cargo:rustc-cfg=fuser_mount_impl=\"libfuse3\"");
} else {
// Fallback to libfuse
pkg_config::Config::new()
.atleast_version("2.6.0")
.probe("fuse")
.map_err(|e| eprintln!("{e}"))
.unwrap();
println!("cargo:rustc-cfg=feature=\"libfuse2\"");
println!("cargo:rustc-cfg=fuser_mount_impl=\"libfuse2\"");
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions examples/hello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@
struct HelloFS;

impl Filesystem for HelloFS {
fn lookup(&mut self, _req: &Request, parent: u64, name: &OsStr, reply: ReplyEntry) {
fn lookup(&self, _req: &Request, parent: u64, name: &OsStr, reply: ReplyEntry) {
if parent == 1 && name.to_str() == Some("hello.txt") {
reply.entry(&TTL, &HELLO_TXT_ATTR, 0);
} else {
reply.error(ENOENT);
}
}

fn getattr(&mut self, _req: &Request, ino: u64, _fh: Option<u64>, reply: ReplyAttr) {
fn getattr(&self, _req: &Request, ino: u64, _fh: Option<u64>, reply: ReplyAttr) {
match ino {
1 => reply.attr(&TTL, &HELLO_DIR_ATTR),
2 => reply.attr(&TTL, &HELLO_TXT_ATTR),
Expand All @@ -67,7 +67,7 @@
}

fn read(
&mut self,
&self,
_req: &Request,
ino: u64,
_fh: u64,
Expand All @@ -81,11 +81,11 @@
reply.data(&HELLO_TXT_CONTENT.as_bytes()[offset as usize..]);
} else {
reply.error(ENOENT);
}

Check warning on line 84 in examples/hello.rs

View workflow job for this annotation

GitHub Actions / ci

Diff in /home/runner/work/mountpoint-s3/mountpoint-s3/examples/hello.rs
}

fn readdir(
&mut self,
&self,
_req: &Request,
ino: u64,
_fh: u64,
Expand Down
22 changes: 12 additions & 10 deletions examples/ioctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@
use libc::{EINVAL, ENOENT};
use log::debug;
use std::ffi::OsStr;
use std::sync::Mutex;
use std::time::{Duration, UNIX_EPOCH};

const TTL: Duration = Duration::from_secs(1); // 1 second

struct FiocFS {
content: Vec<u8>,
content: Mutex<Vec<u8>>,
root_attr: FileAttr,
fioc_file_attr: FileAttr,
}
Expand Down Expand Up @@ -62,23 +63,23 @@
};

Self {
content: vec![],
content: vec![].into(),
root_attr,
fioc_file_attr,
}
}
}

impl Filesystem for FiocFS {
fn lookup(&mut self, _req: &Request, parent: u64, name: &OsStr, reply: ReplyEntry) {
fn lookup(&self, _req: &Request, parent: u64, name: &OsStr, reply: ReplyEntry) {
if parent == 1 && name.to_str() == Some("fioc") {
reply.entry(&TTL, &self.fioc_file_attr, 0);
} else {
reply.error(ENOENT);
}
}

fn getattr(&mut self, _req: &Request, ino: u64, _fh: Option<u64>, reply: ReplyAttr) {
fn getattr(&self, _req: &Request, ino: u64, _fh: Option<u64>, reply: ReplyAttr) {
match ino {
1 => reply.attr(&TTL, &self.root_attr),
2 => reply.attr(&TTL, &self.fioc_file_attr),
Expand All @@ -87,7 +88,7 @@
}

fn read(
&mut self,
&self,
_req: &Request,
ino: u64,
_fh: u64,
Expand All @@ -98,14 +99,15 @@
reply: ReplyData,
) {
if ino == 2 {
reply.data(&self.content[offset as usize..])
let content = self.content.lock().unwrap();
reply.data(&content[offset as usize..])
} else {
reply.error(ENOENT);
}

Check warning on line 106 in examples/ioctl.rs

View workflow job for this annotation

GitHub Actions / ci

Diff in /home/runner/work/mountpoint-s3/mountpoint-s3/examples/ioctl.rs
}

fn readdir(
&mut self,
&self,
_req: &Request,
ino: u64,
_fh: u64,
Expand Down Expand Up @@ -133,7 +135,7 @@
}

fn ioctl(
&mut self,
&self,
_req: &Request<'_>,
ino: u64,
_fh: u64,
Expand All @@ -153,12 +155,12 @@

match cmd.into() {
FIOC_GET_SIZE => {
let size_bytes = self.content.len().to_ne_bytes();
let size_bytes = self.content.lock().unwrap().len().to_ne_bytes();
reply.ioctl(0, &size_bytes);
}
FIOC_SET_SIZE => {
let new_size = usize::from_ne_bytes(in_data.try_into().unwrap());
self.content = vec![0_u8; new_size];
*self.content.lock().unwrap() = vec![0_u8; new_size];
reply.ioctl(0, &[]);
}
_ => {
Expand Down
8 changes: 4 additions & 4 deletions examples/notify_inval_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
}

impl<'a> Filesystem for ClockFS<'a> {
fn lookup(&mut self, _req: &Request, parent: u64, name: &OsStr, reply: ReplyEntry) {
fn lookup(&self, _req: &Request, parent: u64, name: &OsStr, reply: ReplyEntry) {
if parent != FUSE_ROOT_ID || name != AsRef::<OsStr>::as_ref(&self.get_filename()) {
reply.error(ENOENT);
return;
Expand All @@ -78,7 +78,7 @@
reply.entry(&self.timeout, &ClockFS::stat(ClockFS::FILE_INO).unwrap(), 0);
}

fn forget(&mut self, _req: &Request, ino: u64, nlookup: u64) {
fn forget(&self, _req: &Request, ino: u64, nlookup: u64) {
if ino == ClockFS::FILE_INO {
let prev = self.lookup_cnt.fetch_sub(nlookup, SeqCst);
assert!(prev >= nlookup);
Expand All @@ -87,15 +87,15 @@
}
}

fn getattr(&mut self, _req: &Request, ino: u64, _fh: Option<u64>, reply: ReplyAttr) {
fn getattr(&self, _req: &Request, ino: u64, _fh: Option<u64>, reply: ReplyAttr) {
match ClockFS::stat(ino) {
Some(a) => reply.attr(&self.timeout, &a),
None => reply.error(ENOENT),
}

Check warning on line 94 in examples/notify_inval_entry.rs

View workflow job for this annotation

GitHub Actions / ci

Diff in /home/runner/work/mountpoint-s3/mountpoint-s3/examples/notify_inval_entry.rs
}

fn readdir(
&mut self,
&self,
_req: &Request,
ino: u64,
_fh: u64,
Expand Down
12 changes: 6 additions & 6 deletions examples/notify_inval_inode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
}

impl<'a> Filesystem for ClockFS<'a> {
fn lookup(&mut self, _req: &Request, parent: u64, name: &OsStr, reply: ReplyEntry) {
fn lookup(&self, _req: &Request, parent: u64, name: &OsStr, reply: ReplyEntry) {
if parent != FUSE_ROOT_ID || name != AsRef::<OsStr>::as_ref(&Self::FILE_NAME) {
reply.error(ENOENT);
return;
Expand All @@ -77,7 +77,7 @@
reply.entry(&Duration::MAX, &self.stat(ClockFS::FILE_INO).unwrap(), 0);
}

fn forget(&mut self, _req: &Request, ino: u64, nlookup: u64) {
fn forget(&self, _req: &Request, ino: u64, nlookup: u64) {
if ino == ClockFS::FILE_INO {
let prev = self.lookup_cnt.fetch_sub(nlookup, SeqCst);
assert!(prev >= nlookup);
Expand All @@ -86,15 +86,15 @@
}
}

fn getattr(&mut self, _req: &Request, ino: u64, _fh: Option<u64>, reply: ReplyAttr) {
fn getattr(&self, _req: &Request, ino: u64, _fh: Option<u64>, reply: ReplyAttr) {
match self.stat(ino) {
Some(a) => reply.attr(&Duration::MAX, &a),
None => reply.error(ENOENT),
}

Check warning on line 93 in examples/notify_inval_inode.rs

View workflow job for this annotation

GitHub Actions / ci

Diff in /home/runner/work/mountpoint-s3/mountpoint-s3/examples/notify_inval_inode.rs
}

fn readdir(
&mut self,
&self,
_req: &Request,
ino: u64,
_fh: u64,
Expand All @@ -120,7 +120,7 @@
}
}

fn open(&mut self, _req: &Request, ino: u64, flags: i32, reply: ReplyOpen) {
fn open(&self, _req: &Request, ino: u64, flags: i32, reply: ReplyOpen) {
if ino == FUSE_ROOT_ID {
reply.error(EISDIR);
} else if flags & libc::O_ACCMODE != libc::O_RDONLY {
Expand All @@ -134,7 +134,7 @@
}

fn read(
&mut self,
&self,
_req: &Request,
ino: u64,
_fh: u64,
Expand Down
14 changes: 7 additions & 7 deletions examples/poll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ impl FSelFS {
}

impl fuser::Filesystem for FSelFS {
fn lookup(&mut self, _req: &Request, parent: u64, name: &OsStr, reply: fuser::ReplyEntry) {
fn lookup(&self, _req: &Request, parent: u64, name: &OsStr, reply: fuser::ReplyEntry) {
if parent != FUSE_ROOT_ID || name.len() != 1 {
reply.error(ENOENT);
return;
Expand All @@ -101,7 +101,7 @@ impl fuser::Filesystem for FSelFS {
reply.entry(&Duration::ZERO, &self.get_data().filestat(idx), 0);
}

fn getattr(&mut self, _req: &Request, ino: u64, _fh: Option<u64>, reply: fuser::ReplyAttr) {
fn getattr(&self, _req: &Request, ino: u64, _fh: Option<u64>, reply: fuser::ReplyAttr) {
if ino == FUSE_ROOT_ID {
let a = FileAttr {
ino: FUSE_ROOT_ID,
Expand Down Expand Up @@ -132,7 +132,7 @@ impl fuser::Filesystem for FSelFS {
}

fn readdir(
&mut self,
&self,
_req: &Request,
ino: u64,
_fh: u64,
Expand Down Expand Up @@ -169,7 +169,7 @@ impl fuser::Filesystem for FSelFS {
reply.ok();
}

fn open(&mut self, _req: &Request, ino: u64, flags: i32, reply: fuser::ReplyOpen) {
fn open(&self, _req: &Request, ino: u64, flags: i32, reply: fuser::ReplyOpen) {
let idx = FSelData::ino_to_idx(ino);
if idx >= NUMFILES {
reply.error(ENOENT);
Expand All @@ -196,7 +196,7 @@ impl fuser::Filesystem for FSelFS {
}

fn release(
&mut self,
&self,
_req: &Request,
_ino: u64,
fh: u64,
Expand All @@ -215,7 +215,7 @@ impl fuser::Filesystem for FSelFS {
}

fn read(
&mut self,
&self,
_req: &Request,
_ino: u64,
fh: u64,
Expand Down Expand Up @@ -247,7 +247,7 @@ impl fuser::Filesystem for FSelFS {
}

fn poll(
&mut self,
&self,
_req: &Request,
_ino: u64,
fh: u64,
Expand Down
Loading
Loading