asterinas/kernel/src/syscall/statfs.rs

97 lines
2.6 KiB
Rust

// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{
fs::{
file_table::{get_file_fast, FileDesc},
fs_resolver::FsPath,
utils::{SuperBlock, PATH_MAX},
},
prelude::*,
};
pub fn sys_statfs(path_ptr: Vaddr, statfs_buf_ptr: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
let user_space = ctx.user_space();
let path_name = user_space.read_cstring(path_ptr, PATH_MAX)?;
debug!(
"path = {:?}, statfs_buf_ptr = 0x{:x}",
path_name, statfs_buf_ptr,
);
let path = {
let path_name = path_name.to_string_lossy();
let fs_path = FsPath::try_from(path_name.as_ref())?;
ctx.thread_local
.borrow_fs()
.resolver()
.read()
.lookup(&fs_path)?
};
let statfs = Statfs::from(path.fs().sb());
user_space.write_val(statfs_buf_ptr, &statfs)?;
Ok(SyscallReturn::Return(0))
}
pub fn sys_fstatfs(fd: FileDesc, statfs_buf_ptr: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
debug!("fd = {}, statfs_buf_addr = 0x{:x}", fd, statfs_buf_ptr);
let fs = {
let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd);
file.as_inode_or_err()?.path().fs()
};
let statfs = Statfs::from(fs.sb());
ctx.user_space().write_val(statfs_buf_ptr, &statfs)?;
Ok(SyscallReturn::Return(0))
}
/// FS Stat
#[derive(Debug, Clone, Copy, Pod, Default)]
#[repr(C)]
struct Statfs {
/// Type of filesystem
f_type: u64,
/// Optimal transfer block size
f_bsize: usize,
/// Total data blocks in filesystem
f_blocks: usize,
/// Free blocks in filesystem
f_bfree: usize,
/// Free blocks available to unprivileged user
f_bavail: usize,
/// Total inodes in filesystem
f_files: usize,
/// Free inodes in filesystem
f_ffree: usize,
/// Filesystem ID
f_fsid: u64,
/// Maximum length of filenames
f_namelen: usize,
/// Fragment size
f_frsize: usize,
/// Mount flags of filesystem
f_flags: u64,
/// Padding bytes reserved for future use
f_spare: [u64; 4],
}
impl From<SuperBlock> for Statfs {
fn from(sb: SuperBlock) -> Self {
Self {
f_type: sb.magic,
f_bsize: sb.bsize,
f_blocks: sb.blocks,
f_bfree: sb.bfree,
f_bavail: sb.bavail,
f_files: sb.files,
f_ffree: sb.ffree,
f_fsid: sb.fsid,
f_namelen: sb.namelen,
f_frsize: sb.frsize,
f_flags: sb.flags,
f_spare: [0u64; 4],
}
}
}