mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-09 21:36:48 +00:00
Add support for statfs and fstatfs
This commit is contained in:
parent
9f1680d0f3
commit
743344e3fc
@ -1,4 +1,4 @@
|
||||
TESTS ?= open_test read_test
|
||||
TESTS ?= open_test read_test statfs_test
|
||||
|
||||
MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||
CUR_DIR := $(patsubst %/,%,$(dir $(MKFILE_PATH)))
|
||||
|
4
regression/syscall_test/blocklists/statfs_test
Normal file
4
regression/syscall_test/blocklists/statfs_test
Normal file
@ -0,0 +1,4 @@
|
||||
StatfsTest.InternalTmpfs
|
||||
StatfsTest.InternalDevShm
|
||||
FstatfsTest.InternalTmpfs
|
||||
FstatfsTest.InternalDevShm
|
@ -262,7 +262,7 @@ impl FsResolver {
|
||||
let inode_handle = file_table
|
||||
.get_file(fd)?
|
||||
.downcast_ref::<InodeHandle>()
|
||||
.ok_or(Error::with_message(Errno::EBADE, "not inode"))?;
|
||||
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
|
||||
Ok(inode_handle.dentry().clone())
|
||||
}
|
||||
|
||||
@ -381,7 +381,7 @@ impl<'a> FsPath<'a> {
|
||||
FsPathInner::CwdRelative(path)
|
||||
}
|
||||
} else {
|
||||
return_errno_with_message!(Errno::EINVAL, "invalid dirfd number");
|
||||
return_errno_with_message!(Errno::EBADF, "invalid dirfd number");
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
|
@ -14,7 +14,7 @@ mod self_;
|
||||
mod template;
|
||||
|
||||
/// Magic number.
|
||||
const PROC_MAGIC: usize = 0x9fa0;
|
||||
const PROC_MAGIC: u64 = 0x9fa0;
|
||||
/// Root Inode ID.
|
||||
const PROC_ROOT_INO: usize = 1;
|
||||
/// Block size.
|
||||
|
@ -11,7 +11,7 @@ use super::*;
|
||||
use crate::fs::device::Device;
|
||||
use crate::fs::utils::{
|
||||
DirentVisitor, FileSystem, FsFlags, Inode, InodeMode, InodeType, IoEvents, IoctlCmd, Metadata,
|
||||
Poller, SuperBlock,
|
||||
Poller, SuperBlock, NAME_MAX,
|
||||
};
|
||||
|
||||
/// A volatile file system whose data and metadata exists only in memory.
|
||||
|
@ -4,7 +4,6 @@ pub use fs::RamFS;
|
||||
|
||||
mod fs;
|
||||
|
||||
const RAMFS_MAGIC: usize = 0x0102_1994;
|
||||
const RAMFS_MAGIC: u64 = 0x0102_1994;
|
||||
const BLOCK_SIZE: usize = 4096;
|
||||
const NAME_MAX: usize = 255;
|
||||
const ROOT_INO: usize = 1;
|
||||
|
@ -4,7 +4,7 @@ use crate::prelude::*;
|
||||
use alloc::string::String;
|
||||
use core::time::Duration;
|
||||
|
||||
use super::{InodeMode, InodeType, Metadata, Vnode, NAME_MAX};
|
||||
use super::{FileSystem, InodeMode, InodeType, Metadata, Vnode, NAME_MAX};
|
||||
|
||||
lazy_static! {
|
||||
static ref DCACHE: Mutex<BTreeMap<DentryKey, Arc<Dentry>>> = Mutex::new(BTreeMap::new());
|
||||
@ -233,6 +233,11 @@ impl Dentry {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get the filesystem the inode belongs to
|
||||
pub fn fs(&self) -> Arc<dyn FileSystem> {
|
||||
self.vnode.fs()
|
||||
}
|
||||
|
||||
/// Get the inode metadata
|
||||
pub fn inode_metadata(&self) -> Metadata {
|
||||
self.vnode.metadata()
|
||||
|
@ -7,21 +7,21 @@ use crate::prelude::*;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SuperBlock {
|
||||
pub magic: usize,
|
||||
pub magic: u64,
|
||||
pub bsize: usize,
|
||||
pub blocks: usize,
|
||||
pub bfree: usize,
|
||||
pub bavail: usize,
|
||||
pub files: usize,
|
||||
pub ffree: usize,
|
||||
pub fsid: usize,
|
||||
pub fsid: u64,
|
||||
pub namelen: usize,
|
||||
pub frsize: usize,
|
||||
pub flags: usize,
|
||||
pub flags: u64,
|
||||
}
|
||||
|
||||
impl SuperBlock {
|
||||
pub fn new(magic: usize, block_size: usize, name_len: usize) -> Self {
|
||||
pub fn new(magic: u64, block_size: usize, name_max_len: usize) -> Self {
|
||||
Self {
|
||||
magic,
|
||||
bsize: block_size,
|
||||
@ -31,7 +31,7 @@ impl SuperBlock {
|
||||
files: 0,
|
||||
ffree: 0,
|
||||
fsid: 0,
|
||||
namelen: 255,
|
||||
namelen: name_max_len,
|
||||
frsize: block_size,
|
||||
flags: 0,
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use super::{
|
||||
DirentVisitor, FsFlags, Inode, InodeMode, InodeType, IoEvents, IoctlCmd, Metadata, PageCache,
|
||||
Poller,
|
||||
DirentVisitor, FileSystem, FsFlags, Inode, InodeMode, InodeType, IoEvents, IoctlCmd, Metadata,
|
||||
PageCache, Poller,
|
||||
};
|
||||
use crate::fs::device::Device;
|
||||
use crate::prelude::*;
|
||||
@ -202,6 +202,10 @@ impl Vnode {
|
||||
self.inner.read().inode.ioctl(cmd, arg)
|
||||
}
|
||||
|
||||
pub fn fs(&self) -> Arc<dyn FileSystem> {
|
||||
self.inner.read().inode.fs()
|
||||
}
|
||||
|
||||
pub fn metadata(&self) -> Metadata {
|
||||
self.inner.read().inode.metadata()
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ pub fn sys_fchdir(fd: FileDescripter) -> Result<SyscallReturn> {
|
||||
let file = file_table.get_file(fd)?;
|
||||
let inode_handle = file
|
||||
.downcast_ref::<InodeHandle>()
|
||||
.ok_or(Error::with_message(Errno::EBADE, "not inode"))?;
|
||||
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
|
||||
inode_handle.dentry().clone()
|
||||
};
|
||||
if dentry.inode_type() != InodeType::Dir {
|
||||
|
@ -29,7 +29,7 @@ pub fn sys_getdents64(
|
||||
};
|
||||
let inode_handle = file
|
||||
.downcast_ref::<InodeHandle>()
|
||||
.ok_or(Error::with_message(Errno::EBADE, "not inode"))?;
|
||||
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
|
||||
if inode_handle.dentry().inode_type() != InodeType::Dir {
|
||||
return_errno!(Errno::ENOTDIR);
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ use crate::syscall::set_robust_list::sys_set_robust_list;
|
||||
use crate::syscall::set_tid_address::sys_set_tid_address;
|
||||
use crate::syscall::setpgid::sys_setpgid;
|
||||
use crate::syscall::stat::{sys_fstat, sys_fstatat, sys_lstat, sys_stat};
|
||||
use crate::syscall::statfs::{sys_fstatfs, sys_statfs};
|
||||
use crate::syscall::symlink::{sys_symlink, sys_symlinkat};
|
||||
use crate::syscall::tgkill::sys_tgkill;
|
||||
use crate::syscall::time::sys_time;
|
||||
@ -150,6 +151,7 @@ mod setsockopt;
|
||||
mod shutdown;
|
||||
mod socket;
|
||||
mod stat;
|
||||
mod statfs;
|
||||
mod symlink;
|
||||
mod tgkill;
|
||||
mod time;
|
||||
@ -259,6 +261,8 @@ define_syscall_nums!(
|
||||
SYS_SETPGID = 109,
|
||||
SYS_GETPPID = 110,
|
||||
SYS_GETPGRP = 111,
|
||||
SYS_STATFS = 137,
|
||||
SYS_FSTATFS = 138,
|
||||
SYS_PRCTL = 157,
|
||||
SYS_ARCH_PRCTL = 158,
|
||||
SYS_GETTID = 186,
|
||||
@ -411,6 +415,8 @@ pub fn syscall_dispatch(
|
||||
SYS_SETPGID => syscall_handler!(2, sys_setpgid, args),
|
||||
SYS_GETPPID => syscall_handler!(0, sys_getppid),
|
||||
SYS_GETPGRP => syscall_handler!(0, sys_getpgrp),
|
||||
SYS_STATFS => syscall_handler!(2, sys_statfs, args),
|
||||
SYS_FSTATFS => syscall_handler!(2, sys_fstatfs, args),
|
||||
SYS_PRCTL => syscall_handler!(5, sys_prctl, args),
|
||||
SYS_ARCH_PRCTL => syscall_handler!(2, sys_arch_prctl, args, context),
|
||||
SYS_GETTID => syscall_handler!(0, sys_gettid),
|
||||
|
93
services/libs/jinux-std/src/syscall/statfs.rs
Normal file
93
services/libs/jinux-std/src/syscall/statfs.rs
Normal file
@ -0,0 +1,93 @@
|
||||
use crate::fs::{
|
||||
file_table::FileDescripter,
|
||||
fs_resolver::FsPath,
|
||||
inode_handle::InodeHandle,
|
||||
utils::{SuperBlock, PATH_MAX},
|
||||
};
|
||||
use crate::log_syscall_entry;
|
||||
use crate::prelude::*;
|
||||
use crate::util::{read_cstring_from_user, write_val_to_user};
|
||||
|
||||
use super::SyscallReturn;
|
||||
use super::{SYS_FSTATFS, SYS_STATFS};
|
||||
|
||||
pub fn sys_statfs(path_ptr: Vaddr, statfs_buf_ptr: Vaddr) -> Result<SyscallReturn> {
|
||||
log_syscall_entry!(SYS_STATFS);
|
||||
let path = read_cstring_from_user(path_ptr, PATH_MAX)?;
|
||||
debug!("path = {:?}, statfs_buf_ptr = 0x{:x}", path, statfs_buf_ptr,);
|
||||
|
||||
let current = current!();
|
||||
let dentry = {
|
||||
let path = path.to_string_lossy();
|
||||
let fs_path = FsPath::try_from(path.as_ref())?;
|
||||
current.fs().read().lookup(&fs_path)?
|
||||
};
|
||||
let statfs = Statfs::from(dentry.fs().sb());
|
||||
write_val_to_user(statfs_buf_ptr, &statfs)?;
|
||||
Ok(SyscallReturn::Return(0))
|
||||
}
|
||||
|
||||
pub fn sys_fstatfs(fd: FileDescripter, statfs_buf_ptr: Vaddr) -> Result<SyscallReturn> {
|
||||
log_syscall_entry!(SYS_FSTATFS);
|
||||
debug!("fd = {}, statfs_buf_addr = 0x{:x}", fd, statfs_buf_ptr);
|
||||
|
||||
let current = current!();
|
||||
let file_table = current.file_table().lock();
|
||||
let file = file_table.get_file(fd)?;
|
||||
let inode_handle = file
|
||||
.downcast_ref::<InodeHandle>()
|
||||
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
|
||||
let dentry = inode_handle.dentry();
|
||||
let statfs = Statfs::from(dentry.fs().sb());
|
||||
write_val_to_user(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],
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user