Skip to content
Closed
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
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ either = "1"
libc = "0.2"
num_cpus = "1.17"
polyfuse-kernel = { version = "0.3.0-dev", path = "crates/polyfuse-kernel" }
rustix = { version = "1", features = [ "fs", "mount", "net", "param", "pipe", "process", "thread", "use-libc" ] }
rustix = { version = "1", features = [ "fs", "mount", "net", "param", "pipe", "process", "io_uring", "thread", "use-libc" ] }
signal-hook = "0.3.18"
thiserror = "2"
tracing = "0.1"
zerocopy = "0.8.26"
Expand Down
37 changes: 22 additions & 15 deletions examples/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustix::{
io::Errno,
process::{getgid, getuid},
};
use std::{io, path::PathBuf, time::Duration};
use std::{io, path::PathBuf, thread, time::Duration};

const CONTENT: &[u8] = b"Hello from FUSE!\n";

Expand All @@ -30,21 +30,28 @@ fn main() -> Result<()> {
let (session, device, mount) =
polyfuse::connect(mountpoint, MountOptions::new(), KernelConfig::new())?;

// Receive an incoming FUSE request from the kernel.
let mut buf = session.new_fallback_buffer();
while session.recv_request(&device, &mut buf)? {
let (req, op, _remains) = session.decode(&device, &mut buf)?;
match op {
// Dispatch your callbacks to the supported operations...
Operation::Getattr(op) => getattr(req, op)?,
Operation::Read(op) => read(req, op)?,

// Or annotate that the operation is not supported.
_ => req.reply_error(Errno::NOSYS)?,
};
}
thread::scope(|scope| -> Result<()> {
let mount_handle = mount.handle();
scope.spawn(move || mount.unmount_after_interrupted());
Comment thread
ubnt-intrepid marked this conversation as resolved.

// Receive an incoming FUSE request from the kernel.
let mut buf = session.new_fallback_buffer();
while session.recv_request(&device, &mut buf)? {
let (req, op, _remains) = session.decode(&device, &mut buf)?;
match op {
// Dispatch your callbacks to the supported operations...
Operation::Getattr(op) => getattr(req, op)?,
Operation::Read(op) => read(req, op)?,

// Or annotate that the operation is not supported.
_ => req.reply_error(Errno::NOSYS)?,
};
}

mount_handle.close();

mount.unmount()?;
Ok(())
})?;

Ok(())
}
Expand Down
27 changes: 14 additions & 13 deletions examples/heartbeat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use rustix::{io::Errno, param::page_size};
use std::{
io::{self, prelude::*},
path::PathBuf,
sync::{Arc, Mutex},
sync::Mutex,
thread,
time::Duration,
};
Expand All @@ -43,24 +43,25 @@ fn main() -> Result<()> {
let mountpoint: PathBuf = args.opt_free_from_str()?.context("missing mountpoint")?;
ensure!(mountpoint.is_file(), "mountpoint must be a regular file");

let fs = Arc::new(Heartbeat::new(kind, update_interval));
let fs = Heartbeat::new(kind, update_interval);

let (session, conn, mount) =
polyfuse::connect(mountpoint, MountOptions::new(), KernelConfig::new())?;

let conn = &conn;
let session = &session;
let fs = &fs;
thread::scope(|scope| -> Result<()> {
let mount_handle = mount.handle();
scope.spawn(move || mount.unmount_after_interrupted());

// Spawn a task that beats the heart.
scope.spawn({
let fs = fs.clone();
move || -> Result<()> {
loop {
tracing::info!("heartbeat");
fs.update_content();
fs.notify(session, conn)?;
thread::sleep(fs.update_interval);
}
scope.spawn(move || -> Result<()> {
loop {
tracing::info!("heartbeat");
fs.update_content();
fs.notify(session, conn)?;
thread::sleep(fs.update_interval);
}
});
Comment thread
ubnt-intrepid marked this conversation as resolved.

Expand Down Expand Up @@ -124,11 +125,11 @@ fn main() -> Result<()> {
}
}

mount_handle.close();

Ok(())
})?;

mount.unmount()?;

Ok(())
}

Expand Down
24 changes: 9 additions & 15 deletions examples/heartbeat_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,7 @@ use polyfuse::{
use anyhow::{ensure, Context as _, Result};
use chrono::Local;
use rustix::io::Errno;
use std::{
io, mem,
os::unix::prelude::*,
path::PathBuf,
sync::{Arc, Mutex},
thread,
time::Duration,
};
use std::{io, mem, os::unix::prelude::*, path::PathBuf, sync::Mutex, thread, time::Duration};

const FILE_INO: NodeID = match NodeID::from_raw(2) {
Some(ino) => ino,
Expand Down Expand Up @@ -58,19 +51,20 @@ fn main() -> Result<()> {
let mountpoint: PathBuf = args.opt_free_from_str()?.context("missing mountpoint")?;
ensure!(mountpoint.is_dir(), "mountpoint must be a directory");

let fs = Arc::new(Heartbeat::new(ttl, update_interval, no_notify));
let fs = Heartbeat::new(ttl, update_interval, no_notify);

let (session, conn, mount) =
polyfuse::connect(mountpoint, MountOptions::new(), KernelConfig::new())?;

let session = &session;
let conn = &conn;
let fs = &fs;
thread::scope(|scope| -> Result<()> {
let mount_handle = mount.handle();
scope.spawn(move || mount.unmount_after_interrupted());
Comment thread
ubnt-intrepid marked this conversation as resolved.

// spawn heartbeat thread.
scope.spawn({
let fs = fs.clone();
move || fs.heartbeat(session, conn)
});
scope.spawn(move || fs.heartbeat(session, conn));

let mut buf = session.new_splice_buffer()?;
while session.recv_request(conn, &mut buf)? {
Expand Down Expand Up @@ -149,11 +143,11 @@ fn main() -> Result<()> {
}
}

mount_handle.close();

Ok(())
})?;

mount.unmount()?;

Ok(())
}

Expand Down
125 changes: 66 additions & 59 deletions examples/hello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use rustix::{
io::Errno,
process::{getgid, getuid},
};
use std::{os::unix::prelude::*, path::PathBuf, time::Duration};
use std::{os::unix::prelude::*, path::PathBuf, thread, time::Duration};

const TTL: Duration = Duration::from_secs(60 * 60 * 24 * 365);
const HELLO_INO: NodeID = match NodeID::from_raw(2) {
Expand All @@ -39,78 +39,85 @@ fn main() -> Result<()> {

let fs = Hello::new();

let mut buf = session.new_splice_buffer()?;
while session.recv_request(&conn, &mut buf)? {
let (req, op, _remains) = session.decode(&conn, &mut buf)?;
match op {
Operation::Lookup(op) => match op.parent {
NodeID::ROOT if op.name.as_bytes() == HELLO_FILENAME.as_bytes() => {
req.reply_entry(Some(HELLO_INO), &fs.hello_attr(), 0, Some(TTL), Some(TTL))?
}
_ => req.reply_error(Errno::NOENT)?,
},

Operation::Getattr(op) => {
let attr = match op.ino {
NodeID::ROOT => fs.root_attr(),
HELLO_INO => fs.hello_attr(),
_ => Err(Errno::NOENT)?,
};
req.reply_attr(&attr, Some(TTL))?;
}

Operation::Read(op) => {
match op.ino {
HELLO_INO => (),
NodeID::ROOT => {
req.reply_error(Errno::ISDIR)?;
continue;
}
_ => {
req.reply_error(Errno::NOENT)?;
continue;
thread::scope(|scope| -> Result<()> {
let mount_handle = mount.handle();
scope.spawn(move || mount.unmount_after_interrupted());
Comment thread
ubnt-intrepid marked this conversation as resolved.

let mut buf = session.new_splice_buffer()?;
while session.recv_request(&conn, &mut buf)? {
let (req, op, _remains) = session.decode(&conn, &mut buf)?;
match op {
Operation::Lookup(op) => match op.parent {
NodeID::ROOT if op.name.as_bytes() == HELLO_FILENAME.as_bytes() => {
req.reply_entry(Some(HELLO_INO), &fs.hello_attr(), 0, Some(TTL), Some(TTL))?
}
_ => req.reply_error(Errno::NOENT)?,
},

Operation::Getattr(op) => {
let attr = match op.ino {
NodeID::ROOT => fs.root_attr(),
HELLO_INO => fs.hello_attr(),
_ => Err(Errno::NOENT)?,
};
req.reply_attr(&attr, Some(TTL))?;
}

let mut data: &[u8] = &[];
Operation::Read(op) => {
match op.ino {
HELLO_INO => (),
NodeID::ROOT => {
req.reply_error(Errno::ISDIR)?;
continue;
}
_ => {
req.reply_error(Errno::NOENT)?;
continue;
}
}

let offset = op.offset as usize;
if offset < HELLO_CONTENT.len() {
let size = op.size as usize;
data = &HELLO_CONTENT[offset..];
data = &data[..std::cmp::min(data.len(), size)];
}
let mut data: &[u8] = &[];

req.reply_bytes(data)?;
}
let offset = op.offset as usize;
if offset < HELLO_CONTENT.len() {
let size = op.size as usize;
data = &HELLO_CONTENT[offset..];
data = &data[..std::cmp::min(data.len(), size)];
}

Operation::Readdir(op) => {
if op.ino != NodeID::ROOT {
req.reply_error(Errno::NOTDIR)?;
continue;
req.reply_bytes(data)?;
}

let mut buf = DirEntryBuf::new(op.size as usize);
for (i, entry) in fs.dir_entries().skip(op.offset as usize) {
let full = buf.push_entry(
entry.name.as_ref(), //
entry.ino,
entry.typ,
i + 1,
);
if full {
break;
Operation::Readdir(op) => {
if op.ino != NodeID::ROOT {
req.reply_error(Errno::NOTDIR)?;
continue;
}

let mut buf = DirEntryBuf::new(op.size as usize);
for (i, entry) in fs.dir_entries().skip(op.offset as usize) {
let full = buf.push_entry(
entry.name.as_ref(), //
entry.ino,
entry.typ,
i + 1,
);
if full {
break;
}
}

req.reply_dir(&buf)?;
}

req.reply_dir(&buf)?;
_ => req.reply_error(Errno::NOSYS)?,
}

_ => req.reply_error(Errno::NOSYS)?,
}
}

mount.unmount()?;
mount_handle.close();

Ok(())
})?;

Ok(())
}
Expand Down
12 changes: 9 additions & 3 deletions examples/poll.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![forbid(unsafe_code)]

use polyfuse::{
mount::MountOptions,
notify::Notifier as _,
Expand Down Expand Up @@ -38,7 +40,7 @@ fn main() -> Result<()> {
.unwrap_or(5),
);

let fs = Arc::new(PollFS::new(wakeup_interval));
let fs = PollFS::new(wakeup_interval);

let mountpoint: PathBuf = args.opt_free_from_str()?.context("missing mountpoint")?;
ensure!(mountpoint.is_file(), "mountpoint must be a regular file");
Expand All @@ -48,7 +50,11 @@ fn main() -> Result<()> {

let conn = &conn;
let session = &session;
let fs = &fs;
thread::scope(|scope| -> Result<()> {
let mount_handle = mount.handle();
scope.spawn(move || mount.unmount_after_interrupted());
Comment thread
ubnt-intrepid marked this conversation as resolved.

let mut buf = session.new_splice_buffer()?;
while session.recv_request(conn, &mut buf)? {
let (req, op, _remains) = session.decode(conn, &mut buf)?;
Expand Down Expand Up @@ -167,11 +173,11 @@ fn main() -> Result<()> {
}
}

mount_handle.close();

Ok(())
})?;

mount.unmount()?;

Ok(())
}

Expand Down
Loading