Clean up some FS APIs

This commit is contained in:
Ruihan Li 2025-09-05 10:33:22 +08:00 committed by Chengjun Chen
parent d4d84f18b7
commit bb6069d5bb
17 changed files with 135 additions and 147 deletions

View File

@ -3,11 +3,10 @@
use alloc::sync::Arc;
use aster_block::BlockDevice;
use aster_systree::SysBranchNode;
use spin::Once;
use super::inode::CgroupInode;
use crate::{
context::Context,
fs::{
cgroupfs::systree_node::CgroupSystem,
registry::{FsProperties, FsType},
@ -18,7 +17,7 @@ use crate::{
};
/// A file system for managing cgroups.
pub struct CgroupFs {
pub(super) struct CgroupFs {
sb: SuperBlock,
root: Arc<dyn Inode>,
}
@ -29,7 +28,14 @@ const BLOCK_SIZE: usize = 4096;
const NAME_MAX: usize = 255;
impl CgroupFs {
pub(super) fn new(root_node: Arc<CgroupSystem>) -> Arc<Self> {
/// Returns the `CgroupFs` singleton.
pub(super) fn singleton() -> &'static Arc<CgroupFs> {
static SINGLETON: Once<Arc<CgroupFs>> = Once::new();
SINGLETON.call_once(|| Self::new(CgroupSystem::singleton().clone()))
}
fn new(root_node: Arc<CgroupSystem>) -> Arc<Self> {
let sb = SuperBlock::new(MAGIC_NUMBER, BLOCK_SIZE, NAME_MAX);
let root_inode = CgroupInode::new_root(root_node);
@ -59,15 +65,7 @@ impl FileSystem for CgroupFs {
}
}
pub(super) struct CgroupFsType {
systree_root: Arc<CgroupSystem>,
}
impl CgroupFsType {
pub(super) fn new(systree_root: Arc<CgroupSystem>) -> Arc<Self> {
Arc::new(Self { systree_root })
}
}
pub(super) struct CgroupFsType;
impl FsType for CgroupFsType {
fn name(&self) -> &'static str {
@ -82,19 +80,11 @@ impl FsType for CgroupFsType {
&self,
_args: Option<CString>,
_disk: Option<Arc<dyn BlockDevice>>,
_ctx: &Context,
) -> Result<Arc<dyn FileSystem>> {
if super::CGROUP_SINGLETON.is_completed() {
return_errno_with_message!(Errno::EBUSY, "the cgroupfs has been created");
}
let cgroupfs = CgroupFs::new(self.systree_root.clone());
super::CGROUP_SINGLETON.call_once(|| cgroupfs.clone());
Ok(cgroupfs)
Ok(CgroupFs::singleton().clone() as _)
}
fn sysnode(&self) -> Option<Arc<dyn SysBranchNode>> {
Some(self.systree_root.clone())
fn sysnode(&self) -> Option<Arc<dyn aster_systree::SysNode>> {
Some(CgroupSystem::singleton().clone() as _)
}
}

View File

@ -4,6 +4,7 @@ use alloc::sync::{Arc, Weak};
use ostd::sync::RwLock;
use super::fs::CgroupFs;
use crate::{
fs::utils::{
systree_inode::{SysTreeInodeTy, SysTreeNodeKind},
@ -13,7 +14,7 @@ use crate::{
};
/// An inode abstraction used in the cgroup file system.
pub struct CgroupInode {
pub(super) struct CgroupInode {
/// The corresponding node in the SysTree.
node_kind: SysTreeNodeKind,
/// The metadata of this inode.
@ -67,12 +68,14 @@ impl SysTreeInodeTy for CgroupInode {
}
fn this(&self) -> Arc<Self> {
self.this.upgrade().expect("Weak ref invalid")
self.this
.upgrade()
.expect("invalid weak reference to `self`")
}
}
impl Inode for CgroupInode {
fn fs(&self) -> Arc<dyn FileSystem> {
super::singleton().clone()
CgroupFs::singleton().clone()
}
}

View File

@ -2,27 +2,15 @@
use alloc::sync::Arc;
use fs::CgroupFs;
use spin::Once;
use crate::fs::cgroupfs::{fs::CgroupFsType, systree_node::CgroupSystem};
use crate::fs::cgroupfs::fs::CgroupFsType;
mod fs;
mod inode;
mod systree_node;
static CGROUP_SINGLETON: Once<Arc<CgroupFs>> = Once::new();
/// Returns a reference to the global CgroupFs instance. Panics if not initialized.
pub fn singleton() -> &'static Arc<CgroupFs> {
CGROUP_SINGLETON.get().expect("CgroupFs is not initialized")
}
/// Initializes the CgroupFs singleton.
/// Ensures that the singleton is created by calling it.
/// Should be called during kernel file system initialization, *after* aster_systree::init().
pub fn init() {
let cgroup_root = CgroupSystem::new();
let cgroup_fs_type = CgroupFsType::new(cgroup_root);
super::registry::register(cgroup_fs_type).unwrap();
// This method should be called during kernel file system initialization,
// _after_ `aster_systree::init`.
pub(super) fn init() {
let cgroupfs_type = Arc::new(CgroupFsType);
super::registry::register(cgroupfs_type).unwrap();
}

View File

@ -12,6 +12,7 @@ use aster_systree::{
};
use inherit_methods_macro::inherit_methods;
use ostd::mm::{VmReader, VmWriter};
use spin::Once;
/// The root of a cgroup hierarchy, serving as the entry point to
/// the entire cgroup control system.
@ -19,7 +20,7 @@ use ostd::mm::{VmReader, VmWriter};
/// The cgroup system provides v2 unified hierarchy, and is also used as a root
/// node in the cgroup systree.
#[derive(Debug)]
pub struct CgroupSystem {
pub(super) struct CgroupSystem {
fields: BranchNodeFields<CgroupNode, Self>,
}
@ -29,24 +30,31 @@ pub struct CgroupSystem {
/// management. Except for the root node, all nodes in the cgroup tree are of
/// this type.
#[derive(Debug)]
pub struct CgroupNode {
struct CgroupNode {
fields: BranchNodeFields<CgroupNode, Self>,
}
#[inherit_methods(from = "self.fields")]
impl CgroupSystem {
/// Adds a child node.
pub fn add_child(&self, new_child: Arc<CgroupNode>) -> Result<()>;
fn add_child(&self, new_child: Arc<CgroupNode>) -> Result<()>;
}
#[inherit_methods(from = "self.fields")]
impl CgroupNode {
/// Adds a child node.
pub fn add_child(&self, new_child: Arc<CgroupNode>) -> Result<()>;
fn add_child(&self, new_child: Arc<CgroupNode>) -> Result<()>;
}
impl CgroupSystem {
pub(super) fn new() -> Arc<Self> {
/// Returns the `CgroupSystem` singleton.
pub(super) fn singleton() -> &'static Arc<CgroupSystem> {
static SINGLETON: Once<Arc<CgroupSystem>> = Once::new();
SINGLETON.call_once(Self::new)
}
fn new() -> Arc<Self> {
let name = SysStr::from("cgroup");
let mut builder = SysAttrSetBuilder::new();
@ -78,7 +86,7 @@ impl CgroupSystem {
}
impl CgroupNode {
pub(super) fn new(name: SysStr) -> Arc<Self> {
pub(self) fn new(name: SysStr) -> Arc<Self> {
let mut builder = SysAttrSetBuilder::new();
// TODO: Add more attributes as needed. The normal cgroup node may have
// more attributes than the unified one.

View File

@ -112,20 +112,19 @@ impl FsType for DevPtsType {
"devpts"
}
fn create(
&self,
_args: Option<CString>,
_disk: Option<Arc<dyn aster_block::BlockDevice>>,
_ctx: &Context,
) -> Result<Arc<dyn FileSystem>> {
Ok(DevPts::new())
}
fn properties(&self) -> FsProperties {
FsProperties::empty()
}
fn sysnode(&self) -> Option<Arc<dyn aster_systree::SysBranchNode>> {
fn create(
&self,
_args: Option<CString>,
_disk: Option<Arc<dyn aster_block::BlockDevice>>,
) -> Result<Arc<dyn FileSystem>> {
Ok(DevPts::new())
}
fn sysnode(&self) -> Option<Arc<dyn aster_systree::SysNode>> {
None
}
}

View File

@ -458,20 +458,19 @@ impl FsType for ExfatType {
"exfat"
}
fn create(
&self,
_args: Option<CString>,
disk: Option<Arc<dyn BlockDevice>>,
ctx: &Context,
) -> Result<Arc<dyn FileSystem>> {
ExfatFS::open(disk.unwrap(), ExfatMountOptions::default()).map(|fs| fs as _)
}
fn properties(&self) -> FsProperties {
FsProperties::NEED_DISK
}
fn sysnode(&self) -> Option<Arc<dyn aster_systree::SysBranchNode>> {
fn create(
&self,
_args: Option<CString>,
disk: Option<Arc<dyn BlockDevice>>,
) -> Result<Arc<dyn FileSystem>> {
ExfatFS::open(disk.unwrap(), ExfatMountOptions::default()).map(|fs| fs as _)
}
fn sysnode(&self) -> Option<Arc<dyn aster_systree::SysNode>> {
None
}
}

View File

@ -446,20 +446,19 @@ impl FsType for Ext2Type {
"ext2"
}
fn create(
&self,
_args: Option<CString>,
disk: Option<Arc<dyn BlockDevice>>,
_ctx: &Context,
) -> Result<Arc<dyn FileSystem>> {
Ext2::open(disk.unwrap()).map(|fs| fs as _)
}
fn properties(&self) -> FsProperties {
FsProperties::NEED_DISK
}
fn sysnode(&self) -> Option<Arc<dyn aster_systree::SysBranchNode>> {
fn create(
&self,
_args: Option<CString>,
disk: Option<Arc<dyn BlockDevice>>,
) -> Result<Arc<dyn FileSystem>> {
Ext2::open(disk.unwrap()).map(|fs| fs as _)
}
fn sysnode(&self) -> Option<Arc<dyn aster_systree::SysNode>> {
None
}
}

View File

@ -13,7 +13,10 @@ use aster_block::BLOCK_SIZE;
use aster_rights::Full;
use hashbrown::HashSet;
use inherit_methods_macro::inherit_methods;
use ostd::mm::{io_util::HasVmReaderWriter, FrameAllocOptions};
use ostd::{
mm::{io_util::HasVmReaderWriter, FrameAllocOptions},
task::Task,
};
use crate::{
fs::{
@ -1113,11 +1116,14 @@ impl FsType for OverlayFsType {
"overlay"
}
fn properties(&self) -> FsProperties {
FsProperties::empty()
}
fn create(
&self,
args: Option<CString>,
_disk: Option<Arc<dyn aster_block::BlockDevice>>,
ctx: &Context,
) -> Result<Arc<dyn FileSystem>> {
let mut lower = Vec::new();
let mut upper = "";
@ -1155,7 +1161,9 @@ impl FsType for OverlayFsType {
}
}
let fs_ref = ctx.thread_local.borrow_fs();
let task = Task::current().unwrap();
let thread_local = task.as_thread_local().unwrap();
let fs_ref = thread_local.borrow_fs();
let fs = fs_ref.resolver().read();
let upper = fs.lookup(&FsPath::new(AT_FDCWD, upper)?)?;
@ -1168,11 +1176,7 @@ impl FsType for OverlayFsType {
OverlayFS::new(upper, lower, work).map(|fs| fs as _)
}
fn properties(&self) -> FsProperties {
FsProperties::empty()
}
fn sysnode(&self) -> Option<Arc<dyn aster_systree::SysBranchNode>> {
fn sysnode(&self) -> Option<Arc<dyn aster_systree::SysNode>> {
None
}
}

View File

@ -93,20 +93,19 @@ impl FsType for ProcFsType {
"proc"
}
fn create(
&self,
_args: Option<CString>,
_disk: Option<Arc<dyn aster_block::BlockDevice>>,
_ctx: &Context,
) -> Result<Arc<dyn FileSystem>> {
Ok(ProcFS::new())
}
fn properties(&self) -> FsProperties {
FsProperties::empty()
}
fn sysnode(&self) -> Option<Arc<dyn aster_systree::SysBranchNode>> {
fn create(
&self,
_args: Option<CString>,
_disk: Option<Arc<dyn aster_block::BlockDevice>>,
) -> Result<Arc<dyn FileSystem>> {
Ok(ProcFS::new())
}
fn sysnode(&self) -> Option<Arc<dyn aster_systree::SysNode>> {
None
}
}

View File

@ -1279,20 +1279,19 @@ impl FsType for RamFsType {
"ramfs"
}
fn create(
&self,
_args: Option<CString>,
_disk: Option<Arc<dyn aster_block::BlockDevice>>,
_ctx: &Context,
) -> Result<Arc<dyn FileSystem>> {
Ok(RamFS::new())
}
fn properties(&self) -> FsProperties {
FsProperties::empty()
}
fn sysnode(&self) -> Option<Arc<dyn aster_systree::SysBranchNode>> {
fn create(
&self,
_args: Option<CString>,
_disk: Option<Arc<dyn aster_block::BlockDevice>>,
) -> Result<Arc<dyn FileSystem>> {
Ok(RamFS::new())
}
fn sysnode(&self) -> Option<Arc<dyn aster_systree::SysNode>> {
None
}
}

View File

@ -4,7 +4,7 @@ use alloc::borrow::ToOwned;
use aster_block::BlockDevice;
use aster_systree::{
inherit_sys_branch_node, AttrLessBranchNodeFields, SysBranchNode, SysObj, SysPerms, SysStr,
inherit_sys_branch_node, AttrLessBranchNodeFields, SysNode, SysObj, SysPerms, SysStr,
};
use spin::Once;
@ -26,7 +26,6 @@ pub trait FsType: Send + Sync + 'static {
&self,
args: Option<CString>,
disk: Option<Arc<dyn BlockDevice>>,
ctx: &Context,
) -> Result<Arc<dyn FileSystem>>;
/// Returns a `SysTree` node that represents the FS type.
@ -36,7 +35,7 @@ pub trait FsType: Send + Sync + 'static {
///
/// The same result will be returned by this method
/// when it is called multiple times.
fn sysnode(&self) -> Option<Arc<dyn SysBranchNode>>;
fn sysnode(&self) -> Option<Arc<dyn SysNode>>;
}
bitflags! {

View File

@ -3,6 +3,7 @@
use alloc::sync::Arc;
use aster_systree::singleton as systree_singleton;
use spin::Once;
use crate::{
fs::{
@ -16,7 +17,7 @@ use crate::{
/// A file system for exposing kernel information to the user space.
#[derive(Debug)]
pub struct SysFs {
pub(super) struct SysFs {
sb: SuperBlock,
root: Arc<dyn Inode>,
}
@ -26,7 +27,19 @@ const BLOCK_SIZE: usize = 4096;
const NAME_MAX: usize = 255;
impl SysFs {
pub(crate) fn new() -> Arc<Self> {
/// Returns the `SysFs` singleton.
pub(super) fn singleton() -> &'static Arc<SysFs> {
static SINGLETON: Once<Arc<SysFs>> = Once::new();
SINGLETON.call_once(Self::new)
}
#[cfg(ktest)]
pub(super) fn new_for_ktest() -> Arc<Self> {
Self::new()
}
fn new() -> Arc<Self> {
let sb = SuperBlock::new(MAGIC_NUMBER, BLOCK_SIZE, NAME_MAX);
let systree_ref = systree_singleton();
let root_inode = SysFsInode::new_root(systree_ref.root().clone());
@ -72,17 +85,11 @@ impl FsType for SysFsType {
&self,
_args: Option<CString>,
_disk: Option<Arc<dyn aster_block::BlockDevice>>,
_ctx: &Context,
) -> Result<Arc<dyn FileSystem>> {
if super::SYSFS_SINGLETON.is_completed() {
return_errno_with_message!(Errno::EBUSY, "the sysfs has been created");
}
super::SYSFS_SINGLETON.call_once(SysFs::new);
Ok(super::singleton().clone())
Ok(SysFs::singleton().clone() as _)
}
fn sysnode(&self) -> Option<Arc<dyn aster_systree::SysBranchNode>> {
fn sysnode(&self) -> Option<Arc<dyn aster_systree::SysNode>> {
None
}
}

View File

@ -4,6 +4,7 @@ use alloc::sync::{Arc, Weak};
use ostd::sync::RwLock;
use super::fs::SysFs;
use crate::{
fs::utils::{
systree_inode::{SysTreeInodeTy, SysTreeNodeKind},
@ -14,7 +15,7 @@ use crate::{
};
/// An inode abstraction used in the sysfs file system.
pub struct SysFsInode {
pub(super) struct SysFsInode {
/// The corresponding node in the SysTree.
node_kind: SysTreeNodeKind,
/// The metadata of this inode.
@ -74,16 +75,21 @@ impl SysTreeInodeTy for SysFsInode {
}
fn this(&self) -> Arc<Self> {
self.this.upgrade().expect("Weak ref invalid")
self.this
.upgrade()
.expect("invalid weak reference to `self`")
}
}
impl Inode for SysFsInode {
fn fs(&self) -> Arc<dyn FileSystem> {
super::singleton().clone()
SysFs::singleton().clone()
}
fn create(&self, _name: &str, _type_: InodeType, _mode: InodeMode) -> Result<Arc<dyn Inode>> {
Err(Error::new(Errno::EPERM))
Err(Error::with_message(
Errno::EPERM,
"file creation under sysfs is not allowed",
))
}
}

View File

@ -7,21 +7,10 @@ mod test;
use alloc::sync::Arc;
use spin::Once;
pub use self::fs::SysFs;
use crate::fs::sysfs::fs::SysFsType;
static SYSFS_SINGLETON: Once<Arc<SysFs>> = Once::new();
/// Returns a reference to the global [`SysFs`] instance. Panics if not initialized.
pub fn singleton() -> &'static Arc<SysFs> {
SYSFS_SINGLETON.get().expect("SysFs not initialized")
}
/// Initializes the SysFs singleton.
/// Ensures that the singleton is created by calling it.
/// Should be called during kernel file system initialization, *after* aster_systree::init().
// This method should be called during kernel file system initialization,
// _after_ `aster_systree::init`.
pub fn init() {
let sysfs_type = Arc::new(SysFsType);
super::registry::register(sysfs_type).unwrap();

View File

@ -231,7 +231,7 @@ fn create_mock_systree_instance() -> &'static Arc<SysTree> {
// Initialize a SysFs instance using the mock systree.
fn init_sysfs_with_mock_tree() -> Arc<SysFs> {
let _ = create_mock_systree_instance();
SysFs::new()
SysFs::new_for_ktest()
}
#[ktest]

View File

@ -44,22 +44,21 @@ impl FsType for TmpFsType {
"tmpfs"
}
fn properties(&self) -> FsProperties {
FsProperties::empty()
}
fn create(
&self,
_args: Option<CString>,
_disk: Option<Arc<dyn aster_block::BlockDevice>>,
_ctx: &Context,
) -> Result<Arc<dyn FileSystem>> {
Ok(Arc::new(TmpFs {
inner: RamFS::new(),
}))
}
fn properties(&self) -> FsProperties {
FsProperties::empty()
}
fn sysnode(&self) -> Option<Arc<dyn aster_systree::SysBranchNode>> {
fn sysnode(&self) -> Option<Arc<dyn aster_systree::SysNode>> {
None
}
}

View File

@ -180,7 +180,7 @@ fn get_fs(
None
};
fs_type.create(data, disk, ctx)
fs_type.create(data, disk)
}
bitflags! {