From aa33845967473bcd892ef72c21331283378d9612 Mon Sep 17 00:00:00 2001 From: Chaoqun Zheng Date: Wed, 14 Jan 2026 23:11:38 +0800 Subject: [PATCH] Refactor `Metadata`'s fields and document them. Besides, change `MajorId`'s lower bound to 0, which is used to represents a invalid or absent device (pseudo filesystems). --- Cargo.lock | 2 + kernel/libs/device-id/Cargo.toml | 2 + kernel/libs/device-id/src/lib.rs | 72 +++++++++++- kernel/src/fs/devpts/mod.rs | 12 +- kernel/src/fs/devpts/ptmx.rs | 12 +- kernel/src/fs/devpts/slave.rs | 12 +- kernel/src/fs/exfat/inode.rs | 18 +-- kernel/src/fs/ext2/inode.rs | 21 ++-- kernel/src/fs/mod.rs | 1 + kernel/src/fs/path/dentry.rs | 4 +- kernel/src/fs/procfs/template/mod.rs | 12 +- kernel/src/fs/pseudofs.rs | 35 +++--- kernel/src/fs/ramfs/fs.rs | 20 ++-- kernel/src/fs/utils/inode.rs | 157 ++++++++++++++++++++------- kernel/src/fs/utils/systree_inode.rs | 23 ++-- kernel/src/syscall/mount.rs | 4 +- kernel/src/syscall/stat.rs | 16 +-- kernel/src/syscall/statx.rs | 20 ++-- kernel/src/vm/vmar/vm_mapping.rs | 4 +- 19 files changed, 305 insertions(+), 142 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 513726330..5dfa6a764 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -722,6 +722,8 @@ name = "device-id" version = "0.1.0" dependencies = [ "aster-util", + "id-alloc", + "spin", ] [[package]] diff --git a/kernel/libs/device-id/Cargo.toml b/kernel/libs/device-id/Cargo.toml index 5c09fa020..37577aa22 100644 --- a/kernel/libs/device-id/Cargo.toml +++ b/kernel/libs/device-id/Cargo.toml @@ -7,6 +7,8 @@ edition.workspace = true [dependencies] aster-util.workspace = true +id-alloc.workspace = true +spin.workspace = true [lints] workspace = true diff --git a/kernel/libs/device-id/src/lib.rs b/kernel/libs/device-id/src/lib.rs index e63b592a5..4de3adf51 100644 --- a/kernel/libs/device-id/src/lib.rs +++ b/kernel/libs/device-id/src/lib.rs @@ -13,6 +13,61 @@ #![deny(unsafe_code)] use aster_util::ranged_integer::{RangedU16, RangedU32}; +use id_alloc::IdAlloc; +use spin::{Mutex, Once}; + +pub struct PseudoFSDeviceIdAllocator { + minor_allocator: Mutex, +} + +/// An allocator for pseudo filesystems (no backing block device) device ID. +/// +/// This follows the Linux convention where pseudo filesystems use major=0 +/// and dynamically allocate minor numbers (starting from 1) to distinguish different +/// pseudo filesystem instances. +/// +/// Reference: +impl PseudoFSDeviceIdAllocator { + fn new() -> Self { + let mut minor_allocator = IdAlloc::with_capacity(MinorId::MAX.get() as usize + 1); + // Mark 0 as allocated to ensure minor numbers start from 1. + let _ = minor_allocator.alloc_specific(0); + + Self { + minor_allocator: Mutex::new(minor_allocator), + } + } + + /// Allocate a device ID for pseudo filesystems. + /// Returns `None` if minor number allocation fails (exhausted). + /// + /// # Panics + /// + /// Panics if the allocator was not initialized. + pub fn allocate(&self) -> DeviceId { + let major = MajorId::new(0); + let minor = self.minor_allocator.lock().alloc().unwrap() as u32; + + DeviceId::new(major, MinorId::new(minor)) + } + + /// Free a dynamically allocated pseudo filesystem device ID. + /// + /// # Panics + /// + /// Panics if the device ID's major is not 0. + pub fn release(&mut self, id: DeviceId) { + debug_assert!(id.major().get() == 0); + + self.minor_allocator.lock().free(id.minor().get() as usize); + } +} + +pub static PSEUDO_FS_DEVICE_ID_ALLOCATOR: Once = Once::new(); + +pub fn init() { + PSEUDO_FS_DEVICE_ID_ALLOCATOR.call_once(PseudoFSDeviceIdAllocator::new); +} /// A device ID, embedding the major ID and minor ID. #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -24,6 +79,11 @@ impl DeviceId { Self(((major.get() as u32) << 20) | minor.get()) } + /// FIXME: just a placeholder for now. + pub const fn none() -> Self { + Self(0) + } + /// Returns the encoded `u32` value. pub fn to_raw(&self) -> u32 { self.0 @@ -38,6 +98,11 @@ impl DeviceId { pub fn minor(&self) -> MinorId { MinorId::new(self.0 & 0xf_ffff) } + + /// Checks if the container device is valid (major != 0). + pub fn has_valid_container(&self) -> bool { + self.major().get() != 0 + } } impl DeviceId { @@ -92,10 +157,13 @@ const MAX_MINOR_ID: u32 = 0x000f_ffff; /// The major component of a device ID. /// -/// A major ID is a non-zero, 12-bit integer, thus falling in the range of `1..(1u16 << 12)`. +/// A major ID is a 12-bit integer, thus falling in the range of `0..(1u16 << 12)`. +/// +/// - **0**: Represents an invalid or absent device (used for pseudo filesystems) +/// - **1-4095**: Valid major device numbers /// /// Reference: . -pub type MajorId = RangedU16<1, MAX_MAJOR_ID>; +pub type MajorId = RangedU16<0, MAX_MAJOR_ID>; /// The minor component of a device ID. /// diff --git a/kernel/src/fs/devpts/mod.rs b/kernel/src/fs/devpts/mod.rs index 67ad2027a..86b83afa5 100644 --- a/kernel/src/fs/devpts/mod.rs +++ b/kernel/src/fs/devpts/mod.rs @@ -239,27 +239,27 @@ impl Inode for RootInode { } fn atime(&self) -> Duration { - self.metadata.read().atime + self.metadata.read().last_access_at } fn set_atime(&self, time: Duration) { - self.metadata.write().atime = time; + self.metadata.write().last_access_at = time; } fn mtime(&self) -> Duration { - self.metadata.read().mtime + self.metadata.read().last_modify_at } fn set_mtime(&self, time: Duration) { - self.metadata.write().mtime = time; + self.metadata.write().last_modify_at = time; } fn ctime(&self) -> Duration { - self.metadata.read().ctime + self.metadata.read().last_meta_change_at } fn set_ctime(&self, time: Duration) { - self.metadata.write().ctime = time; + self.metadata.write().last_meta_change_at = time; } fn create(&self, name: &str, type_: InodeType, mode: InodeMode) -> Result> { diff --git a/kernel/src/fs/devpts/ptmx.rs b/kernel/src/fs/devpts/ptmx.rs index 121c0dbd0..8d8d87d51 100644 --- a/kernel/src/fs/devpts/ptmx.rs +++ b/kernel/src/fs/devpts/ptmx.rs @@ -121,27 +121,27 @@ impl Inode for Ptmx { } fn atime(&self) -> Duration { - self.metadata.read().atime + self.metadata.read().last_access_at } fn set_atime(&self, time: Duration) { - self.metadata.write().atime = time; + self.metadata.write().last_access_at = time; } fn mtime(&self) -> Duration { - self.metadata.read().mtime + self.metadata.read().last_modify_at } fn set_mtime(&self, time: Duration) { - self.metadata.write().mtime = time; + self.metadata.write().last_modify_at = time; } fn ctime(&self) -> Duration { - self.metadata.read().ctime + self.metadata.read().last_meta_change_at } fn set_ctime(&self, time: Duration) { - self.metadata.write().ctime = time; + self.metadata.write().last_meta_change_at = time; } fn fs(&self) -> Arc { diff --git a/kernel/src/fs/devpts/slave.rs b/kernel/src/fs/devpts/slave.rs index c66372157..f4db71faa 100644 --- a/kernel/src/fs/devpts/slave.rs +++ b/kernel/src/fs/devpts/slave.rs @@ -120,27 +120,27 @@ impl Inode for PtySlaveInode { } fn atime(&self) -> Duration { - self.metadata.read().atime + self.metadata.read().last_access_at } fn set_atime(&self, time: Duration) { - self.metadata.write().atime = time; + self.metadata.write().last_access_at = time; } fn mtime(&self) -> Duration { - self.metadata.read().mtime + self.metadata.read().last_modify_at } fn set_mtime(&self, time: Duration) { - self.metadata.write().mtime = time; + self.metadata.write().last_modify_at = time; } fn ctime(&self) -> Duration { - self.metadata.read().ctime + self.metadata.read().last_meta_change_at } fn set_ctime(&self, time: Duration) { - self.metadata.write().ctime = time; + self.metadata.write().last_meta_change_at = time; } fn fs(&self) -> Arc { diff --git a/kernel/src/fs/exfat/inode.rs b/kernel/src/fs/exfat/inode.rs index b7d6e2874..f69accda4 100644 --- a/kernel/src/fs/exfat/inode.rs +++ b/kernel/src/fs/exfat/inode.rs @@ -12,6 +12,7 @@ use aster_block::{ bio::{BioDirection, BioSegment, BioWaiter}, id::{Bid, BlockId}, }; +use device_id::DeviceId; use ostd::mm::{Segment, VmIo, io_util::HasVmReaderWriter}; use super::{ @@ -1358,21 +1359,20 @@ impl Inode for ExfatInode { }; Metadata { - dev: 0, ino: inner.ino, size: inner.size, - blk_size, - blocks: inner.size.div_ceil(blk_size), - atime: inner.atime.as_duration().unwrap_or_default(), - mtime: inner.mtime.as_duration().unwrap_or_default(), - ctime: inner.ctime.as_duration().unwrap_or_default(), + optimal_block_size: blk_size, + nr_sectors_allocated: inner.size.div_ceil(blk_size), + last_access_at: inner.atime.as_duration().unwrap_or_default(), + last_modify_at: inner.mtime.as_duration().unwrap_or_default(), + last_meta_change_at: inner.ctime.as_duration().unwrap_or_default(), type_: inner.inode_type, mode: inner.make_mode(), - nlinks, + nr_hard_links: nlinks, uid: Uid::new(inner.fs().mount_option().fs_uid as u32), gid: Gid::new(inner.fs().mount_option().fs_gid as u32), - //real device - rdev: 0, + container_dev_id: DeviceId::none(), // FIXME: placeholder + self_dev_id: None, } } diff --git a/kernel/src/fs/ext2/inode.rs b/kernel/src/fs/ext2/inode.rs index 686bde9c8..74f7392dc 100644 --- a/kernel/src/fs/ext2/inode.rs +++ b/kernel/src/fs/ext2/inode.rs @@ -6,6 +6,7 @@ use alloc::{borrow::ToOwned, rc::Rc}; use core::sync::atomic::{AtomicUsize, Ordering}; +use device_id::DeviceId; use inherit_methods_macro::inherit_methods; use ostd::{const_assert, mm::io_util::HasVmReaderWriter}; @@ -106,20 +107,24 @@ impl Inode { let inner = self.inner.read(); let id = self.fs.upgrade().unwrap().block_device().id(); Metadata { - dev: id.as_encoded_u64(), ino: self.ino() as _, size: inner.file_size() as _, - blk_size: BLOCK_SIZE, - blocks: inner.blocks_count() as _, - atime: inner.atime(), - mtime: inner.mtime(), - ctime: inner.ctime(), + optimal_block_size: BLOCK_SIZE, + nr_sectors_allocated: inner.blocks_count() as _, + last_access_at: inner.atime(), + last_modify_at: inner.mtime(), + last_meta_change_at: inner.ctime(), type_: self.type_, mode: InodeMode::from(inner.file_perm()), - nlinks: inner.hard_links() as _, + nr_hard_links: inner.hard_links() as _, uid: Uid::new(inner.uid()), gid: Gid::new(inner.gid()), - rdev: self.device_id(), + container_dev_id: id, + self_dev_id: if self.device_id() != 0 { + DeviceId::from_encoded_u64(self.device_id()) + } else { + None + }, } } diff --git a/kernel/src/fs/mod.rs b/kernel/src/fs/mod.rs index 74737b5fc..4ce4624ce 100644 --- a/kernel/src/fs/mod.rs +++ b/kernel/src/fs/mod.rs @@ -34,6 +34,7 @@ use crate::{ }; pub fn init() { + device_id::init(); registry::init(); sysfs::init(); diff --git a/kernel/src/fs/path/dentry.rs b/kernel/src/fs/path/dentry.rs index 6e039903e..a8895a853 100644 --- a/kernel/src/fs/path/dentry.rs +++ b/kernel/src/fs/path/dentry.rs @@ -371,7 +371,7 @@ impl DirDentry<'_> { dir_inode.unlink(name)?; - let nlinks = child_inode.metadata().nlinks; + let nlinks = child_inode.metadata().nr_hard_links; fs::notify::on_link_count(&child_inode); if nlinks == 0 { // FIXME: `DELETE_SELF` should be generated after closing the last FD. @@ -422,7 +422,7 @@ impl DirDentry<'_> { dir_inode.rmdir(name)?; - let nlinks = child_inode.metadata().nlinks; + let nlinks = child_inode.metadata().nr_hard_links; if nlinks == 0 { // FIXME: `DELETE_SELF` should be generated after closing the last FD. fs::notify::on_inode_removed(&child_inode); diff --git a/kernel/src/fs/procfs/template/mod.rs b/kernel/src/fs/procfs/template/mod.rs index bb664f9fe..021b7b56c 100644 --- a/kernel/src/fs/procfs/template/mod.rs +++ b/kernel/src/fs/procfs/template/mod.rs @@ -58,27 +58,27 @@ impl Common { } pub fn atime(&self) -> Duration { - self.metadata.read().atime + self.metadata.read().last_access_at } pub fn set_atime(&self, time: Duration) { - self.metadata.write().atime = time; + self.metadata.write().last_access_at = time; } pub fn mtime(&self) -> Duration { - self.metadata.read().mtime + self.metadata.read().last_modify_at } pub fn set_mtime(&self, time: Duration) { - self.metadata.write().mtime = time; + self.metadata.write().last_modify_at = time; } pub fn ctime(&self) -> Duration { - self.metadata.read().ctime + self.metadata.read().last_meta_change_at } pub fn set_ctime(&self, time: Duration) { - self.metadata.write().ctime = time; + self.metadata.write().last_meta_change_at = time; } pub fn mode(&self) -> Result { diff --git a/kernel/src/fs/pseudofs.rs b/kernel/src/fs/pseudofs.rs index d34ef12ce..e5ac2eb09 100644 --- a/kernel/src/fs/pseudofs.rs +++ b/kernel/src/fs/pseudofs.rs @@ -6,6 +6,7 @@ use core::{ time::Duration, }; +use device_id::DeviceId; use spin::Once; use super::utils::{Extension, InodeIo, StatusFlags}; @@ -372,20 +373,20 @@ impl PseudoInode { let type_ = InodeType::from(type_); let metadata = Metadata { - dev: 0, ino, size: 0, - blk_size: aster_block::BLOCK_SIZE, - blocks: 0, - atime: now, - mtime: now, - ctime: now, + optimal_block_size: aster_block::BLOCK_SIZE, + nr_sectors_allocated: 0, + last_access_at: now, + last_modify_at: now, + last_meta_change_at: now, type_, mode, - nlinks: 1, + nr_hard_links: 1, uid, gid, - rdev: 0, + container_dev_id: DeviceId::none(), // FIXME: placeholder + self_dev_id: None, }; PseudoInode { @@ -462,7 +463,7 @@ impl Inode for PseudoInode { let mut meta = self.metadata.lock(); meta.mode = mode; - meta.ctime = now(); + meta.last_meta_change_at = now(); Ok(()) } @@ -473,7 +474,7 @@ impl Inode for PseudoInode { fn set_owner(&self, uid: Uid) -> Result<()> { let mut meta = self.metadata.lock(); meta.uid = uid; - meta.ctime = now(); + meta.last_meta_change_at = now(); Ok(()) } @@ -484,32 +485,32 @@ impl Inode for PseudoInode { fn set_group(&self, gid: Gid) -> Result<()> { let mut meta = self.metadata.lock(); meta.gid = gid; - meta.ctime = now(); + meta.last_meta_change_at = now(); Ok(()) } fn atime(&self) -> Duration { - self.metadata.lock().atime + self.metadata.lock().last_access_at } fn set_atime(&self, time: Duration) { - self.metadata.lock().atime = time; + self.metadata.lock().last_access_at = time; } fn mtime(&self) -> Duration { - self.metadata.lock().mtime + self.metadata.lock().last_modify_at } fn set_mtime(&self, time: Duration) { - self.metadata.lock().mtime = time; + self.metadata.lock().last_modify_at = time; } fn ctime(&self) -> Duration { - self.metadata.lock().ctime + self.metadata.lock().last_meta_change_at } fn set_ctime(&self, time: Duration) { - self.metadata.lock().ctime = time; + self.metadata.lock().last_meta_change_at = time; } fn open( diff --git a/kernel/src/fs/ramfs/fs.rs b/kernel/src/fs/ramfs/fs.rs index 725ccc2fd..bf411bfc2 100644 --- a/kernel/src/fs/ramfs/fs.rs +++ b/kernel/src/fs/ramfs/fs.rs @@ -1170,20 +1170,24 @@ impl Inode for RamInode { let rdev = self.inner.device_id().unwrap_or(0); let inode_metadata = self.metadata.lock(); Metadata { - dev: 0, ino: self.ino as _, size: inode_metadata.size, - blk_size: BLOCK_SIZE, - blocks: inode_metadata.blocks, - atime: inode_metadata.atime, - mtime: inode_metadata.mtime, - ctime: inode_metadata.ctime, + optimal_block_size: BLOCK_SIZE, + nr_sectors_allocated: inode_metadata.blocks, + last_access_at: inode_metadata.atime, + last_modify_at: inode_metadata.mtime, + last_meta_change_at: inode_metadata.ctime, type_: self.typ, mode: inode_metadata.mode, - nlinks: inode_metadata.nlinks, + nr_hard_links: inode_metadata.nlinks, uid: inode_metadata.uid, gid: inode_metadata.gid, - rdev, + container_dev_id: DeviceId::none(), // FIXME: placeholder + self_dev_id: if rdev == 0 { + None + } else { + DeviceId::from_encoded_u64(rdev) + }, } } diff --git a/kernel/src/fs/utils/inode.rs b/kernel/src/fs/utils/inode.rs index 6122019da..3043bd839 100644 --- a/kernel/src/fs/utils/inode.rs +++ b/kernel/src/fs/utils/inode.rs @@ -6,6 +6,7 @@ use alloc::boxed::ThinBox; use core::time::Duration; use core2::io::{Error as IoError, ErrorKind as IoErrorKind, Result as IoResult, Write}; +use device_id::DeviceId; use ostd::task::Task; use spin::Once; @@ -124,101 +125,177 @@ impl From for Permission { } } +/// File metadata, providing detailed information about an inode. +/// +/// Asterinas's type-safe counterparts for Linux's `struct stat`. #[derive(Debug, Clone, Copy)] pub struct Metadata { - pub dev: u64, + /// The inode number, which uniquely identifies the file within the filesystem. + /// + /// Corresponds to `st_ino`. pub ino: u64, + + /// The size of the inode. + /// + /// The interpretation depends on `inode_type`: + /// - **Regular File**: The total length of the file content. + /// - **Directory**: The size of the directory's internal table (usually a multiple of block size). + /// - **Symbolic Link**: The length of the target pathname. + /// - **Device/Socket/FIFO**: Usually zero. + /// + /// Corresponds to `st_size`. pub size: usize, - pub blk_size: usize, - pub blocks: usize, - pub atime: Duration, - pub mtime: Duration, - pub ctime: Duration, + + /// The optimal block size for filesystem I/O operations. + /// + /// Corresponds to `st_blksize`. + pub optimal_block_size: usize, + + /// Number of 512-byte sectors allocated for the inode on disk. + /// + /// Corresponds to `st_blocks`. + /// + /// This represents physical usage. + /// For sparse files (those having holes), `size` is greater than this field. + /// For files with preallocated blocks (`FALLOC_FL_KEEP_SIZE`), + /// `size` is smaller than this field. + pub nr_sectors_allocated: usize, + + /// The timestamp of the last access to the inode's data. + /// + /// Corresponds to `st_atime`. + pub last_access_at: Duration, + + /// The timestamp of the last modification to the inode's content. + /// + /// Corresponds to `st_mtime`. + pub last_modify_at: Duration, + + /// The timestamp of the last change to the inode's metadata. + /// + /// This is updated when permissions, ownership, or link count change, + /// not just when the inode content is modified. + /// + /// Corresponds to `st_ctime`. + pub last_meta_change_at: Duration, + + /// The type of the inode (e.g., regular file, directory, symlink). + /// + /// Derived from the file type bits of `st_mode` (using the `S_IFMT` mask). pub type_: InodeType, + + /// The inode mode, representing access permissions. + /// + /// Derived from the permission bits of `st_mode`. pub mode: InodeMode, - pub nlinks: usize, + + /// The number of hard links pointing to this inode. + /// + /// Corresponds to `st_nlink`. + pub nr_hard_links: usize, + + /// The User ID (UID) of the inode's owner. + /// + /// Corresponds to `st_uid`. pub uid: Uid, + + /// The Group ID (GID) of the inode's owner. + /// + /// Corresponds to `st_gid`. pub gid: Gid, - pub rdev: u64, + + /// The ID of the device containing the inode. + /// + /// For persisted files, this device could be a on-disk partition or a logical volume (with RAID). + /// For pseudo files (e.g., those on sockfs), this device is also "pseudo". + /// + /// Corresponds to `st_dev`. + pub container_dev_id: DeviceId, + + /// The device ID of the inode itself, if this inode represents a special device file (character or block). + /// + /// Corresponds to `st_rdev`. + pub self_dev_id: Option, } impl Metadata { pub fn new_dir(ino: u64, mode: InodeMode, blk_size: usize) -> Self { let now = RealTimeCoarseClock::get().read_time(); Self { - dev: 0, ino, size: 2, - blk_size, - blocks: 1, - atime: now, - mtime: now, - ctime: now, + optimal_block_size: blk_size, + nr_sectors_allocated: 1, + last_access_at: now, + last_modify_at: now, + last_meta_change_at: now, type_: InodeType::Dir, mode, - nlinks: 2, + nr_hard_links: 2, uid: Uid::new_root(), gid: Gid::new_root(), - rdev: 0, + container_dev_id: DeviceId::none(), // FIXME: placeholder + self_dev_id: None, } } pub fn new_file(ino: u64, mode: InodeMode, blk_size: usize) -> Self { let now = RealTimeCoarseClock::get().read_time(); Self { - dev: 0, ino, size: 0, - blk_size, - blocks: 0, - atime: now, - mtime: now, - ctime: now, + optimal_block_size: blk_size, + nr_sectors_allocated: 0, + last_access_at: now, + last_modify_at: now, + last_meta_change_at: now, type_: InodeType::File, mode, - nlinks: 1, + nr_hard_links: 1, uid: Uid::new_root(), gid: Gid::new_root(), - rdev: 0, + container_dev_id: DeviceId::none(), // FIXME: placeholder + self_dev_id: None, } } pub fn new_symlink(ino: u64, mode: InodeMode, blk_size: usize) -> Self { let now = RealTimeCoarseClock::get().read_time(); Self { - dev: 0, ino, size: 0, - blk_size, - blocks: 0, - atime: now, - mtime: now, - ctime: now, + optimal_block_size: blk_size, + nr_sectors_allocated: 0, + last_access_at: now, + last_modify_at: now, + last_meta_change_at: now, type_: InodeType::SymLink, mode, - nlinks: 1, + nr_hard_links: 1, uid: Uid::new_root(), gid: Gid::new_root(), - rdev: 0, + container_dev_id: DeviceId::none(), // FIXME: placeholder + self_dev_id: None, } } + pub fn new_device(ino: u64, mode: InodeMode, blk_size: usize, device: &dyn Device) -> Self { let now = RealTimeCoarseClock::get().read_time(); Self { - dev: 0, ino, size: 0, - blk_size, - blocks: 0, - atime: now, - mtime: now, - ctime: now, + optimal_block_size: blk_size, + nr_sectors_allocated: 0, + last_access_at: now, + last_modify_at: now, + last_meta_change_at: now, type_: InodeType::from(device.type_()), mode, - nlinks: 1, + nr_hard_links: 1, uid: Uid::new_root(), gid: Gid::new_root(), - rdev: device.id().as_encoded_u64(), + container_dev_id: DeviceId::none(), // FIXME: placeholder + self_dev_id: Some(device.id()), } } } diff --git a/kernel/src/fs/utils/systree_inode.rs b/kernel/src/fs/utils/systree_inode.rs index 587e1e6d0..1861f10a9 100644 --- a/kernel/src/fs/utils/systree_inode.rs +++ b/kernel/src/fs/utils/systree_inode.rs @@ -12,6 +12,7 @@ use core::time::Duration; use aster_systree::{ SysAttr, SysBranchNode, SysNode, SysNodeId, SysNodeType, SysObj, SysStr, SysSymlink, }; +use device_id::DeviceId; use super::Extension; use crate::{ @@ -74,21 +75,21 @@ pub(in crate::fs) trait SysTreeInodeTy: Send + Sync + 'static { fn new_metadata(ino: u64, type_: InodeType) -> Metadata { let now = RealTimeCoarseClock::get().read_time(); Metadata { - dev: 0, ino, size: 0, - blk_size: 1024, - blocks: 0, - atime: now, - mtime: now, - ctime: now, + optimal_block_size: 1024, + nr_sectors_allocated: 0, + last_access_at: now, + last_modify_at: now, + last_meta_change_at: now, type_, // The mode field in metadata will not be used mode: mkmod!(a=), - nlinks: 1, + nr_hard_links: 1, uid: Uid::new_root(), gid: Gid::new_root(), - rdev: 0, + container_dev_id: DeviceId::none(), // FIXME: placeholder + self_dev_id: None, } } @@ -361,19 +362,19 @@ impl Inode for KInode { } default fn atime(&self) -> Duration { - self.metadata().atime + self.metadata().last_access_at } default fn set_atime(&self, _time: Duration) {} default fn mtime(&self) -> Duration { - self.metadata().mtime + self.metadata().last_modify_at } default fn set_mtime(&self, _time: Duration) {} default fn ctime(&self) -> Duration { - self.metadata().ctime + self.metadata().last_meta_change_at } default fn set_ctime(&self, _time: Duration) {} diff --git a/kernel/src/syscall/mount.rs b/kernel/src/syscall/mount.rs index 67d2aa0b1..6d11936c7 100644 --- a/kernel/src/syscall/mount.rs +++ b/kernel/src/syscall/mount.rs @@ -1,7 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -use device_id::DeviceId; - use super::SyscallReturn; use crate::{ fs::{ @@ -240,7 +238,7 @@ fn get_fs( return_errno_with_message!(Errno::ENODEV, "the path is not a device file"); } - let id = DeviceId::from_encoded_u64(path.metadata().rdev); + let id = path.metadata().self_dev_id; let device = id.and_then(aster_block::lookup); if device.is_none() { return_errno_with_message!(Errno::ENODEV, "the device is not found"); diff --git a/kernel/src/syscall/stat.rs b/kernel/src/syscall/stat.rs index 7e3c7d65d..132c81a83 100644 --- a/kernel/src/syscall/stat.rs +++ b/kernel/src/syscall/stat.rs @@ -175,19 +175,19 @@ struct Stat { impl From for Stat { fn from(info: Metadata) -> Self { Self { - st_dev: info.dev, + st_dev: info.container_dev_id.as_encoded_u64(), st_ino: info.ino, - st_nlink: info.nlinks as _, + st_nlink: info.nr_hard_links as _, st_mode: info.type_ as u32 | info.mode.bits() as u32, st_uid: info.uid.into(), st_gid: info.gid.into(), - st_rdev: info.rdev, + st_rdev: info.self_dev_id.map_or(0, |id| id.as_encoded_u64()), st_size: info.size as i64, - st_blksize: info.blk_size as _, - st_blocks: (info.blocks * (info.blk_size / 512)) as i64, - st_atime: info.atime.into(), - st_mtime: info.mtime.into(), - st_ctime: info.ctime.into(), + st_blksize: info.optimal_block_size as _, + st_blocks: info.nr_sectors_allocated as _, + st_atime: info.last_access_at.into(), + st_mtime: info.last_modify_at.into(), + st_ctime: info.last_meta_change_at.into(), ..Default::default() } } diff --git a/kernel/src/syscall/statx.rs b/kernel/src/syscall/statx.rs index 504e46e5c..4da358256 100644 --- a/kernel/src/syscall/statx.rs +++ b/kernel/src/syscall/statx.rs @@ -128,8 +128,10 @@ impl Statx { fn new(path: &Path) -> Self { let info = path.metadata(); - let (stx_dev_major, stx_dev_minor) = device_id::decode_device_numbers(info.dev); - let (stx_rdev_major, stx_rdev_minor) = device_id::decode_device_numbers(info.rdev); + let (stx_dev_major, stx_dev_minor) = + device_id::decode_device_numbers(info.container_dev_id.as_encoded_u64()); + let (stx_rdev_major, stx_rdev_minor) = + device_id::decode_device_numbers(info.self_dev_id.map_or(0, |id| id.as_encoded_u64())); // TODO: Support more `stx_attributes` flags. let stx_attributes_mask = STATX_ATTR_MOUNT_ROOT; @@ -146,21 +148,21 @@ impl Statx { Self { // FIXME: All zero fields below are dummy implementations that need to be improved in the future. stx_mask, - stx_blksize: info.blk_size as u32, + stx_blksize: info.optimal_block_size as u32, stx_attributes, - stx_nlink: info.nlinks as u32, + stx_nlink: info.nr_hard_links as u32, stx_uid: info.uid.into(), stx_gid: info.gid.into(), stx_mode: info.type_ as u16 | info.mode.bits(), __spare0: [0; 1], stx_ino: info.ino, stx_size: info.size as u64, - stx_blocks: (info.blocks * (info.blk_size / 512)) as u64, + stx_blocks: (info.nr_sectors_allocated * (info.optimal_block_size / 512)) as u64, stx_attributes_mask, - stx_atime: StatxTimestamp::from(info.atime), - stx_btime: StatxTimestamp::from(info.atime), - stx_ctime: StatxTimestamp::from(info.ctime), - stx_mtime: StatxTimestamp::from(info.ctime), + stx_atime: StatxTimestamp::from(info.last_access_at), + stx_btime: StatxTimestamp::from(info.last_access_at), + stx_ctime: StatxTimestamp::from(info.last_meta_change_at), + stx_mtime: StatxTimestamp::from(info.last_meta_change_at), stx_rdev_major, stx_rdev_minor, stx_dev_major, diff --git a/kernel/src/vm/vmar/vm_mapping.rs b/kernel/src/vm/vmar/vm_mapping.rs index e78e24183..bc76e62dc 100644 --- a/kernel/src/vm/vmar/vm_mapping.rs +++ b/kernel/src/vm/vmar/vm_mapping.rs @@ -242,7 +242,9 @@ impl VmMapping { let offset = self.vmo().map(|vmo| vmo.offset).unwrap_or(0); let (dev_major, dev_minor) = self .inode() - .map(|inode| device_id::decode_device_numbers(inode.metadata().dev)) + .map(|inode| { + device_id::decode_device_numbers(inode.metadata().container_dev_id.as_encoded_u64()) + }) .unwrap_or((0, 0)); let ino = self.inode().map(|inode| inode.ino()).unwrap_or(0);