diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index 6543b899..992df850 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -361,6 +361,41 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.100", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.100", +] + [[package]] name = "defer" version = "0.2.1" @@ -399,6 +434,37 @@ dependencies = [ "thiserror", ] +[[package]] +name = "derive_builder" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "derive_builder_macro" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" +dependencies = [ + "derive_builder_core", + "syn 2.0.100", +] + [[package]] name = "derive_more" version = "0.99.19" @@ -435,6 +501,7 @@ dependencies = [ "bitmap", "cfg-if", "defer", + "derive_builder", "driver_base_macros", "elf 0.7.2", "fdt", @@ -546,6 +613,12 @@ name = "fdt" version = "0.2.0-alpha1" source = "git+https://git.mirrors.dragonos.org.cn/DragonOS-Community/fdt?rev=9862813020#98628130200086c2e55dae0d997ac4daeb590e90" +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "foldhash" version = "0.1.5" @@ -668,6 +741,12 @@ dependencies = [ "kdepends", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "indexmap" version = "1.9.3" @@ -1558,6 +1637,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "syn" version = "1.0.109" diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 9d5d967e..0abfb04c 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -79,6 +79,7 @@ static-keys = { version = "=0.7" } defer = "0.2.1" cfg-if = { version = "1.0.0" } +derive_builder = { version = "0.20.2", default-features = false, features = ["alloc"] } # target为x86_64时,使用下面的依赖 diff --git a/kernel/src/debug/tracing/tracepoint.rs b/kernel/src/debug/tracing/tracepoint.rs index fada434b..b9ee0760 100644 --- a/kernel/src/debug/tracing/tracepoint.rs +++ b/kernel/src/debug/tracing/tracepoint.rs @@ -162,7 +162,7 @@ macro_rules! define_event_trace{ #[derive(Debug)] #[repr(C)] #[allow(non_snake_case)] - + #[allow(non_camel_case_types)] struct [<__ $name _TracePointMeta>]{ trace_point: &'static $crate::debug::tracing::tracepoint::TracePoint, print_func: fn(&mut (dyn core::any::Any+Send+Sync),$($arg_type),*), diff --git a/kernel/src/driver/input/ps2_mouse/ps_mouse_device.rs b/kernel/src/driver/input/ps2_mouse/ps_mouse_device.rs index 78633ea9..1790e70b 100644 --- a/kernel/src/driver/input/ps2_mouse/ps_mouse_device.rs +++ b/kernel/src/driver/input/ps2_mouse/ps_mouse_device.rs @@ -31,7 +31,7 @@ use crate::{ devfs::{devfs_register, DevFS, DeviceINode}, kernfs::KernFSInode, vfs::{ - core::generate_inode_id, syscall::ModeType, utils::DName, FilePrivateData, FileSystem, + syscall::ModeType, utils::DName, vcore::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, }, }, @@ -198,6 +198,7 @@ impl Ps2MouseDevice { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type: FileType::CharDevice, // 文件夹,block设备,char设备 mode: ModeType::from_bits_truncate(0o644), nlinks: 1, diff --git a/kernel/src/driver/keyboard/ps2_keyboard.rs b/kernel/src/driver/keyboard/ps2_keyboard.rs index 94564e9f..35a65a65 100644 --- a/kernel/src/driver/keyboard/ps2_keyboard.rs +++ b/kernel/src/driver/keyboard/ps2_keyboard.rs @@ -22,7 +22,7 @@ use crate::{ filesystem::{ devfs::{devfs_register, DevFS, DeviceINode}, vfs::{ - core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, + file::FileMode, syscall::ModeType, vcore::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, }, }, @@ -86,6 +86,7 @@ impl LockedPS2KeyBoardInode { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type: FileType::CharDevice, // 文件夹,block设备,char设备 mode: ModeType::from_bits_truncate(0o666), nlinks: 1, @@ -155,6 +156,7 @@ impl IndexNode for LockedPS2KeyBoardInode { inode.metadata.atime = metadata.atime; inode.metadata.mtime = metadata.mtime; inode.metadata.ctime = metadata.ctime; + inode.metadata.btime = metadata.btime; inode.metadata.mode = metadata.mode; inode.metadata.uid = metadata.uid; inode.metadata.gid = metadata.gid; diff --git a/kernel/src/filesystem/devfs/mod.rs b/kernel/src/filesystem/devfs/mod.rs index 51cafc7d..bc19daf1 100644 --- a/kernel/src/filesystem/devfs/mod.rs +++ b/kernel/src/filesystem/devfs/mod.rs @@ -3,10 +3,10 @@ pub mod null_dev; pub mod zero_dev; use super::vfs::{ - core::{generate_inode_id, ROOT_INODE}, file::FileMode, syscall::ModeType, utils::DName, + vcore::{generate_inode_id, ROOT_INODE}, FilePrivateData, FileSystem, FileType, FsInfo, IndexNode, Magic, Metadata, SuperBlock, }; use crate::{ @@ -284,6 +284,7 @@ impl DevFSInode { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type: dev_type_, // 文件夹 mode, nlinks: 1, @@ -375,6 +376,7 @@ impl LockedDevFSInode { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type, mode, nlinks: 1, @@ -531,6 +533,7 @@ impl IndexNode for LockedDevFSInode { inode.metadata.atime = metadata.atime; inode.metadata.mtime = metadata.mtime; inode.metadata.ctime = metadata.ctime; + inode.metadata.btime = metadata.btime; inode.metadata.mode = metadata.mode; inode.metadata.uid = metadata.uid; inode.metadata.gid = metadata.gid; diff --git a/kernel/src/filesystem/devfs/null_dev.rs b/kernel/src/filesystem/devfs/null_dev.rs index 0b050031..71f45aab 100644 --- a/kernel/src/filesystem/devfs/null_dev.rs +++ b/kernel/src/filesystem/devfs/null_dev.rs @@ -2,7 +2,7 @@ use crate::driver::base::device::device_number::DeviceNumber; use crate::filesystem::vfs::file::FileMode; use crate::filesystem::vfs::syscall::ModeType; use crate::filesystem::vfs::{ - core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, + vcore::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, }; use crate::libs::spinlock::SpinLockGuard; use crate::{libs::spinlock::SpinLock, time::PosixTimeSpec}; @@ -45,6 +45,7 @@ impl LockedNullInode { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type: FileType::CharDevice, // 文件夹,block设备,char设备 mode: ModeType::from_bits_truncate(0o666), nlinks: 1, @@ -101,6 +102,7 @@ impl IndexNode for LockedNullInode { inode.metadata.atime = metadata.atime; inode.metadata.mtime = metadata.mtime; inode.metadata.ctime = metadata.ctime; + inode.metadata.btime = metadata.btime; inode.metadata.mode = metadata.mode; inode.metadata.uid = metadata.uid; inode.metadata.gid = metadata.gid; diff --git a/kernel/src/filesystem/devfs/zero_dev.rs b/kernel/src/filesystem/devfs/zero_dev.rs index 0a74b586..b19af347 100644 --- a/kernel/src/filesystem/devfs/zero_dev.rs +++ b/kernel/src/filesystem/devfs/zero_dev.rs @@ -2,7 +2,7 @@ use crate::driver::base::device::device_number::DeviceNumber; use crate::filesystem::vfs::file::FileMode; use crate::filesystem::vfs::syscall::ModeType; use crate::filesystem::vfs::{ - core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, + vcore::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, }; use crate::libs::spinlock::SpinLockGuard; use crate::{libs::spinlock::SpinLock, time::PosixTimeSpec}; @@ -45,6 +45,7 @@ impl LockedZeroInode { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type: FileType::CharDevice, // 文件夹,block设备,char设备 mode: ModeType::from_bits_truncate(0o666), nlinks: 1, @@ -101,6 +102,7 @@ impl IndexNode for LockedZeroInode { inode.metadata.atime = metadata.atime; inode.metadata.mtime = metadata.mtime; inode.metadata.ctime = metadata.ctime; + inode.metadata.btime = metadata.btime; inode.metadata.mode = metadata.mode; inode.metadata.uid = metadata.uid; inode.metadata.gid = metadata.gid; diff --git a/kernel/src/filesystem/devpts/mod.rs b/kernel/src/filesystem/devpts/mod.rs index dae03024..62e6c387 100644 --- a/kernel/src/filesystem/devpts/mod.rs +++ b/kernel/src/filesystem/devpts/mod.rs @@ -22,14 +22,14 @@ use crate::{ tty_device::{PtyType, TtyDevice, TtyType}, }, }, - filesystem::vfs::{core::do_mount_mkdir, syscall::ModeType, FileType}, + filesystem::vfs::{syscall::ModeType, vcore::do_mount_mkdir, FileType}, init::initcall::INITCALL_FS, libs::spinlock::{SpinLock, SpinLockGuard}, time::PosixTimeSpec, }; use super::vfs::{ - core::generate_inode_id, FilePrivateData, FileSystem, FsInfo, IndexNode, Metadata, + vcore::generate_inode_id, FilePrivateData, FileSystem, FsInfo, IndexNode, Metadata, }; const DEV_PTYFS_MAX_NAMELEN: usize = 16; @@ -109,6 +109,7 @@ impl LockedDevPtsFSInode { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type: FileType::Dir, mode: ModeType::from_bits_truncate(0o777), nlinks: 1, diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index 88712c45..5256949a 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -23,9 +23,9 @@ use crate::mm::VmFaultReason; use crate::{ driver::base::block::{block_device::LBA_SIZE, disk_info::Partition, SeekFrom}, filesystem::vfs::{ - core::generate_inode_id, file::{FileMode, FilePrivateData}, syscall::ModeType, + vcore::generate_inode_id, FileSystem, FileType, IndexNode, InodeId, Metadata, }, libs::{ @@ -227,6 +227,7 @@ impl LockedFATInode { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type, mode: ModeType::from_bits_truncate(0o777), nlinks: 1, @@ -377,6 +378,7 @@ impl FATFileSystem { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type: FileType::Dir, mode: ModeType::from_bits_truncate(0o777), nlinks: 1, diff --git a/kernel/src/filesystem/kernfs/mod.rs b/kernel/src/filesystem/kernfs/mod.rs index 91765e57..867abded 100644 --- a/kernel/src/filesystem/kernfs/mod.rs +++ b/kernel/src/filesystem/kernfs/mod.rs @@ -22,7 +22,7 @@ use crate::{ use self::callback::{KernCallbackData, KernFSCallback, KernInodePrivateData}; use super::vfs::{ - core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, + file::FileMode, syscall::ModeType, vcore::generate_inode_id, FilePrivateData, FileSystem, FileType, FsInfo, IndexNode, InodeId, Magic, Metadata, SuperBlock, }; @@ -94,6 +94,7 @@ impl KernFS { atime: PosixTimeSpec::new(0, 0), mtime: PosixTimeSpec::new(0, 0), ctime: PosixTimeSpec::new(0, 0), + btime: PosixTimeSpec::new(0, 0), dev_id: 0, inode_id: generate_inode_id(), file_type: FileType::Dir, @@ -525,6 +526,7 @@ impl KernFSInode { atime: PosixTimeSpec::new(0, 0), mtime: PosixTimeSpec::new(0, 0), ctime: PosixTimeSpec::new(0, 0), + btime: PosixTimeSpec::new(0, 0), dev_id: 0, inode_id: generate_inode_id(), file_type: file_type.into(), diff --git a/kernel/src/filesystem/procfs/mod.rs b/kernel/src/filesystem/procfs/mod.rs index 07f0d36f..3e7fd479 100644 --- a/kernel/src/filesystem/procfs/mod.rs +++ b/kernel/src/filesystem/procfs/mod.rs @@ -15,7 +15,7 @@ use crate::{ arch::mm::LockedFrameAllocator, driver::base::device::device_number::DeviceNumber, filesystem::vfs::{ - core::{generate_inode_id, ROOT_INODE}, + vcore::{generate_inode_id, ROOT_INODE}, FileType, }, libs::{ @@ -361,6 +361,7 @@ impl ProcFS { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type: FileType::Dir, mode: ModeType::from_bits_truncate(0o555), nlinks: 1, @@ -656,6 +657,7 @@ impl IndexNode for LockedProcFSInode { inode.metadata.atime = metadata.atime; inode.metadata.mtime = metadata.mtime; inode.metadata.ctime = metadata.ctime; + inode.metadata.btime = metadata.btime; inode.metadata.mode = metadata.mode; inode.metadata.uid = metadata.uid; inode.metadata.gid = metadata.gid; @@ -708,6 +710,7 @@ impl IndexNode for LockedProcFSInode { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type, mode, nlinks: 1, diff --git a/kernel/src/filesystem/ramfs/mod.rs b/kernel/src/filesystem/ramfs/mod.rs index 61dddf34..40ae7fe0 100644 --- a/kernel/src/filesystem/ramfs/mod.rs +++ b/kernel/src/filesystem/ramfs/mod.rs @@ -5,7 +5,7 @@ use crate::filesystem::vfs::{FileSystemMakerData, FSMAKER}; use crate::libs::rwlock::RwLock; use crate::{ driver::base::device::device_number::DeviceNumber, - filesystem::vfs::{core::generate_inode_id, FileType}, + filesystem::vfs::{vcore::generate_inode_id, FileType}, ipc::pipe::LockedPipeInode, libs::casting::DowncastArc, libs::spinlock::{SpinLock, SpinLockGuard}, @@ -86,6 +86,7 @@ impl RamFSInode { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type: FileType::Dir, mode: ModeType::from_bits_truncate(0o777), nlinks: 1, @@ -281,6 +282,7 @@ impl IndexNode for LockedRamFSInode { inode.metadata.atime = metadata.atime; inode.metadata.mtime = metadata.mtime; inode.metadata.ctime = metadata.ctime; + inode.metadata.btime = metadata.btime; inode.metadata.mode = metadata.mode; inode.metadata.uid = metadata.uid; inode.metadata.gid = metadata.gid; @@ -332,6 +334,7 @@ impl IndexNode for LockedRamFSInode { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type, mode, nlinks: 1, @@ -594,6 +597,7 @@ impl IndexNode for LockedRamFSInode { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type: FileType::Pipe, mode, nlinks: 1, diff --git a/kernel/src/filesystem/vfs/fcntl.rs b/kernel/src/filesystem/vfs/fcntl.rs index 0c7b42d5..5d4985df 100644 --- a/kernel/src/filesystem/vfs/fcntl.rs +++ b/kernel/src/filesystem/vfs/fcntl.rs @@ -101,6 +101,8 @@ bitflags! { /// 应用于整个子树。 /// AT_RECURSIVE: 0x8000 const AT_RECURSIVE = 0x8000; + + const AT_GETATTR_NOSEC = i32::MIN; } } diff --git a/kernel/src/filesystem/vfs/mod.rs b/kernel/src/filesystem/vfs/mod.rs index 8c77a87f..875f3d28 100644 --- a/kernel/src/filesystem/vfs/mod.rs +++ b/kernel/src/filesystem/vfs/mod.rs @@ -1,13 +1,15 @@ -pub mod core; pub mod fcntl; pub mod file; pub mod mount; pub mod open; +pub mod stat; pub mod syscall; pub mod utils; +pub mod vcore; use ::core::{any::Any, fmt::Debug, sync::atomic::AtomicUsize}; use alloc::{string::String, sync::Arc, vec::Vec}; +use derive_builder::Builder; use intertrait::CastFromSync; use system_error::SystemError; @@ -25,8 +27,8 @@ use crate::{ time::PosixTimeSpec, }; -use self::{core::generate_inode_id, file::FileMode, syscall::ModeType, utils::DName}; -pub use self::{core::ROOT_INODE, file::FilePrivateData, mount::MountFS}; +use self::{file::FileMode, syscall::ModeType, utils::DName, vcore::generate_inode_id}; +pub use self::{file::FilePrivateData, mount::MountFS, vcore::ROOT_INODE}; use super::page_cache::PageCache; @@ -59,6 +61,22 @@ pub enum FileType { Socket, } +impl From for ModeType { + fn from(val: FileType) -> Self { + match val { + FileType::File => ModeType::S_IFREG, + FileType::Dir => ModeType::S_IFDIR, + FileType::BlockDevice => ModeType::S_IFBLK, + FileType::CharDevice => ModeType::S_IFCHR, + FileType::SymLink => ModeType::S_IFLNK, + FileType::Socket => ModeType::S_IFSOCK, + FileType::Pipe => ModeType::S_IFIFO, + FileType::KvmDevice => ModeType::S_IFCHR, + FileType::FramebufferDevice => ModeType::S_IFCHR, + } + } +} + #[allow(dead_code)] #[derive(Debug, Clone)] pub enum SpecialNodeData { @@ -781,7 +799,8 @@ impl dyn IndexNode { /// IndexNode的元数据 /// /// 对应Posix2008中的sys/stat.h中的定义 https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_stat.h.html -#[derive(Debug, PartialEq, Eq, Clone)] +#[derive(Debug, PartialEq, Eq, Clone, Builder)] +#[builder(no_std, setter(into))] pub struct Metadata { /// 当前inode所在的文件系统的设备号 pub dev_id: usize, @@ -803,12 +822,15 @@ pub struct Metadata { /// inode最后一次被访问的时间 pub atime: PosixTimeSpec, - /// inode最后一次修改的时间 + /// inode的文件数据最后一次修改的时间 pub mtime: PosixTimeSpec, - /// inode的创建时间 + /// inode的元数据、权限或文件内容最后一次发生改变的时间 pub ctime: PosixTimeSpec, + /// inode的创建时间 + pub btime: PosixTimeSpec, + /// 文件类型 pub file_type: FileType, @@ -839,6 +861,7 @@ impl Default for Metadata { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type: FileType::File, mode: ModeType::empty(), nlinks: 1, @@ -975,6 +998,7 @@ impl Metadata { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type, mode, nlinks: 1, diff --git a/kernel/src/filesystem/vfs/mount.rs b/kernel/src/filesystem/vfs/mount.rs index ed6ace17..732153b9 100644 --- a/kernel/src/filesystem/vfs/mount.rs +++ b/kernel/src/filesystem/vfs/mount.rs @@ -749,3 +749,18 @@ impl Debug for MountList { f.debug_map().entries(MOUNT_LIST().0.read().iter()).finish() } } + +/// 判断给定的inode是否为其所在文件系统的根inode +/// +/// ## 返回值 +/// +/// - `true`: 是根inode +/// - `false`: 不是根inode或者传入的inode不是MountFSInode类型,或者调用inode的metadata方法时报错了。 +pub fn is_mountpoint_root(inode: &Arc) -> bool { + let mnt_inode = inode.as_any_ref().downcast_ref::(); + if let Some(mnt) = mnt_inode { + return mnt.is_mountpoint_root().unwrap_or(false); + } + + return false; +} diff --git a/kernel/src/filesystem/vfs/stat.rs b/kernel/src/filesystem/vfs/stat.rs new file mode 100644 index 00000000..1adb68d7 --- /dev/null +++ b/kernel/src/filesystem/vfs/stat.rs @@ -0,0 +1,398 @@ +use system_error::SystemError; + +use crate::{ + filesystem::vfs::{mount::is_mountpoint_root, vcore::do_file_lookup_at}, + syscall::user_access::UserBufferWriter, + time::PosixTimeSpec, +}; +use alloc::sync::Arc; + +use super::{ + fcntl::AtFlags, + syscall::{ModeType, PosixStatx, PosixStatxMask, StxAttributes}, + IndexNode, +}; + +#[derive(Clone)] +pub struct KStat { + pub result_mask: PosixStatxMask, // What fields the user got + pub mode: ModeType, // umode_t + pub nlink: u32, + pub blksize: u32, // Preferred I/O size + pub attributes: StxAttributes, + pub attributes_mask: StxAttributes, + pub ino: u64, + pub dev: i64, // dev_t + pub rdev: i64, // dev_t + pub uid: u32, // kuid_t + pub gid: u32, // kgid_t + pub size: usize, // loff_t + pub atime: PosixTimeSpec, // struct timespec64 + pub mtime: PosixTimeSpec, // struct timespec64 + pub ctime: PosixTimeSpec, // struct timespec64 + pub btime: PosixTimeSpec, // File creation time + pub blocks: u64, + pub mnt_id: u64, + pub dio_mem_align: u32, + pub dio_offset_align: u32, +} + +impl Default for KStat { + fn default() -> Self { + Self { + result_mask: PosixStatxMask::empty(), + mode: ModeType::empty(), + nlink: Default::default(), + blksize: Default::default(), + attributes: StxAttributes::empty(), + attributes_mask: StxAttributes::empty(), + ino: Default::default(), + dev: Default::default(), + rdev: Default::default(), + uid: Default::default(), + gid: Default::default(), + size: Default::default(), + atime: Default::default(), + mtime: Default::default(), + ctime: Default::default(), + btime: Default::default(), + blocks: Default::default(), + mnt_id: Default::default(), + dio_mem_align: Default::default(), + dio_offset_align: Default::default(), + } + } +} + +bitflags! { + /// https://code.dragonos.org.cn/xref/linux-6.6.21/include/linux/namei.h?fi=LOOKUP_FOLLOW#21 + pub struct LookUpFlags: u32 { + /// follow links at the end + const FOLLOW = 0x0001; + /// require a directory + const DIRECTORY = 0x0002; + /// force terminal automount + const AUTOMOUNT = 0x0004; + /// accept empty path [user_... only] + const EMPTY = 0x4000; + /// follow mounts in the starting point + const DOWN = 0x8000; + /// follow mounts in the end + const MOUNTPOINT = 0x0080; + /// tell ->d_revalidate() to trust no cache + const REVAL = 0x0020; + /// RCU pathwalk mode; semi-internal + const RCU = 0x0040; + /// ... in open + const OPEN = 0x0100; + /// ... in object creation + const CREATE = 0x0200; + /// ... in exclusive creation + const EXCL = 0x0400; + /// ... in destination of rename() + const RENAME_TARGET = 0x0800; + /// internal use only + const PARENT = 0x0010; + /// No symlink crossing + const NO_SYMLINKS = 0x010000; + /// No nd_jump_link() crossing + const NO_MAGICLINKS = 0x020000; + /// No mountpoint crossing + const NO_XDEV = 0x040000; + /// No escaping from starting point + const BENEATH = 0x080000; + /// Treat dirfd as fs root + const IN_ROOT = 0x100000; + /// Only do cached lookup + const CACHED = 0x200000; + /// LOOKUP_* flags which do scope-related checks based on the dirfd. + const IS_SCOPED = LookUpFlags::BENEATH.bits | LookUpFlags::IN_ROOT.bits; + } +} + +impl From for LookUpFlags { + fn from(value: AtFlags) -> Self { + let mut lookup_flags = LookUpFlags::empty(); + + if !value.contains(AtFlags::AT_SYMLINK_NOFOLLOW) { + lookup_flags |= LookUpFlags::FOLLOW; + } + + if !value.contains(AtFlags::AT_NO_AUTOMOUNT) { + lookup_flags |= LookUpFlags::AUTOMOUNT; + } + + if value.contains(AtFlags::AT_EMPTY_PATH) { + lookup_flags |= LookUpFlags::EMPTY; + } + + lookup_flags + } +} + +/// https://code.dragonos.org.cn/xref/linux-6.6.21/fs/stat.c#232 +#[inline(never)] +pub fn vfs_statx( + dfd: i32, + filename: &str, + flags: AtFlags, + request_mask: PosixStatxMask, +) -> Result { + let lookup_flags: LookUpFlags = flags.into(); + + // Validate flags - only allowed flags are AT_SYMLINK_NOFOLLOW, AT_NO_AUTOMOUNT, AT_EMPTY_PATH, AT_STATX_SYNC_TYPE + if flags.intersects( + !(AtFlags::AT_SYMLINK_NOFOLLOW + | AtFlags::AT_NO_AUTOMOUNT + | AtFlags::AT_EMPTY_PATH + | AtFlags::AT_STATX_SYNC_TYPE), + ) { + return Err(SystemError::EINVAL); + } + let inode = do_file_lookup_at(dfd, filename, lookup_flags)?; + + let mut kstat = vfs_getattr(&inode, request_mask, flags)?; + if is_mountpoint_root(&inode) { + kstat + .attributes + .insert(StxAttributes::STATX_ATTR_MOUNT_ROOT); + } + kstat + .attributes_mask + .insert(StxAttributes::STATX_ATTR_MOUNT_ROOT); + + // todo: 添加 https://code.dragonos.org.cn/xref/linux-6.6.21/fs/stat.c#266 这里的逻辑 + + Ok(kstat) +} + +/// 获取文件的增强基本属性 +/// +/// # 参数 +/// - `path`: 目标文件路径 +/// - `stat`: 用于返回统计信息的结构体 +/// - `request_mask`: PosixStatxMask标志位,指示调用者需要哪些属性 +/// - `query_flags`: 查询模式(AT_STATX_SYNC_TYPE) +/// +/// # 描述 +/// 向文件系统请求文件的属性。调用者必须通过request_mask和query_flags指定需要的信息。 +/// +/// 如果文件是远程的: +/// - 可以通过传递AT_STATX_FORCE_SYNC强制文件系统从后端存储更新属性 +/// - 可以通过传递AT_STATX_DONT_SYNC禁止更新 +/// +/// request_mask中必须设置相应的位来指示调用者需要检索哪些属性。 +/// 未请求的属性也可能被返回,但其值可能是近似的,如果是远程文件, +/// 可能没有与服务器同步。 +/// +/// # 返回值 +/// 成功时返回0,失败时返回负的错误码 +/// +/// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/fs/stat.c#165 +#[inline(never)] +pub fn vfs_getattr( + inode: &Arc, + request_mask: PosixStatxMask, + mut at_flags: AtFlags, +) -> Result { + if at_flags.contains(AtFlags::AT_GETATTR_NOSEC) { + return Err(SystemError::EPERM); + } + + let mut kstat = KStat::default(); + kstat.result_mask |= PosixStatxMask::STATX_BASIC_STATS; + at_flags &= AtFlags::AT_STATX_SYNC_TYPE; + + let metadata = inode.metadata()?; + if metadata.atime.is_empty() { + kstat.result_mask.remove(PosixStatxMask::STATX_ATIME); + } + + // todo: 添加automount和dax属性 + + kstat.blksize = metadata.blk_size as u32; + if request_mask.contains(PosixStatxMask::STATX_MODE) + || request_mask.contains(PosixStatxMask::STATX_TYPE) + { + kstat.mode = metadata.mode; + } + if request_mask.contains(PosixStatxMask::STATX_NLINK) { + kstat.nlink = metadata.nlinks as u32; + } + if request_mask.contains(PosixStatxMask::STATX_UID) { + kstat.uid = metadata.uid as u32; + } + if request_mask.contains(PosixStatxMask::STATX_GID) { + kstat.gid = metadata.gid as u32; + } + if request_mask.contains(PosixStatxMask::STATX_ATIME) { + kstat.atime.tv_sec = metadata.atime.tv_sec; + kstat.atime.tv_nsec = metadata.atime.tv_nsec; + } + if request_mask.contains(PosixStatxMask::STATX_MTIME) { + kstat.mtime.tv_sec = metadata.mtime.tv_sec; + kstat.mtime.tv_nsec = metadata.mtime.tv_nsec; + } + if request_mask.contains(PosixStatxMask::STATX_CTIME) { + // ctime是文件上次修改状态的时间 + kstat.ctime.tv_sec = metadata.ctime.tv_sec; + kstat.ctime.tv_nsec = metadata.ctime.tv_nsec; + } + if request_mask.contains(PosixStatxMask::STATX_INO) { + kstat.ino = metadata.inode_id.into() as u64; + } + if request_mask.contains(PosixStatxMask::STATX_SIZE) { + kstat.size = metadata.size as usize; + } + if request_mask.contains(PosixStatxMask::STATX_BLOCKS) { + kstat.blocks = metadata.blocks as u64; + } + + if request_mask.contains(PosixStatxMask::STATX_BTIME) { + // btime是文件创建时间 + kstat.btime.tv_sec = metadata.btime.tv_sec; + kstat.btime.tv_nsec = metadata.btime.tv_nsec; + } + if request_mask.contains(PosixStatxMask::STATX_ALL) { + kstat.attributes = StxAttributes::STATX_ATTR_APPEND; + kstat.attributes_mask |= + StxAttributes::STATX_ATTR_AUTOMOUNT | StxAttributes::STATX_ATTR_DAX; + kstat.dev = metadata.dev_id as i64; + kstat.rdev = metadata.raw_dev.data() as i64; + } + + // 把文件类型加入mode里面 (todo: 在具体的文件系统里面去实现这个操作。这里只是权宜之计) + kstat.mode |= metadata.file_type.into(); + + return Ok(kstat); +} + +/// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/fs/stat.c#660 +pub(super) fn do_statx( + dfd: i32, + filename: &str, + flags: u32, + mask: u32, + user_kstat_ptr: usize, +) -> Result<(), SystemError> { + let mask = PosixStatxMask::from_bits_truncate(mask); + if mask.contains(PosixStatxMask::STATX_RESERVED) { + return Err(SystemError::EINVAL); + } + + let flags = AtFlags::from_bits_truncate(flags as i32); + if flags.contains(AtFlags::AT_STATX_SYNC_TYPE) { + return Err(SystemError::EINVAL); + } + + let kstat = vfs_statx(dfd, filename, flags, mask)?; + cp_statx(kstat, user_kstat_ptr) +} + +/// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/fs/stat.c#622 +#[inline(never)] +fn cp_statx(kstat: KStat, user_buf_ptr: usize) -> Result<(), SystemError> { + let mut userbuf = UserBufferWriter::new( + user_buf_ptr as *mut PosixStatx, + size_of::(), + true, + )?; + let mut statx: PosixStatx = PosixStatx::new(); + + // Copy fields from KStat to PosixStatx + statx.stx_mask = kstat.result_mask & !PosixStatxMask::STATX_CHANGE_COOKIE; + statx.stx_blksize = kstat.blksize; + statx.stx_attributes = kstat.attributes & !StxAttributes::STATX_ATTR_CHANGE_MONOTONIC; + statx.stx_nlink = kstat.nlink; + statx.stx_uid = kstat.uid; + statx.stx_gid = kstat.gid; + statx.stx_mode = kstat.mode; + statx.stx_inode = kstat.ino; + statx.stx_size = kstat.size as i64; + statx.stx_blocks = kstat.blocks; + statx.stx_attributes_mask = kstat.attributes_mask; + + // Copy time fields + statx.stx_atime = kstat.atime; + statx.stx_btime = kstat.btime; + statx.stx_ctime = kstat.ctime; + statx.stx_mtime = kstat.mtime; + + // Convert device numbers + statx.stx_rdev_major = ((kstat.rdev >> 32) & 0xffff_ffff) as u32; // MAJOR equivalent + statx.stx_rdev_minor = (kstat.rdev & 0xffff_ffff) as u32; // MINOR equivalent + statx.stx_dev_major = ((kstat.dev >> 32) & 0xffff_ffff) as u32; // MAJOR equivalent + statx.stx_dev_minor = (kstat.dev & 0xffff_ffff) as u32; // MINOR equivalent + + statx.stx_mnt_id = kstat.mnt_id; + statx.stx_dio_mem_align = kstat.dio_mem_align; + statx.stx_dio_offset_align = kstat.dio_offset_align; + + // Write to user space + userbuf.copy_one_to_user(&statx, 0)?; + Ok(()) +} + +// 注意!这个结构体定义的貌似不太对,需要修改! +#[repr(C)] +#[derive(Clone, Copy)] +/// # 文件信息结构体 +pub struct PosixKstat { + /// 硬件设备ID + pub dev_id: u64, + /// inode号 + pub inode: u64, + /// 硬链接数 + pub nlink: u64, + /// 文件权限 + pub mode: ModeType, + /// 所有者用户ID + pub uid: i32, + /// 所有者组ID + pub gid: i32, + /// 设备ID + pub rdev: i64, + /// 文件大小 + pub size: i64, + /// 文件系统块大小 + pub blcok_size: i64, + /// 分配的512B块数 + pub blocks: u64, + /// 最后访问时间 + pub atime: PosixTimeSpec, + /// 最后修改时间 + pub mtime: PosixTimeSpec, + /// 最后状态变化时间 + pub ctime: PosixTimeSpec, + /// 用于填充结构体大小的空白数据 + pub _pad: [i8; 24], +} +impl PosixKstat { + pub(super) fn new() -> Self { + Self { + inode: 0, + dev_id: 0, + mode: ModeType::empty(), + nlink: 0, + uid: 0, + gid: 0, + rdev: 0, + size: 0, + atime: PosixTimeSpec { + tv_sec: 0, + tv_nsec: 0, + }, + mtime: PosixTimeSpec { + tv_sec: 0, + tv_nsec: 0, + }, + ctime: PosixTimeSpec { + tv_sec: 0, + tv_nsec: 0, + }, + blcok_size: 0, + blocks: 0, + _pad: Default::default(), + } + } +} diff --git a/kernel/src/filesystem/vfs/syscall.rs b/kernel/src/filesystem/vfs/syscall.rs index f9ca9528..d7ad96e3 100644 --- a/kernel/src/filesystem/vfs/syscall.rs +++ b/kernel/src/filesystem/vfs/syscall.rs @@ -10,7 +10,7 @@ use crate::producefs; use crate::syscall::user_access::UserBufferReader; use crate::{ driver::base::{block::SeekFrom, device::device_number::DeviceNumber}, - filesystem::vfs::{core as Vcore, file::FileDescriptorVec}, + filesystem::vfs::{file::FileDescriptorVec, vcore as Vcore}, libs::rwlock::RwLockWriteGuard, mm::{verify_area, VirtAddr}, process::ProcessManager, @@ -21,15 +21,16 @@ use crate::{ time::{syscall::PosixTimeval, PosixTimeSpec}, }; -use super::core::do_symlinkat; +use super::stat::{do_statx, PosixKstat}; +use super::vcore::do_symlinkat; use super::{ - core::{do_mkdir_at, do_remove_dir, do_unlink_at}, fcntl::{AtFlags, FcntlCommand, FD_CLOEXEC}, file::{File, FileMode}, open::{ do_faccessat, do_fchmodat, do_fchownat, do_sys_open, do_utimensat, do_utimes, ksys_fchown, }, utils::{rsplit_path, user_path_at}, + vcore::{do_mkdir_at, do_remove_dir, do_unlink_at}, Dirent, FileType, IndexNode, SuperBlock, FSMAKER, MAX_PATHLEN, ROOT_INODE, VFS_MAX_FOLLOW_SYMLINK_TIMES, }; @@ -88,126 +89,65 @@ bitflags! { } } -#[repr(C)] -#[derive(Clone, Copy)] -/// # 文件信息结构体 -pub struct PosixKstat { - /// 硬件设备ID - dev_id: u64, - /// inode号 - inode: u64, - /// 硬链接数 - nlink: u64, - /// 文件权限 - mode: ModeType, - /// 所有者用户ID - uid: i32, - /// 所有者组ID - gid: i32, - /// 设备ID - rdev: i64, - /// 文件大小 - size: i64, - /// 文件系统块大小 - blcok_size: i64, - /// 分配的512B块数 - blocks: u64, - /// 最后访问时间 - atime: PosixTimeSpec, - /// 最后修改时间 - mtime: PosixTimeSpec, - /// 最后状态变化时间 - ctime: PosixTimeSpec, - /// 用于填充结构体大小的空白数据 - pub _pad: [i8; 24], -} -impl PosixKstat { - fn new() -> Self { - Self { - inode: 0, - dev_id: 0, - mode: ModeType { bits: 0 }, - nlink: 0, - uid: 0, - gid: 0, - rdev: 0, - size: 0, - atime: PosixTimeSpec { - tv_sec: 0, - tv_nsec: 0, - }, - mtime: PosixTimeSpec { - tv_sec: 0, - tv_nsec: 0, - }, - ctime: PosixTimeSpec { - tv_sec: 0, - tv_nsec: 0, - }, - blcok_size: 0, - blocks: 0, - _pad: Default::default(), - } - } -} - #[repr(C)] #[derive(Clone, Copy)] /// # 文件信息结构体X pub struct PosixStatx { /* 0x00 */ - stx_mask: PosixStatxMask, + pub stx_mask: PosixStatxMask, /// 文件系统块大小 - stx_blksize: u32, + pub stx_blksize: u32, /// Flags conveying information about the file [uncond] - stx_attributes: StxAttributes, + pub stx_attributes: StxAttributes, /* 0x10 */ /// 硬链接数 - stx_nlink: u32, + pub stx_nlink: u32, /// 所有者用户ID - stx_uid: u32, + pub stx_uid: u32, /// 所有者组ID - stx_gid: u32, + pub stx_gid: u32, /// 文件权限 - stx_mode: ModeType, + pub stx_mode: ModeType, /* 0x20 */ /// inode号 - stx_inode: u64, + pub stx_inode: u64, /// 文件大小 - stx_size: i64, + pub stx_size: i64, /// 分配的512B块数 - stx_blocks: u64, + pub stx_blocks: u64, /// Mask to show what's supported in stx_attributes - stx_attributes_mask: StxAttributes, + pub stx_attributes_mask: StxAttributes, /* 0x40 */ /// 最后访问时间 - stx_atime: PosixTimeSpec, + pub stx_atime: PosixTimeSpec, /// 文件创建时间 - stx_btime: PosixTimeSpec, + pub stx_btime: PosixTimeSpec, /// 最后状态变化时间 - stx_ctime: PosixTimeSpec, + pub stx_ctime: PosixTimeSpec, /// 最后修改时间 - stx_mtime: PosixTimeSpec, + pub stx_mtime: PosixTimeSpec, /* 0x80 */ /// 主设备ID - stx_rdev_major: u32, + pub stx_rdev_major: u32, /// 次设备ID - stx_rdev_minor: u32, + pub stx_rdev_minor: u32, /// 主硬件设备ID - stx_dev_major: u32, + pub stx_dev_major: u32, /// 次硬件设备ID - stx_dev_minor: u32, + pub stx_dev_minor: u32, /* 0x90 */ - stx_mnt_id: u64, - stx_dio_mem_align: u32, - stx_dio_offset_align: u32, + pub stx_mnt_id: u64, + pub stx_dio_mem_align: u32, + pub stx_dio_offset_align: u32, } + impl PosixStatx { - fn new() -> Self { + #[inline(never)] + pub(super) fn new() -> Self { Self { stx_mask: PosixStatxMask::STATX_BASIC_STATS, stx_blksize: 0, @@ -301,6 +241,9 @@ bitflags! { /// Reserved for future struct statx expansion const STATX_RESERVED = 0x80000000; + + /// Want/got stx_change_attr + const STATX_CHANGE_COOKIE = 0x40000000; } } @@ -324,6 +267,8 @@ bitflags! { const STATX_ATTR_VERITY = 0x00100000; /// 文件当前处于 DAX 状态 CPU直接访问 const STATX_ATTR_DAX = 0x00200000; + /// version monotonically increases + const STATX_ATTR_CHANGE_MONOTONIC = 0x8000000000000000; } } @@ -1411,112 +1356,22 @@ impl Syscall { return Ok(0); } - pub fn do_statx( - fd: i32, - path: *const u8, + #[inline(never)] + pub fn statx( + dfd: i32, + filename_ptr: usize, flags: u32, mask: u32, - usr_kstat: *mut PosixStatx, + user_kstat_ptr: usize, ) -> Result { - if usr_kstat.is_null() { + if user_kstat_ptr == 0 { return Err(SystemError::EFAULT); } - let mask = PosixStatxMask::from_bits_truncate(mask); + let filename = check_and_clone_cstr(filename_ptr as *const u8, Some(MAX_PATHLEN))?; + let filename_str = filename.to_str().map_err(|_| SystemError::EINVAL)?; - if mask.contains(PosixStatxMask::STATX_RESERVED) { - return Err(SystemError::ENAVAIL); - } - - let flags = FileMode::from_bits_truncate(flags); - let ofd = Self::open(path, flags.bits(), ModeType::empty().bits, true)?; - - let binding = ProcessManager::current_pcb().fd_table(); - let fd_table_guard = binding.read(); - let file = fd_table_guard - .get_file_by_fd(ofd as i32) - .ok_or(SystemError::EBADF)?; - // drop guard 以避免无法调度的问题 - drop(fd_table_guard); - let mut writer = UserBufferWriter::new(usr_kstat, size_of::(), true)?; - let mut tmp: PosixStatx = PosixStatx::new(); - // 获取文件信息 - let metadata = file.metadata()?; - - tmp.stx_mask |= PosixStatxMask::STATX_BASIC_STATS; - tmp.stx_blksize = metadata.blk_size as u32; - if mask.contains(PosixStatxMask::STATX_MODE) || mask.contains(PosixStatxMask::STATX_TYPE) { - tmp.stx_mode = metadata.mode; - } - if mask.contains(PosixStatxMask::STATX_NLINK) { - tmp.stx_nlink = metadata.nlinks as u32; - } - if mask.contains(PosixStatxMask::STATX_UID) { - tmp.stx_uid = metadata.uid as u32; - } - if mask.contains(PosixStatxMask::STATX_GID) { - tmp.stx_gid = metadata.gid as u32; - } - if mask.contains(PosixStatxMask::STATX_ATIME) { - tmp.stx_atime.tv_sec = metadata.atime.tv_sec; - tmp.stx_atime.tv_nsec = metadata.atime.tv_nsec; - } - if mask.contains(PosixStatxMask::STATX_MTIME) { - tmp.stx_mtime.tv_sec = metadata.ctime.tv_sec; - tmp.stx_mtime.tv_nsec = metadata.ctime.tv_nsec; - } - if mask.contains(PosixStatxMask::STATX_CTIME) { - // ctime是文件上次修改状态的时间 - tmp.stx_ctime.tv_sec = metadata.mtime.tv_sec; - tmp.stx_ctime.tv_nsec = metadata.mtime.tv_nsec; - } - if mask.contains(PosixStatxMask::STATX_INO) { - tmp.stx_inode = metadata.inode_id.into() as u64; - } - if mask.contains(PosixStatxMask::STATX_SIZE) { - tmp.stx_size = metadata.size; - } - if mask.contains(PosixStatxMask::STATX_BLOCKS) { - tmp.stx_blocks = metadata.blocks as u64; - } - - if mask.contains(PosixStatxMask::STATX_BTIME) { - // btime是文件创建时间 - tmp.stx_btime.tv_sec = metadata.ctime.tv_sec; - tmp.stx_btime.tv_nsec = metadata.ctime.tv_nsec; - } - if mask.contains(PosixStatxMask::STATX_ALL) { - tmp.stx_attributes = StxAttributes::STATX_ATTR_APPEND; - tmp.stx_attributes_mask |= - StxAttributes::STATX_ATTR_AUTOMOUNT | StxAttributes::STATX_ATTR_DAX; - tmp.stx_dev_major = metadata.dev_id as u32; - tmp.stx_dev_minor = metadata.dev_id as u32; // - tmp.stx_rdev_major = metadata.raw_dev.data(); - tmp.stx_rdev_minor = metadata.raw_dev.data(); - } - if mask.contains(PosixStatxMask::STATX_MNT_ID) { - tmp.stx_mnt_id = 0; - } - if mask.contains(PosixStatxMask::STATX_DIOALIGN) { - tmp.stx_dio_mem_align = 0; - tmp.stx_dio_offset_align = 0; - } - - match file.file_type() { - FileType::File => tmp.stx_mode.insert(ModeType::S_IFREG), - FileType::Dir => tmp.stx_mode.insert(ModeType::S_IFDIR), - FileType::BlockDevice => tmp.stx_mode.insert(ModeType::S_IFBLK), - FileType::CharDevice => tmp.stx_mode.insert(ModeType::S_IFCHR), - FileType::SymLink => tmp.stx_mode.insert(ModeType::S_IFLNK), - FileType::Socket => tmp.stx_mode.insert(ModeType::S_IFSOCK), - FileType::Pipe => tmp.stx_mode.insert(ModeType::S_IFIFO), - FileType::KvmDevice => tmp.stx_mode.insert(ModeType::S_IFCHR), - FileType::FramebufferDevice => tmp.stx_mode.insert(ModeType::S_IFCHR), - } - - writer.copy_one_to_user(&tmp, 0)?; - Self::close(fd as usize).ok(); - return Ok(0); + do_statx(dfd, filename_str, flags, mask, user_kstat_ptr).map(|_| 0) } pub fn mknod( diff --git a/kernel/src/filesystem/vfs/core.rs b/kernel/src/filesystem/vfs/vcore.rs similarity index 97% rename from kernel/src/filesystem/vfs/core.rs rename to kernel/src/filesystem/vfs/vcore.rs index 2642adf8..cc422bae 100644 --- a/kernel/src/filesystem/vfs/core.rs +++ b/kernel/src/filesystem/vfs/vcore.rs @@ -26,6 +26,7 @@ use super::{ fcntl::AtFlags, file::FileMode, mount::{init_mountlist, MOUNT_LIST}, + stat::LookUpFlags, syscall::UmountFlag, utils::{rsplit_path, user_path_at}, FilePrivateData, IndexNode, InodeId, VFS_MAX_FOLLOW_SYMLINK_TIMES, @@ -396,3 +397,13 @@ pub fn do_umount2( }; return do_umount(); } + +pub(super) fn do_file_lookup_at( + dfd: i32, + path: &str, + lookup_flags: LookUpFlags, +) -> Result, SystemError> { + let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dfd, path)?; + let follow_final = lookup_flags.contains(LookUpFlags::FOLLOW); + return inode.lookup_follow_symlink2(&path, VFS_MAX_FOLLOW_SYMLINK_TIMES, follow_final); +} diff --git a/kernel/src/init/init.rs b/kernel/src/init/init.rs index ec826be6..43ecdd79 100644 --- a/kernel/src/init/init.rs +++ b/kernel/src/init/init.rs @@ -9,7 +9,7 @@ use crate::{ video::VideoRefreshManager, }, exception::{init::irq_init, softirq::softirq_init, InterruptArch}, - filesystem::vfs::core::vfs_init, + filesystem::vfs::vcore::vfs_init, init::init_intertrait, libs::{ futex::futex::Futex, diff --git a/kernel/src/init/initial_kthread.rs b/kernel/src/init/initial_kthread.rs index 64538258..cc3393c2 100644 --- a/kernel/src/init/initial_kthread.rs +++ b/kernel/src/init/initial_kthread.rs @@ -9,7 +9,7 @@ use system_error::SystemError; use crate::{ arch::{interrupt::TrapFrame, process::arch_switch_to_user}, driver::net::e1000e::e1000e::e1000e_init, - filesystem::vfs::core::mount_root_fs, + filesystem::vfs::vcore::mount_root_fs, namespaces::NsProxy, net::net_core::net_init, process::{ diff --git a/kernel/src/ipc/pipe.rs b/kernel/src/ipc/pipe.rs index 4f69801c..2d0ea6c2 100644 --- a/kernel/src/ipc/pipe.rs +++ b/kernel/src/ipc/pipe.rs @@ -3,7 +3,7 @@ use core::sync::atomic::compiler_fence; use crate::{ arch::ipc::signal::{SigCode, Signal}, filesystem::vfs::{ - core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, + file::FileMode, syscall::ModeType, vcore::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollableInode, }, libs::{ @@ -128,6 +128,7 @@ impl LockedPipeInode { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type: FileType::Pipe, mode: ModeType::from_bits_truncate(0o666), nlinks: 1, diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 79c349c0..9f1f39a8 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -5,7 +5,7 @@ use core::{ use crate::{ arch::{ipc::signal::SigSet, syscall::nr::*}, - filesystem::vfs::syscall::{PosixStatfs, PosixStatx}, + filesystem::vfs::syscall::PosixStatfs, ipc::shm::{ShmCtlCmd, ShmFlags, ShmId, ShmKey}, libs::{futex::constant::FutexFlag, rand::GRandFlags}, mm::{page::PAGE_4K_SIZE, syscall::MremapFlags}, @@ -29,7 +29,8 @@ use crate::{ filesystem::vfs::{ fcntl::{AtFlags, FcntlCommand}, file::FileMode, - syscall::{ModeType, PosixKstat, UtimensFlags}, + stat::PosixKstat, + syscall::{ModeType, UtimensFlags}, MAX_PATHLEN, }, libs::align::page_align_up, @@ -811,15 +812,13 @@ impl Syscall { Self::fstatfs(fd, statfs) } - SYS_STATX => { - let fd = args[0] as i32; - let path = args[1] as *const u8; - let flags = args[2] as u32; - let mask = args[3] as u32; - let kstat = args[4] as *mut PosixStatx; - - Self::do_statx(fd, path, flags, mask, kstat) - } + SYS_STATX => Self::statx( + args[0] as i32, + args[1], + args[2] as u32, + args[3] as u32, + args[4], + ), #[cfg(target_arch = "x86_64")] SYS_EPOLL_CREATE => Self::epoll_create(args[0] as i32), diff --git a/kernel/src/time/mod.rs b/kernel/src/time/mod.rs index 004d6283..30c0d0a0 100644 --- a/kernel/src/time/mod.rs +++ b/kernel/src/time/mod.rs @@ -65,6 +65,10 @@ impl PosixTimeSpec { }; } + pub fn is_empty(&self) -> bool { + self.tv_nsec == 0 && self.tv_sec == 0 + } + /// 获取当前时间 #[inline(always)] pub fn now() -> Self { diff --git a/kernel/src/virt/vm/kvm_dev.rs b/kernel/src/virt/vm/kvm_dev.rs index cab74f37..b64f0d6a 100644 --- a/kernel/src/virt/vm/kvm_dev.rs +++ b/kernel/src/virt/vm/kvm_dev.rs @@ -13,9 +13,9 @@ use crate::{ filesystem::{ devfs::{devfs_register, DevFS, DeviceINode}, vfs::{ - core::generate_inode_id, file::{File, FileMode}, syscall::ModeType, + vcore::generate_inode_id, FileType, IndexNode, Metadata, }, }, @@ -61,6 +61,7 @@ impl LockedKvmInode { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type: FileType::KvmDevice, // 文件夹,block设备,char设备 mode: ModeType::S_IALLUGO, nlinks: 1, @@ -202,6 +203,7 @@ impl KvmInstance { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type: FileType::KvmDevice, mode: ModeType::S_IALLUGO, nlinks: 1, @@ -332,6 +334,7 @@ impl KvmVcpuDev { atime: PosixTimeSpec::default(), mtime: PosixTimeSpec::default(), ctime: PosixTimeSpec::default(), + btime: PosixTimeSpec::default(), file_type: FileType::KvmDevice, // 文件夹,block设备,char设备 mode: ModeType::S_IALLUGO, nlinks: 1,