From 498c2f3c914d59ca89cd3ccd083f72a76eb68cee Mon Sep 17 00:00:00 2001 From: Chen Chengjun Date: Fri, 31 Oct 2025 08:42:31 +0000 Subject: [PATCH] Make FsFlags consistent with Linux's super block flags --- kernel/src/fs/cgroupfs/fs.rs | 5 +- kernel/src/fs/configfs/fs.rs | 5 +- kernel/src/fs/exfat/fs.rs | 5 +- kernel/src/fs/ext2/fs.rs | 3 +- kernel/src/fs/ext2/impl_for_vfs/fs.rs | 6 +-- kernel/src/fs/overlayfs/fs.rs | 5 +- kernel/src/fs/procfs/mod.rs | 5 +- kernel/src/fs/ramfs/fs.rs | 5 +- kernel/src/fs/registry.rs | 6 ++- kernel/src/fs/sysfs/fs.rs | 5 +- kernel/src/fs/tmpfs/fs.rs | 5 +- kernel/src/fs/utils/fs.rs | 77 +++++++++++++++++++++++++-- kernel/src/syscall/mount.rs | 19 +++++-- 13 files changed, 104 insertions(+), 47 deletions(-) diff --git a/kernel/src/fs/cgroupfs/fs.rs b/kernel/src/fs/cgroupfs/fs.rs index bad43df8e..cbc142d01 100644 --- a/kernel/src/fs/cgroupfs/fs.rs +++ b/kernel/src/fs/cgroupfs/fs.rs @@ -64,10 +64,6 @@ impl FileSystem for CgroupFs { fn sb(&self) -> SuperBlock { self.sb.clone() } - - fn flags(&self) -> FsFlags { - FsFlags::empty() - } } pub(super) struct CgroupFsType; @@ -83,6 +79,7 @@ impl FsType for CgroupFsType { fn create( &self, + _flags: FsFlags, _args: Option, _disk: Option>, ) -> Result> { diff --git a/kernel/src/fs/configfs/fs.rs b/kernel/src/fs/configfs/fs.rs index 08423a19f..3038a3141 100644 --- a/kernel/src/fs/configfs/fs.rs +++ b/kernel/src/fs/configfs/fs.rs @@ -69,10 +69,6 @@ impl FileSystem for ConfigFs { fn sb(&self) -> SuperBlock { self.sb.clone() } - - fn flags(&self) -> FsFlags { - FsFlags::empty() - } } pub(super) struct ConfigFsType; @@ -88,6 +84,7 @@ impl FsType for ConfigFsType { fn create( &self, + _flags: FsFlags, _args: Option, _disk: Option>, ) -> Result> { diff --git a/kernel/src/fs/exfat/fs.rs b/kernel/src/fs/exfat/fs.rs index 1b84fe499..cebd655a1 100644 --- a/kernel/src/fs/exfat/fs.rs +++ b/kernel/src/fs/exfat/fs.rs @@ -417,10 +417,6 @@ impl FileSystem for ExfatFs { fn sb(&self) -> SuperBlock { SuperBlock::new(BOOT_SIGNATURE as u64, self.sector_size(), MAX_NAME_LENGTH) } - - fn flags(&self) -> FsFlags { - FsFlags::DENTRY_UNEVICTABLE - } } #[derive(Clone, Debug, Default)] @@ -463,6 +459,7 @@ impl FsType for ExfatType { fn create( &self, + _flags: FsFlags, _args: Option, disk: Option>, ) -> Result> { diff --git a/kernel/src/fs/ext2/fs.rs b/kernel/src/fs/ext2/fs.rs index 92da93511..2188a272d 100644 --- a/kernel/src/fs/ext2/fs.rs +++ b/kernel/src/fs/ext2/fs.rs @@ -11,7 +11,7 @@ use super::{ }; use crate::fs::{ registry::{FsProperties, FsType}, - utils::FileSystem, + utils::{FileSystem, FsFlags}, }; /// The root inode number. @@ -452,6 +452,7 @@ impl FsType for Ext2Type { fn create( &self, + _flags: FsFlags, _args: Option, disk: Option>, ) -> Result> { diff --git a/kernel/src/fs/ext2/impl_for_vfs/fs.rs b/kernel/src/fs/ext2/impl_for_vfs/fs.rs index bec555bc8..ded2ab844 100644 --- a/kernel/src/fs/ext2/impl_for_vfs/fs.rs +++ b/kernel/src/fs/ext2/impl_for_vfs/fs.rs @@ -5,7 +5,7 @@ use ostd::sync::RwMutexReadGuard; use crate::{ fs::{ ext2::{utils::Dirty, Ext2, SuperBlock as Ext2SuperBlock, MAGIC_NUM as EXT2_MAGIC}, - utils::{FileSystem, FsFlags, Inode, SuperBlock, NAME_MAX}, + utils::{FileSystem, Inode, SuperBlock, NAME_MAX}, }, prelude::*, }; @@ -30,10 +30,6 @@ impl FileSystem for Ext2 { fn sb(&self) -> SuperBlock { SuperBlock::from(self.super_block()) } - - fn flags(&self) -> FsFlags { - FsFlags::empty() - } } impl From>> for SuperBlock { diff --git a/kernel/src/fs/overlayfs/fs.rs b/kernel/src/fs/overlayfs/fs.rs index f12845276..61479deb5 100644 --- a/kernel/src/fs/overlayfs/fs.rs +++ b/kernel/src/fs/overlayfs/fs.rs @@ -190,10 +190,6 @@ impl FileSystem for OverlayFs { // TODO: Fill the super block with valid field values. SuperBlock::new(OVERLAY_FS_MAGIC, BLOCK_SIZE, NAME_MAX) } - - fn flags(&self) -> FsFlags { - FsFlags::empty() - } } impl OverlayFs { @@ -1117,6 +1113,7 @@ impl FsType for OverlayFsType { fn create( &self, + _flags: FsFlags, args: Option, _disk: Option>, ) -> Result> { diff --git a/kernel/src/fs/procfs/mod.rs b/kernel/src/fs/procfs/mod.rs index 270213420..89cbe2787 100644 --- a/kernel/src/fs/procfs/mod.rs +++ b/kernel/src/fs/procfs/mod.rs @@ -92,10 +92,6 @@ impl FileSystem for ProcFs { fn sb(&self) -> SuperBlock { self.sb.clone() } - - fn flags(&self) -> FsFlags { - FsFlags::empty() - } } struct ProcFsType; @@ -111,6 +107,7 @@ impl FsType for ProcFsType { fn create( &self, + _flags: FsFlags, _args: Option, _disk: Option>, ) -> Result> { diff --git a/kernel/src/fs/ramfs/fs.rs b/kernel/src/fs/ramfs/fs.rs index c05b52bc8..eb7d5a2fa 100644 --- a/kernel/src/fs/ramfs/fs.rs +++ b/kernel/src/fs/ramfs/fs.rs @@ -89,10 +89,6 @@ impl FileSystem for RamFs { fn sb(&self) -> SuperBlock { self.sb.clone() } - - fn flags(&self) -> FsFlags { - FsFlags::DENTRY_UNEVICTABLE - } } /// An inode of `RamFs`. @@ -1288,6 +1284,7 @@ impl FsType for RamFsType { fn create( &self, + _flags: FsFlags, _args: Option, _disk: Option>, ) -> Result> { diff --git a/kernel/src/fs/registry.rs b/kernel/src/fs/registry.rs index b23982d60..6b95a121d 100644 --- a/kernel/src/fs/registry.rs +++ b/kernel/src/fs/registry.rs @@ -7,7 +7,10 @@ use aster_systree::{ use spin::Once; use crate::{ - fs::{sysfs, utils::FileSystem}, + fs::{ + sysfs, + utils::{FileSystem, FsFlags}, + }, prelude::*, }; @@ -25,6 +28,7 @@ pub trait FsType: Send + Sync + 'static { /// if `self.properties()` contains `FsProperties::NEED_DISK`. fn create( &self, + flags: FsFlags, args: Option, disk: Option>, ) -> Result>; diff --git a/kernel/src/fs/sysfs/fs.rs b/kernel/src/fs/sysfs/fs.rs index b2544d2e7..40f45d6b7 100644 --- a/kernel/src/fs/sysfs/fs.rs +++ b/kernel/src/fs/sysfs/fs.rs @@ -65,10 +65,6 @@ impl FileSystem for SysFs { fn sb(&self) -> SuperBlock { self.sb.clone() } - - fn flags(&self) -> FsFlags { - FsFlags::empty() - } } pub(super) struct SysFsType; @@ -84,6 +80,7 @@ impl FsType for SysFsType { fn create( &self, + _flags: FsFlags, _args: Option, _disk: Option>, ) -> Result> { diff --git a/kernel/src/fs/tmpfs/fs.rs b/kernel/src/fs/tmpfs/fs.rs index 7fb7c5700..1edc2df8a 100644 --- a/kernel/src/fs/tmpfs/fs.rs +++ b/kernel/src/fs/tmpfs/fs.rs @@ -35,10 +35,6 @@ impl FileSystem for TmpFs { fn sb(&self) -> SuperBlock { self.inner.sb() } - - fn flags(&self) -> FsFlags { - FsFlags::DENTRY_UNEVICTABLE - } } pub(super) struct TmpFsType; @@ -54,6 +50,7 @@ impl FsType for TmpFsType { fn create( &self, + _flags: FsFlags, _args: Option, _disk: Option>, ) -> Result> { diff --git a/kernel/src/fs/utils/fs.rs b/kernel/src/fs/utils/fs.rs index 50b1f71f6..2b49ece5b 100644 --- a/kernel/src/fs/utils/fs.rs +++ b/kernel/src/fs/utils/fs.rs @@ -1,5 +1,9 @@ // SPDX-License-Identifier: MPL-2.0 +use core::sync::atomic::AtomicU32; + +use atomic_integer_wrapper::define_atomic_version_of_integer_like_type; + use super::Inode; use crate::prelude::*; @@ -37,12 +41,68 @@ impl SuperBlock { } bitflags! { + /// Flags for per file system. pub struct FsFlags: u32 { - /// Dentry cannot be evicted. - const DENTRY_UNEVICTABLE = 1 << 1; + /// The filesystem is mounted read-only. + const RDONLY = 1 << 0; + /// Writes are synced at once. + const SYNCHRONOUS = 1 << 4; + /// Allow mandatory locks on an FS. + const MANDLOCK = 1 << 6; + /// Directory modifications are synchronous. + const DIRSYNC = 1 << 7; + /// Suppress certain messages in kernel log. + const SILENT = 1 << 15; + /// Update the on-disk [acm]times lazily. + const LAZYTIME = 1 << 25; } } +impl core::fmt::Display for FsFlags { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + if self.contains(FsFlags::RDONLY) { + write!(f, "ro")?; + } else { + write!(f, "rw")?; + } + if self.contains(FsFlags::SYNCHRONOUS) { + write!(f, ",sync")?; + } + if self.contains(FsFlags::MANDLOCK) { + write!(f, ",mandlock")?; + } + if self.contains(FsFlags::DIRSYNC) { + write!(f, ",dirsync")?; + } + if self.contains(FsFlags::SILENT) { + write!(f, ",silent")?; + } + if self.contains(FsFlags::LAZYTIME) { + write!(f, ",lazytime")?; + } + Ok(()) + } +} + +impl From for FsFlags { + fn from(value: u32) -> Self { + Self::from_bits_truncate(value) + } +} + +impl From for u32 { + fn from(value: FsFlags) -> Self { + value.bits() + } +} + +define_atomic_version_of_integer_like_type!(FsFlags, { + /// An atomic version of `FsFlags`. + #[derive(Debug)] + #[expect(dead_code)] + pub struct AtomicFsFlags(AtomicU32); +}); + pub trait FileSystem: Any + Sync + Send { /// Gets the name of this FS type such as `"ext4"` or `"sysfs"`. fn name(&self) -> &'static str; @@ -57,7 +117,18 @@ pub trait FileSystem: Any + Sync + Send { fn sb(&self) -> SuperBlock; /// Returns the flags of this file system. - fn flags(&self) -> FsFlags; + fn flags(&self) -> FsFlags { + // TODO: Currently we do not support any flags for filesystems. + // Remove the default empty implementation in the future. + FsFlags::empty() + } + + /// Sets the flags of this file system. + fn set_fs_flags(&self, _flags: FsFlags, _data: Option, _ctx: &Context) -> Result<()> { + // TODO: Remove the default empty implementation in the future. + warn!("setting file system flags is not implemented"); + Ok(()) + } } impl dyn FileSystem { diff --git a/kernel/src/syscall/mount.rs b/kernel/src/syscall/mount.rs index d356fd1e6..99e3024bc 100644 --- a/kernel/src/syscall/mount.rs +++ b/kernel/src/syscall/mount.rs @@ -142,9 +142,10 @@ fn do_move_mount_old(src_name: CString, dst_path: Path, ctx: &Context) -> Result Ok(()) } -/// Mount a new filesystem. +/// Mounts a new filesystem. fn do_new_mount( devname: CString, + flags: MountFlags, fs_type: Vaddr, target_path: Path, data: Vaddr, @@ -158,15 +159,16 @@ fn do_new_mount( if fs_type.is_empty() { return_errno_with_message!(Errno::EINVAL, "fs_type is empty"); } - let fs = get_fs(fs_type, devname, data, ctx)?; + let fs = get_fs(devname, flags, fs_type, data, ctx)?; target_path.mount(fs, ctx)?; Ok(()) } -/// Get the filesystem by fs_type and devname. +/// Gets the filesystem by fs_type and devname. fn get_fs( - fs_type: CString, devname: CString, + flags: MountFlags, + fs_type: CString, data: Vaddr, ctx: &Context, ) -> Result> { @@ -192,7 +194,7 @@ fn get_fs( None }; - fs_type.create(data, disk) + fs_type.create(flags.into(), data, disk) } bitflags! { @@ -219,5 +221,12 @@ bitflags! { const MS_SHARED = 1 << 20; // Change to shared. const MS_RELATIME = 1 << 21; // Update atime relative to mtime/ctime. const MS_KERNMOUNT = 1 << 22; // This is a kern_mount call. + const MS_STRICTATIME = 1 << 24; // Always perform atime updates. + const MS_LAZYTIME = 1 << 25; // Update the on-disk [acm]times lazily. + } +} +impl From for FsFlags { + fn from(flags: MountFlags) -> Self { + Self::from_bits_truncate(flags.bits()) } }