Skip to content

Commit 85179a6

Browse files
committed
rust: fs: introduce Type::statfs
This allows file system to expose their stats. This is required by overlayfs to have use part of a file system as an overlay. Signed-off-by: Wedson Almeida Filho <walmeida@microsoft.com>
1 parent 2cf6a7a commit 85179a6

3 files changed

Lines changed: 53 additions & 1 deletion

File tree

rust/bindings/bindings_helper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/fs.h>
1212
#include <linux/fs_context.h>
1313
#include <linux/slab.h>
14+
#include <linux/statfs.h>
1415
#include <linux/pagemap.h>
1516
#include <linux/refcount.h>
1617
#include <linux/wait.h>

rust/kernel/error.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ pub mod code {
8383
declare_err!(ENOGRACE, "NFS file lock reclaim refused.");
8484
declare_err!(ENODATA, "No data available.");
8585
declare_err!(EOPNOTSUPP, "Operation not supported on transport endpoint.");
86+
declare_err!(ENOSYS, "Invalid system call number.");
8687
}
8788

8889
/// Generic integer kernel error.

rust/kernel/fs.rs

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,31 @@ pub mod ro {
5757
fn read_xattr(_inode: &INode<Self>, _name: &CStr, _outbuf: &mut [u8]) -> Result<usize> {
5858
Err(EOPNOTSUPP)
5959
}
60+
61+
/// Get filesystem statistics.
62+
fn statfs(_sb: &SuperBlock<Self>) -> Result<Stat> {
63+
Err(ENOSYS)
64+
}
65+
}
66+
67+
/// File system stats.
68+
///
69+
/// A subset of C's `kstatfs`.
70+
pub struct Stat {
71+
/// Magic number of the file system.
72+
pub magic: u32,
73+
74+
/// The maximum length of a file name.
75+
pub namelen: i64,
76+
77+
/// Block size.
78+
pub bsize: i64,
79+
80+
/// Number of files in the file system.
81+
pub files: u64,
82+
83+
/// Number of blocks in the file system.
84+
pub blocks: u64,
6085
}
6186

6287
/// The types of directory entries reported by [`Type::read_dir`].
@@ -508,7 +533,7 @@ pub mod ro {
508533
freeze_fs: None,
509534
thaw_super: None,
510535
unfreeze_fs: None,
511-
statfs: None,
536+
statfs: Some(Self::statfs_callback),
512537
remount_fs: None,
513538
umount_begin: None,
514539
show_options: None,
@@ -526,6 +551,31 @@ pub mod ro {
526551
shutdown: None,
527552
};
528553

554+
unsafe extern "C" fn statfs_callback(
555+
dentry: *mut bindings::dentry,
556+
buf: *mut bindings::kstatfs,
557+
) -> core::ffi::c_int {
558+
from_result(|| {
559+
// SAFETY: The C api guarantees that `dentry` is valid for read. `d_sb` is
560+
// immutable, so it's safe to read it. The superblock is guaranteed to be valid dor
561+
// the duration of the call.
562+
let sb = unsafe { &*(*dentry).d_sb.cast::<SuperBlock<T>>() };
563+
let s = T::statfs(sb)?;
564+
565+
// SAFETY: The C api guarantees that `buf` is valid for read and write.
566+
let buf = unsafe { &mut *buf };
567+
buf.f_type = s.magic.into();
568+
buf.f_namelen = s.namelen;
569+
buf.f_bsize = s.bsize;
570+
buf.f_files = s.files;
571+
buf.f_blocks = s.blocks;
572+
buf.f_bfree = 0;
573+
buf.f_bavail = 0;
574+
buf.f_ffree = 0;
575+
Ok(0)
576+
})
577+
}
578+
529579
const XATTR_HANDLERS: [*const bindings::xattr_handler; 2] =
530580
[&Self::XATTR_HANDLER, ptr::null()];
531581

0 commit comments

Comments
 (0)