lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Tue, 14 May 2024 10:17:01 -0300
From: Wedson Almeida Filho <wedsonaf@...il.com>
To: Alexander Viro <viro@...iv.linux.org.uk>,
	Christian Brauner <brauner@...nel.org>,
	Matthew Wilcox <willy@...radead.org>,
	Dave Chinner <david@...morbit.com>
Cc: Kent Overstreet <kent.overstreet@...il.com>,
	Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
	linux-fsdevel@...r.kernel.org,
	rust-for-linux@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	Wedson Almeida Filho <walmeida@...rosoft.com>
Subject: [RFC PATCH v2 20/30] rust: fs: introduce `FileSystem::statfs`

From: Wedson Almeida Filho <walmeida@...rosoft.com>

Allow Rust file systems to expose their stats. `overlayfs` requires that
this be implemented by all file systems that are part of an overlay.
The planned file systems need to be overlayed with overlayfs, so they
must be able to implement this.

Signed-off-by: Wedson Almeida Filho <walmeida@...rosoft.com>
---
 rust/bindings/bindings_helper.h |  1 +
 rust/kernel/error.rs            |  1 +
 rust/kernel/fs.rs               | 47 ++++++++++++++++++++++++++++++++-
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index 2133f95e8be5..f4c7c3951dbe 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -20,6 +20,7 @@
 #include <linux/refcount.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/statfs.h>
 #include <linux/wait.h>
 #include <linux/workqueue.h>
 #include <linux/xattr.h>
diff --git a/rust/kernel/error.rs b/rust/kernel/error.rs
index f40a2bdf28d4..edada157879a 100644
--- a/rust/kernel/error.rs
+++ b/rust/kernel/error.rs
@@ -79,6 +79,7 @@ macro_rules! declare_err {
     declare_err!(ENOGRACE, "NFS file lock reclaim refused.");
     declare_err!(ENODATA, "No data available.");
     declare_err!(EOPNOTSUPP, "Operation not supported on transport endpoint.");
+    declare_err!(ENOSYS, "Invalid system call number.");
     declare_err!(ESTALE, "Stale file handle.");
     declare_err!(EUCLEAN, "Structure needs cleaning.");
 }
diff --git a/rust/kernel/fs.rs b/rust/kernel/fs.rs
index 5b8f9c346767..51de73008857 100644
--- a/rust/kernel/fs.rs
+++ b/rust/kernel/fs.rs
@@ -61,6 +61,31 @@ fn read_xattr(
     ) -> Result<usize> {
         Err(EOPNOTSUPP)
     }
+
+    /// Get filesystem statistics.
+    fn statfs(_dentry: &DEntry<Self>) -> Result<Stat> {
+        Err(ENOSYS)
+    }
+}
+
+/// File system stats.
+///
+/// A subset of C's `kstatfs`.
+pub struct Stat {
+    /// Magic number of the file system.
+    pub magic: usize,
+
+    /// The maximum length of a file name.
+    pub namelen: isize,
+
+    /// Block size.
+    pub bsize: isize,
+
+    /// Number of files in the file system.
+    pub files: u64,
+
+    /// Number of blocks in the file system.
+    pub blocks: u64,
 }
 
 /// A file system that is unspecified.
@@ -213,7 +238,7 @@ impl<T: FileSystem + ?Sized> Tables<T> {
         freeze_fs: None,
         thaw_super: None,
         unfreeze_fs: None,
-        statfs: None,
+        statfs: Some(Self::statfs_callback),
         remount_fs: None,
         umount_begin: None,
         show_options: None,
@@ -231,6 +256,26 @@ impl<T: FileSystem + ?Sized> Tables<T> {
         shutdown: None,
     };
 
+    unsafe extern "C" fn statfs_callback(
+        dentry_ptr: *mut bindings::dentry,
+        buf: *mut bindings::kstatfs,
+    ) -> ffi::c_int {
+        from_result(|| {
+            // SAFETY: The C API guarantees that `dentry_ptr` is a valid dentry.
+            let dentry = unsafe { DEntry::from_raw(dentry_ptr) };
+            let s = T::statfs(dentry)?;
+
+            // SAFETY: The C API guarantees that `buf` is valid for read and write.
+            let buf = unsafe { &mut *buf };
+            buf.f_type = s.magic as ffi::c_long;
+            buf.f_namelen = s.namelen as ffi::c_long;
+            buf.f_bsize = s.bsize as ffi::c_long;
+            buf.f_files = s.files;
+            buf.f_blocks = s.blocks;
+            Ok(0)
+        })
+    }
+
     const XATTR_HANDLERS: [*const bindings::xattr_handler; 2] = [&Self::XATTR_HANDLER, ptr::null()];
 
     const XATTR_HANDLER: bindings::xattr_handler = bindings::xattr_handler {
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ