From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id EB2491FF13F for ; Thu, 12 Mar 2026 09:55:53 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 53A11AA08; Thu, 12 Mar 2026 09:55:48 +0100 (CET) Date: Thu, 12 Mar 2026 09:55:42 +0100 From: Wolfgang Bumiller To: Kefu Chai Subject: applied: [PATCH proxmox-fuse-rs v1] Add statfs support to proxmox-fuse Message-ID: References: <20260212071003.1544536-1-k.chai@proxmox.com> <20260212071003.1544536-4-k.chai@proxmox.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20260212071003.1544536-4-k.chai@proxmox.com> X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1773305707224 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.983 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_MSPIKE_H2 0.001 Average reputation (+2) RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.408 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.819 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.903 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: HVIXIVH745RAV5W6O5KPKZMGZIL5E5O3 X-Message-ID-Hash: HVIXIVH745RAV5W6O5KPKZMGZIL5E5O3 X-MailFrom: w.bumiller@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: pve-devel@lists.proxmox.com X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: 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 > --- > 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 > > > > >