applied I added a small follow-up commit, see the comment below inline.
I also added `#[non_exhaustive]` to `Request` so we can add entries without major version bumps. Bumped to v3 so it can be used right away. On Thu, Feb 12, 2026 at 03:05:47PM +0800, Kefu Chai wrote: > - Add fuse_reply_statfs FFI binding in sys.rs > - Add Statfs request struct in requests.rs > - Add Statfs variant to Request enum > - Add statfs callback to FuseData > - Add enable_statfs() method to FuseSessionBuilder > > This enables filesystems to handle statfs requests and return filesystem > statistics. > > Signed-off-by: Kefu Chai <[email protected]> > --- > examples/tmpfs/main.rs | 4 ++-- > src/requests.rs | 24 ++++++++++++++++++++++++ > src/session.rs | 17 +++++++++++++++++ > src/sys.rs | 1 + > 4 files changed, 44 insertions(+), 2 deletions(-) > > diff --git a/examples/tmpfs/main.rs b/examples/tmpfs/main.rs > index f3f7d26..36db9e8 100644 > --- a/examples/tmpfs/main.rs > +++ b/examples/tmpfs/main.rs > @@ -3,11 +3,11 @@ use std::ffi::OsStr; > use std::path::Path; > use std::{io, mem}; > > -use anyhow::{bail, format_err, Error}; > +use anyhow::{Error, bail, format_err}; > use futures::future::FutureExt; > use futures::select; > use futures::stream::TryStreamExt; > -use tokio::signal::unix::{signal, SignalKind}; > +use tokio::signal::unix::{SignalKind, signal}; > > use proxmox_fuse::requests::{self, FuseRequest, SetTime}; > use proxmox_fuse::{EntryParam, Fuse, ReplyBufState, Request}; > diff --git a/src/requests.rs b/src/requests.rs > index d1846cc..458b956 100644 > --- a/src/requests.rs > +++ b/src/requests.rs > @@ -106,6 +106,7 @@ pub enum Request { > Forget(Forget), > Getattr(Getattr), > Setattr(Setattr), > + Statfs(Statfs), > Readdir(Readdir), > ReaddirPlus(ReaddirPlus), > Mkdir(Mkdir), > @@ -144,6 +145,7 @@ impl FuseRequest for Request { > Request::Lookup(r) => r.fail(errno), > Request::Getattr(r) => r.fail(errno), > Request::Setattr(r) => r.fail(errno), > + Request::Statfs(r) => r.fail(errno), > Request::Readdir(r) => r.fail(errno), > Request::ReaddirPlus(r) => r.fail(errno), > Request::Mkdir(r) => r.fail(errno), > @@ -239,6 +241,28 @@ impl Getattr { > } > } > > +/// Get filesystem statistics. > +/// > +/// This is the equivalent of a `statfs` call. > +#[derive(Debug)] > +pub struct Statfs { > + pub(crate) request: RequestGuard, > + pub inode: u64, > +} > + > +impl FuseRequest for Statfs { > + fn fail(self, errno: libc::c_int) -> io::Result<()> { > + reply_err(self.request, errno) > + } > +} > + > +impl Statfs { > + /// Send a reply for a `Statfs` request. > + pub fn reply(self, stbuf: &libc::statvfs) -> io::Result<()> { > + reply_result!(self: sys::fuse_reply_statfs(self.request.raw, stbuf > as *const _)) The cast here is actually not necessary. Initially I just replaced it with `&raw const *stbuf` (since `&raw {const,mut}` is a thing now in rust) - only after pushing out the change did I realize that the cast is actually completely unnecessary, since references are automatically converted to pointers in this case anyway... > + } > +} > + > /// Get the contents of a directory without changing any lookup counts. > (Contrary to > /// `ReaddirPlus`). > #[derive(Debug)] > diff --git a/src/session.rs b/src/session.rs > index 62a8a9e..3e4841c 100644 > --- a/src/session.rs > +++ b/src/session.rs > @@ -94,6 +94,17 @@ impl FuseData { > })); > } > > + extern "C" fn statfs(request: sys::Request, inode: u64) { > + let fuse_data = unsafe { &*(sys::fuse_req_userdata(request) as *mut > FuseData) }; > + fuse_data > + .pending_requests > + .borrow_mut() > + .push_back(Request::Statfs(requests::Statfs { > + request: RequestGuard::from_raw(request), > + inode, > + })); > + } > + > extern "C" fn readdir( > request: sys::Request, > inode: u64, > @@ -547,6 +558,12 @@ impl FuseSessionBuilder { > self > } > > + /// Enable `Statfs` requests. > + pub fn enable_statfs(mut self) -> Self { > + self.operations.statfs = Some(FuseData::statfs); > + self > + } > + > /// Enable `Unlink` requests. > pub fn enable_unlink(mut self) -> Self { > self.operations.unlink = Some(FuseData::unlink); > diff --git a/src/sys.rs b/src/sys.rs > index 17a01de..186b0ec 100644 > --- a/src/sys.rs > +++ b/src/sys.rs > @@ -77,6 +77,7 @@ unsafe extern "C" { > pub fn fuse_reply_readlink(req: Request, link: StrPtr) -> c_int; > pub fn fuse_reply_none(req: Request); > pub fn fuse_reply_write(req: Request, count: libc::size_t) -> c_int; > + pub fn fuse_reply_statfs(req: Request, stbuf: *const libc::statvfs) -> > c_int; > pub fn fuse_req_userdata(req: Request) -> MutPtr; > pub fn fuse_add_direntry_plus(req: Request, buf: MutStrPtr, bufsize: > size_t, name: StrPtr, stbuf: Option<&EntryParam>, off: c_int) -> size_t; > pub fn fuse_add_direntry(req: Request, buf: MutStrPtr, bufsize: size_t, > name: StrPtr, stbuf: Option<&libc::stat>, off: c_int) -> size_t; > -- > 2.47.3 > > > > >
