- 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 _)) + } +} + /// 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
