diff --git a/kernel/aster-nix/src/fs/procfs/filesystems.rs b/kernel/aster-nix/src/fs/procfs/filesystems.rs new file mode 100644 index 000000000..ce1a23db9 --- /dev/null +++ b/kernel/aster-nix/src/fs/procfs/filesystems.rs @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: MPL-2.0 + +use alloc::format; + +use crate::{ + fs::{ + procfs::template::{FileOps, ProcFileBuilder}, + utils::Inode, + }, + prelude::*, +}; + +/// Represents the inode at /proc/filesystems. +pub struct FileSystemsFileOps; + +impl FileSystemsFileOps { + pub fn new_inode(parent: Weak) -> Arc { + ProcFileBuilder::new(Self).parent(parent).build().unwrap() + } +} + +impl FileOps for FileSystemsFileOps { + fn data(&self) -> Result> { + let mut result = String::new(); + for fs in FILESYSTEM_TYPES.iter() { + if fs.is_nodev { + result.push_str(&format!("nodev\t{}\n", fs.name)); + } else { + result.push_str(&format!("\t{}\n", fs.name)); + } + } + Ok(result.into_bytes()) + } +} + +lazy_static! { + static ref FILESYSTEM_TYPES: Vec = { + vec![ + FileSystemType::new("proc", true), + FileSystemType::new("ramfs", true), + FileSystemType::new("devpts", true), + FileSystemType::new("ext2", false), + FileSystemType::new("exfat", false), + ] + }; +} + +struct FileSystemType { + name: String, + is_nodev: bool, +} + +impl FileSystemType { + fn new(name: &str, is_nodev: bool) -> Self { + FileSystemType { + name: name.to_string(), + is_nodev, + } + } +} diff --git a/kernel/aster-nix/src/fs/procfs/mod.rs b/kernel/aster-nix/src/fs/procfs/mod.rs index d9b9450bf..d698df661 100644 --- a/kernel/aster-nix/src/fs/procfs/mod.rs +++ b/kernel/aster-nix/src/fs/procfs/mod.rs @@ -11,11 +11,15 @@ use self::{ }; use crate::{ events::Observer, - fs::utils::{DirEntryVecExt, FileSystem, FsFlags, Inode, SuperBlock, NAME_MAX}, + fs::{ + procfs::filesystems::FileSystemsFileOps, + utils::{DirEntryVecExt, FileSystem, FsFlags, Inode, SuperBlock, NAME_MAX}, + }, prelude::*, process::{process_table, process_table::PidEvent, Pid}, }; +mod filesystems; mod pid; mod self_; mod sys; @@ -96,6 +100,8 @@ impl DirOps for RootDirOps { SelfSymOps::new_inode(this_ptr.clone()) } else if name == "sys" { SysDirOps::new_inode(this_ptr.clone()) + } else if name == "filesystems" { + FileSystemsFileOps::new_inode(this_ptr.clone()) } else if let Ok(pid) = name.parse::() { let process_ref = process_table::get_process(pid).ok_or_else(|| Error::new(Errno::ENOENT))?; @@ -114,6 +120,9 @@ impl DirOps for RootDirOps { let mut cached_children = this.cached_children().write(); cached_children.put_entry_if_not_found("self", || SelfSymOps::new_inode(this_ptr.clone())); cached_children.put_entry_if_not_found("sys", || SysDirOps::new_inode(this_ptr.clone())); + cached_children.put_entry_if_not_found("filesystems", || { + FileSystemsFileOps::new_inode(this_ptr.clone()) + }); for process in process_table::process_table().iter() { let pid = process.pid().to_string();