From bb6069d5bbe7ea57e54ea03353bfb9102e7dd854 Mon Sep 17 00:00:00 2001 From: Ruihan Li Date: Fri, 5 Sep 2025 10:33:22 +0800 Subject: [PATCH] Clean up some FS APIs --- kernel/src/fs/cgroupfs/fs.rs | 38 ++++++++++---------------- kernel/src/fs/cgroupfs/inode.rs | 9 ++++-- kernel/src/fs/cgroupfs/mod.rs | 24 ++++------------ kernel/src/fs/cgroupfs/systree_node.rs | 20 ++++++++++---- kernel/src/fs/devpts/mod.rs | 19 ++++++------- kernel/src/fs/exfat/fs.rs | 19 ++++++------- kernel/src/fs/ext2/fs.rs | 19 ++++++------- kernel/src/fs/overlayfs/fs.rs | 20 ++++++++------ kernel/src/fs/procfs/mod.rs | 19 ++++++------- kernel/src/fs/ramfs/fs.rs | 19 ++++++------- kernel/src/fs/registry.rs | 5 ++-- kernel/src/fs/sysfs/fs.rs | 27 +++++++++++------- kernel/src/fs/sysfs/inode.rs | 14 +++++++--- kernel/src/fs/sysfs/mod.rs | 15 ++-------- kernel/src/fs/sysfs/test.rs | 2 +- kernel/src/fs/tmpfs/fs.rs | 11 ++++---- kernel/src/syscall/mount.rs | 2 +- 17 files changed, 135 insertions(+), 147 deletions(-) diff --git a/kernel/src/fs/cgroupfs/fs.rs b/kernel/src/fs/cgroupfs/fs.rs index 21271506b..1817164c7 100644 --- a/kernel/src/fs/cgroupfs/fs.rs +++ b/kernel/src/fs/cgroupfs/fs.rs @@ -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, } @@ -29,7 +28,14 @@ const BLOCK_SIZE: usize = 4096; const NAME_MAX: usize = 255; impl CgroupFs { - pub(super) fn new(root_node: Arc) -> Arc { + /// Returns the `CgroupFs` singleton. + pub(super) fn singleton() -> &'static Arc { + static SINGLETON: Once> = Once::new(); + + SINGLETON.call_once(|| Self::new(CgroupSystem::singleton().clone())) + } + + fn new(root_node: Arc) -> Arc { 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, -} - -impl CgroupFsType { - pub(super) fn new(systree_root: Arc) -> Arc { - 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, _disk: Option>, - _ctx: &Context, ) -> Result> { - 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> { - Some(self.systree_root.clone()) + fn sysnode(&self) -> Option> { + Some(CgroupSystem::singleton().clone() as _) } } diff --git a/kernel/src/fs/cgroupfs/inode.rs b/kernel/src/fs/cgroupfs/inode.rs index 06ca7a1b0..2b88e5c8d 100644 --- a/kernel/src/fs/cgroupfs/inode.rs +++ b/kernel/src/fs/cgroupfs/inode.rs @@ -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.this.upgrade().expect("Weak ref invalid") + self.this + .upgrade() + .expect("invalid weak reference to `self`") } } impl Inode for CgroupInode { fn fs(&self) -> Arc { - super::singleton().clone() + CgroupFs::singleton().clone() } } diff --git a/kernel/src/fs/cgroupfs/mod.rs b/kernel/src/fs/cgroupfs/mod.rs index 37a56ed28..debd226d4 100644 --- a/kernel/src/fs/cgroupfs/mod.rs +++ b/kernel/src/fs/cgroupfs/mod.rs @@ -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> = Once::new(); - -/// Returns a reference to the global CgroupFs instance. Panics if not initialized. -pub fn singleton() -> &'static Arc { - 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(); } diff --git a/kernel/src/fs/cgroupfs/systree_node.rs b/kernel/src/fs/cgroupfs/systree_node.rs index 4035e2d93..4e630a880 100644 --- a/kernel/src/fs/cgroupfs/systree_node.rs +++ b/kernel/src/fs/cgroupfs/systree_node.rs @@ -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, } @@ -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, } #[inherit_methods(from = "self.fields")] impl CgroupSystem { /// Adds a child node. - pub fn add_child(&self, new_child: Arc) -> Result<()>; + fn add_child(&self, new_child: Arc) -> Result<()>; } #[inherit_methods(from = "self.fields")] impl CgroupNode { /// Adds a child node. - pub fn add_child(&self, new_child: Arc) -> Result<()>; + fn add_child(&self, new_child: Arc) -> Result<()>; } impl CgroupSystem { - pub(super) fn new() -> Arc { + /// Returns the `CgroupSystem` singleton. + pub(super) fn singleton() -> &'static Arc { + static SINGLETON: Once> = Once::new(); + + SINGLETON.call_once(Self::new) + } + + fn new() -> Arc { 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 { + pub(self) fn new(name: SysStr) -> Arc { let mut builder = SysAttrSetBuilder::new(); // TODO: Add more attributes as needed. The normal cgroup node may have // more attributes than the unified one. diff --git a/kernel/src/fs/devpts/mod.rs b/kernel/src/fs/devpts/mod.rs index 60fe06e0f..6bc9c5ea5 100644 --- a/kernel/src/fs/devpts/mod.rs +++ b/kernel/src/fs/devpts/mod.rs @@ -112,20 +112,19 @@ impl FsType for DevPtsType { "devpts" } - fn create( - &self, - _args: Option, - _disk: Option>, - _ctx: &Context, - ) -> Result> { - Ok(DevPts::new()) - } - fn properties(&self) -> FsProperties { FsProperties::empty() } - fn sysnode(&self) -> Option> { + fn create( + &self, + _args: Option, + _disk: Option>, + ) -> Result> { + Ok(DevPts::new()) + } + + fn sysnode(&self) -> Option> { None } } diff --git a/kernel/src/fs/exfat/fs.rs b/kernel/src/fs/exfat/fs.rs index b8f70e959..a49835570 100644 --- a/kernel/src/fs/exfat/fs.rs +++ b/kernel/src/fs/exfat/fs.rs @@ -458,20 +458,19 @@ impl FsType for ExfatType { "exfat" } - fn create( - &self, - _args: Option, - disk: Option>, - ctx: &Context, - ) -> Result> { - ExfatFS::open(disk.unwrap(), ExfatMountOptions::default()).map(|fs| fs as _) - } - fn properties(&self) -> FsProperties { FsProperties::NEED_DISK } - fn sysnode(&self) -> Option> { + fn create( + &self, + _args: Option, + disk: Option>, + ) -> Result> { + ExfatFS::open(disk.unwrap(), ExfatMountOptions::default()).map(|fs| fs as _) + } + + fn sysnode(&self) -> Option> { None } } diff --git a/kernel/src/fs/ext2/fs.rs b/kernel/src/fs/ext2/fs.rs index cafdc925a..92da93511 100644 --- a/kernel/src/fs/ext2/fs.rs +++ b/kernel/src/fs/ext2/fs.rs @@ -446,20 +446,19 @@ impl FsType for Ext2Type { "ext2" } - fn create( - &self, - _args: Option, - disk: Option>, - _ctx: &Context, - ) -> Result> { - Ext2::open(disk.unwrap()).map(|fs| fs as _) - } - fn properties(&self) -> FsProperties { FsProperties::NEED_DISK } - fn sysnode(&self) -> Option> { + fn create( + &self, + _args: Option, + disk: Option>, + ) -> Result> { + Ext2::open(disk.unwrap()).map(|fs| fs as _) + } + + fn sysnode(&self) -> Option> { None } } diff --git a/kernel/src/fs/overlayfs/fs.rs b/kernel/src/fs/overlayfs/fs.rs index f4e9f43d8..edf2642b6 100644 --- a/kernel/src/fs/overlayfs/fs.rs +++ b/kernel/src/fs/overlayfs/fs.rs @@ -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, _disk: Option>, - ctx: &Context, ) -> Result> { 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> { + fn sysnode(&self) -> Option> { None } } diff --git a/kernel/src/fs/procfs/mod.rs b/kernel/src/fs/procfs/mod.rs index 68b141acf..014efda52 100644 --- a/kernel/src/fs/procfs/mod.rs +++ b/kernel/src/fs/procfs/mod.rs @@ -93,20 +93,19 @@ impl FsType for ProcFsType { "proc" } - fn create( - &self, - _args: Option, - _disk: Option>, - _ctx: &Context, - ) -> Result> { - Ok(ProcFS::new()) - } - fn properties(&self) -> FsProperties { FsProperties::empty() } - fn sysnode(&self) -> Option> { + fn create( + &self, + _args: Option, + _disk: Option>, + ) -> Result> { + Ok(ProcFS::new()) + } + + fn sysnode(&self) -> Option> { None } } diff --git a/kernel/src/fs/ramfs/fs.rs b/kernel/src/fs/ramfs/fs.rs index 414c8696b..4dcc7b804 100644 --- a/kernel/src/fs/ramfs/fs.rs +++ b/kernel/src/fs/ramfs/fs.rs @@ -1279,20 +1279,19 @@ impl FsType for RamFsType { "ramfs" } - fn create( - &self, - _args: Option, - _disk: Option>, - _ctx: &Context, - ) -> Result> { - Ok(RamFS::new()) - } - fn properties(&self) -> FsProperties { FsProperties::empty() } - fn sysnode(&self) -> Option> { + fn create( + &self, + _args: Option, + _disk: Option>, + ) -> Result> { + Ok(RamFS::new()) + } + + fn sysnode(&self) -> Option> { None } } diff --git a/kernel/src/fs/registry.rs b/kernel/src/fs/registry.rs index 88c0031f5..d3e541ef5 100644 --- a/kernel/src/fs/registry.rs +++ b/kernel/src/fs/registry.rs @@ -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, disk: Option>, - ctx: &Context, ) -> Result>; /// 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>; + fn sysnode(&self) -> Option>; } bitflags! { diff --git a/kernel/src/fs/sysfs/fs.rs b/kernel/src/fs/sysfs/fs.rs index 6b0d84a91..46dece3c6 100644 --- a/kernel/src/fs/sysfs/fs.rs +++ b/kernel/src/fs/sysfs/fs.rs @@ -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, } @@ -26,7 +27,19 @@ const BLOCK_SIZE: usize = 4096; const NAME_MAX: usize = 255; impl SysFs { - pub(crate) fn new() -> Arc { + /// Returns the `SysFs` singleton. + pub(super) fn singleton() -> &'static Arc { + static SINGLETON: Once> = Once::new(); + + SINGLETON.call_once(Self::new) + } + + #[cfg(ktest)] + pub(super) fn new_for_ktest() -> Arc { + Self::new() + } + + fn new() -> Arc { 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, _disk: Option>, - _ctx: &Context, ) -> Result> { - 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> { + fn sysnode(&self) -> Option> { None } } diff --git a/kernel/src/fs/sysfs/inode.rs b/kernel/src/fs/sysfs/inode.rs index f446e2fa7..89a0b5cfb 100644 --- a/kernel/src/fs/sysfs/inode.rs +++ b/kernel/src/fs/sysfs/inode.rs @@ -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.this.upgrade().expect("Weak ref invalid") + self.this + .upgrade() + .expect("invalid weak reference to `self`") } } impl Inode for SysFsInode { fn fs(&self) -> Arc { - super::singleton().clone() + SysFs::singleton().clone() } fn create(&self, _name: &str, _type_: InodeType, _mode: InodeMode) -> Result> { - Err(Error::new(Errno::EPERM)) + Err(Error::with_message( + Errno::EPERM, + "file creation under sysfs is not allowed", + )) } } diff --git a/kernel/src/fs/sysfs/mod.rs b/kernel/src/fs/sysfs/mod.rs index 37448fb23..5ea5e7b38 100644 --- a/kernel/src/fs/sysfs/mod.rs +++ b/kernel/src/fs/sysfs/mod.rs @@ -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> = Once::new(); - -/// Returns a reference to the global [`SysFs`] instance. Panics if not initialized. -pub fn singleton() -> &'static Arc { - 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(); diff --git a/kernel/src/fs/sysfs/test.rs b/kernel/src/fs/sysfs/test.rs index bf37c9822..389e756f3 100644 --- a/kernel/src/fs/sysfs/test.rs +++ b/kernel/src/fs/sysfs/test.rs @@ -231,7 +231,7 @@ fn create_mock_systree_instance() -> &'static Arc { // Initialize a SysFs instance using the mock systree. fn init_sysfs_with_mock_tree() -> Arc { let _ = create_mock_systree_instance(); - SysFs::new() + SysFs::new_for_ktest() } #[ktest] diff --git a/kernel/src/fs/tmpfs/fs.rs b/kernel/src/fs/tmpfs/fs.rs index f9b8bb7c6..2c6fac4e4 100644 --- a/kernel/src/fs/tmpfs/fs.rs +++ b/kernel/src/fs/tmpfs/fs.rs @@ -44,22 +44,21 @@ impl FsType for TmpFsType { "tmpfs" } + fn properties(&self) -> FsProperties { + FsProperties::empty() + } + fn create( &self, _args: Option, _disk: Option>, - _ctx: &Context, ) -> Result> { Ok(Arc::new(TmpFs { inner: RamFS::new(), })) } - fn properties(&self) -> FsProperties { - FsProperties::empty() - } - - fn sysnode(&self) -> Option> { + fn sysnode(&self) -> Option> { None } } diff --git a/kernel/src/syscall/mount.rs b/kernel/src/syscall/mount.rs index 20b98ab8d..7e3cb7eb9 100644 --- a/kernel/src/syscall/mount.rs +++ b/kernel/src/syscall/mount.rs @@ -180,7 +180,7 @@ fn get_fs( None }; - fs_type.create(data, disk, ctx) + fs_type.create(data, disk) } bitflags! {