mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 10:15:03 +00:00
refactor(vfs): 重构statx系统调用的实现 (#1149)
- 将kstat的获取,与posix statx的获取进行分离. - 修复statx没有处理dirfd的bug - 在Metadata结构体中新增btime字段,表示文件的创建时间 - 更新多个文件系统的metadata实现,添加对btime的支持 - 引入derive_builder crate以简化Metadata构建过程 - 重构vfs模块,将core重命名为vcore以避免命名冲突 - 实现vfs_statx和vfs_getattr函数,支持更详细的文件属性查询 - 新增LookUpFlags定义,用于路径查找时的标志位 Signed-off-by: longjin <longjin@dragonos.org>
This commit is contained in:
parent
bc9bb9607f
commit
0b89d7130e
85
kernel/Cargo.lock
generated
85
kernel/Cargo.lock
generated
@ -361,6 +361,41 @@ version = "1.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
|
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]]
|
[[package]]
|
||||||
name = "defer"
|
name = "defer"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@ -399,6 +434,37 @@ dependencies = [
|
|||||||
"thiserror",
|
"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]]
|
[[package]]
|
||||||
name = "derive_more"
|
name = "derive_more"
|
||||||
version = "0.99.19"
|
version = "0.99.19"
|
||||||
@ -435,6 +501,7 @@ dependencies = [
|
|||||||
"bitmap",
|
"bitmap",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"defer",
|
"defer",
|
||||||
|
"derive_builder",
|
||||||
"driver_base_macros",
|
"driver_base_macros",
|
||||||
"elf 0.7.2",
|
"elf 0.7.2",
|
||||||
"fdt",
|
"fdt",
|
||||||
@ -546,6 +613,12 @@ name = "fdt"
|
|||||||
version = "0.2.0-alpha1"
|
version = "0.2.0-alpha1"
|
||||||
source = "git+https://git.mirrors.dragonos.org.cn/DragonOS-Community/fdt?rev=9862813020#98628130200086c2e55dae0d997ac4daeb590e90"
|
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]]
|
[[package]]
|
||||||
name = "foldhash"
|
name = "foldhash"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
@ -668,6 +741,12 @@ dependencies = [
|
|||||||
"kdepends",
|
"kdepends",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ident_case"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.9.3"
|
version = "1.9.3"
|
||||||
@ -1558,6 +1637,12 @@ version = "0.1.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
|
checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.109"
|
version = "1.0.109"
|
||||||
|
@ -79,6 +79,7 @@ static-keys = { version = "=0.7" }
|
|||||||
|
|
||||||
defer = "0.2.1"
|
defer = "0.2.1"
|
||||||
cfg-if = { version = "1.0.0" }
|
cfg-if = { version = "1.0.0" }
|
||||||
|
derive_builder = { version = "0.20.2", default-features = false, features = ["alloc"] }
|
||||||
|
|
||||||
|
|
||||||
# target为x86_64时,使用下面的依赖
|
# target为x86_64时,使用下面的依赖
|
||||||
|
@ -162,7 +162,7 @@ macro_rules! define_event_trace{
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
struct [<__ $name _TracePointMeta>]{
|
struct [<__ $name _TracePointMeta>]{
|
||||||
trace_point: &'static $crate::debug::tracing::tracepoint::TracePoint,
|
trace_point: &'static $crate::debug::tracing::tracepoint::TracePoint,
|
||||||
print_func: fn(&mut (dyn core::any::Any+Send+Sync),$($arg_type),*),
|
print_func: fn(&mut (dyn core::any::Any+Send+Sync),$($arg_type),*),
|
||||||
|
@ -31,7 +31,7 @@ use crate::{
|
|||||||
devfs::{devfs_register, DevFS, DeviceINode},
|
devfs::{devfs_register, DevFS, DeviceINode},
|
||||||
kernfs::KernFSInode,
|
kernfs::KernFSInode,
|
||||||
vfs::{
|
vfs::{
|
||||||
core::generate_inode_id, syscall::ModeType, utils::DName, FilePrivateData, FileSystem,
|
syscall::ModeType, utils::DName, vcore::generate_inode_id, FilePrivateData, FileSystem,
|
||||||
FileType, IndexNode, Metadata,
|
FileType, IndexNode, Metadata,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -198,6 +198,7 @@ impl Ps2MouseDevice {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type: FileType::CharDevice, // 文件夹,block设备,char设备
|
file_type: FileType::CharDevice, // 文件夹,block设备,char设备
|
||||||
mode: ModeType::from_bits_truncate(0o644),
|
mode: ModeType::from_bits_truncate(0o644),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
|
@ -22,7 +22,7 @@ use crate::{
|
|||||||
filesystem::{
|
filesystem::{
|
||||||
devfs::{devfs_register, DevFS, DeviceINode},
|
devfs::{devfs_register, DevFS, DeviceINode},
|
||||||
vfs::{
|
vfs::{
|
||||||
core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData,
|
file::FileMode, syscall::ModeType, vcore::generate_inode_id, FilePrivateData,
|
||||||
FileSystem, FileType, IndexNode, Metadata,
|
FileSystem, FileType, IndexNode, Metadata,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -86,6 +86,7 @@ impl LockedPS2KeyBoardInode {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type: FileType::CharDevice, // 文件夹,block设备,char设备
|
file_type: FileType::CharDevice, // 文件夹,block设备,char设备
|
||||||
mode: ModeType::from_bits_truncate(0o666),
|
mode: ModeType::from_bits_truncate(0o666),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
@ -155,6 +156,7 @@ impl IndexNode for LockedPS2KeyBoardInode {
|
|||||||
inode.metadata.atime = metadata.atime;
|
inode.metadata.atime = metadata.atime;
|
||||||
inode.metadata.mtime = metadata.mtime;
|
inode.metadata.mtime = metadata.mtime;
|
||||||
inode.metadata.ctime = metadata.ctime;
|
inode.metadata.ctime = metadata.ctime;
|
||||||
|
inode.metadata.btime = metadata.btime;
|
||||||
inode.metadata.mode = metadata.mode;
|
inode.metadata.mode = metadata.mode;
|
||||||
inode.metadata.uid = metadata.uid;
|
inode.metadata.uid = metadata.uid;
|
||||||
inode.metadata.gid = metadata.gid;
|
inode.metadata.gid = metadata.gid;
|
||||||
|
@ -3,10 +3,10 @@ pub mod null_dev;
|
|||||||
pub mod zero_dev;
|
pub mod zero_dev;
|
||||||
|
|
||||||
use super::vfs::{
|
use super::vfs::{
|
||||||
core::{generate_inode_id, ROOT_INODE},
|
|
||||||
file::FileMode,
|
file::FileMode,
|
||||||
syscall::ModeType,
|
syscall::ModeType,
|
||||||
utils::DName,
|
utils::DName,
|
||||||
|
vcore::{generate_inode_id, ROOT_INODE},
|
||||||
FilePrivateData, FileSystem, FileType, FsInfo, IndexNode, Magic, Metadata, SuperBlock,
|
FilePrivateData, FileSystem, FileType, FsInfo, IndexNode, Magic, Metadata, SuperBlock,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -284,6 +284,7 @@ impl DevFSInode {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type: dev_type_, // 文件夹
|
file_type: dev_type_, // 文件夹
|
||||||
mode,
|
mode,
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
@ -375,6 +376,7 @@ impl LockedDevFSInode {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type,
|
file_type,
|
||||||
mode,
|
mode,
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
@ -531,6 +533,7 @@ impl IndexNode for LockedDevFSInode {
|
|||||||
inode.metadata.atime = metadata.atime;
|
inode.metadata.atime = metadata.atime;
|
||||||
inode.metadata.mtime = metadata.mtime;
|
inode.metadata.mtime = metadata.mtime;
|
||||||
inode.metadata.ctime = metadata.ctime;
|
inode.metadata.ctime = metadata.ctime;
|
||||||
|
inode.metadata.btime = metadata.btime;
|
||||||
inode.metadata.mode = metadata.mode;
|
inode.metadata.mode = metadata.mode;
|
||||||
inode.metadata.uid = metadata.uid;
|
inode.metadata.uid = metadata.uid;
|
||||||
inode.metadata.gid = metadata.gid;
|
inode.metadata.gid = metadata.gid;
|
||||||
|
@ -2,7 +2,7 @@ use crate::driver::base::device::device_number::DeviceNumber;
|
|||||||
use crate::filesystem::vfs::file::FileMode;
|
use crate::filesystem::vfs::file::FileMode;
|
||||||
use crate::filesystem::vfs::syscall::ModeType;
|
use crate::filesystem::vfs::syscall::ModeType;
|
||||||
use crate::filesystem::vfs::{
|
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::SpinLockGuard;
|
||||||
use crate::{libs::spinlock::SpinLock, time::PosixTimeSpec};
|
use crate::{libs::spinlock::SpinLock, time::PosixTimeSpec};
|
||||||
@ -45,6 +45,7 @@ impl LockedNullInode {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type: FileType::CharDevice, // 文件夹,block设备,char设备
|
file_type: FileType::CharDevice, // 文件夹,block设备,char设备
|
||||||
mode: ModeType::from_bits_truncate(0o666),
|
mode: ModeType::from_bits_truncate(0o666),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
@ -101,6 +102,7 @@ impl IndexNode for LockedNullInode {
|
|||||||
inode.metadata.atime = metadata.atime;
|
inode.metadata.atime = metadata.atime;
|
||||||
inode.metadata.mtime = metadata.mtime;
|
inode.metadata.mtime = metadata.mtime;
|
||||||
inode.metadata.ctime = metadata.ctime;
|
inode.metadata.ctime = metadata.ctime;
|
||||||
|
inode.metadata.btime = metadata.btime;
|
||||||
inode.metadata.mode = metadata.mode;
|
inode.metadata.mode = metadata.mode;
|
||||||
inode.metadata.uid = metadata.uid;
|
inode.metadata.uid = metadata.uid;
|
||||||
inode.metadata.gid = metadata.gid;
|
inode.metadata.gid = metadata.gid;
|
||||||
|
@ -2,7 +2,7 @@ use crate::driver::base::device::device_number::DeviceNumber;
|
|||||||
use crate::filesystem::vfs::file::FileMode;
|
use crate::filesystem::vfs::file::FileMode;
|
||||||
use crate::filesystem::vfs::syscall::ModeType;
|
use crate::filesystem::vfs::syscall::ModeType;
|
||||||
use crate::filesystem::vfs::{
|
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::SpinLockGuard;
|
||||||
use crate::{libs::spinlock::SpinLock, time::PosixTimeSpec};
|
use crate::{libs::spinlock::SpinLock, time::PosixTimeSpec};
|
||||||
@ -45,6 +45,7 @@ impl LockedZeroInode {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type: FileType::CharDevice, // 文件夹,block设备,char设备
|
file_type: FileType::CharDevice, // 文件夹,block设备,char设备
|
||||||
mode: ModeType::from_bits_truncate(0o666),
|
mode: ModeType::from_bits_truncate(0o666),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
@ -101,6 +102,7 @@ impl IndexNode for LockedZeroInode {
|
|||||||
inode.metadata.atime = metadata.atime;
|
inode.metadata.atime = metadata.atime;
|
||||||
inode.metadata.mtime = metadata.mtime;
|
inode.metadata.mtime = metadata.mtime;
|
||||||
inode.metadata.ctime = metadata.ctime;
|
inode.metadata.ctime = metadata.ctime;
|
||||||
|
inode.metadata.btime = metadata.btime;
|
||||||
inode.metadata.mode = metadata.mode;
|
inode.metadata.mode = metadata.mode;
|
||||||
inode.metadata.uid = metadata.uid;
|
inode.metadata.uid = metadata.uid;
|
||||||
inode.metadata.gid = metadata.gid;
|
inode.metadata.gid = metadata.gid;
|
||||||
|
@ -22,14 +22,14 @@ use crate::{
|
|||||||
tty_device::{PtyType, TtyDevice, TtyType},
|
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,
|
init::initcall::INITCALL_FS,
|
||||||
libs::spinlock::{SpinLock, SpinLockGuard},
|
libs::spinlock::{SpinLock, SpinLockGuard},
|
||||||
time::PosixTimeSpec,
|
time::PosixTimeSpec,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::vfs::{
|
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;
|
const DEV_PTYFS_MAX_NAMELEN: usize = 16;
|
||||||
@ -109,6 +109,7 @@ impl LockedDevPtsFSInode {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type: FileType::Dir,
|
file_type: FileType::Dir,
|
||||||
mode: ModeType::from_bits_truncate(0o777),
|
mode: ModeType::from_bits_truncate(0o777),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
|
@ -23,9 +23,9 @@ use crate::mm::VmFaultReason;
|
|||||||
use crate::{
|
use crate::{
|
||||||
driver::base::block::{block_device::LBA_SIZE, disk_info::Partition, SeekFrom},
|
driver::base::block::{block_device::LBA_SIZE, disk_info::Partition, SeekFrom},
|
||||||
filesystem::vfs::{
|
filesystem::vfs::{
|
||||||
core::generate_inode_id,
|
|
||||||
file::{FileMode, FilePrivateData},
|
file::{FileMode, FilePrivateData},
|
||||||
syscall::ModeType,
|
syscall::ModeType,
|
||||||
|
vcore::generate_inode_id,
|
||||||
FileSystem, FileType, IndexNode, InodeId, Metadata,
|
FileSystem, FileType, IndexNode, InodeId, Metadata,
|
||||||
},
|
},
|
||||||
libs::{
|
libs::{
|
||||||
@ -227,6 +227,7 @@ impl LockedFATInode {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type,
|
file_type,
|
||||||
mode: ModeType::from_bits_truncate(0o777),
|
mode: ModeType::from_bits_truncate(0o777),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
@ -377,6 +378,7 @@ impl FATFileSystem {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type: FileType::Dir,
|
file_type: FileType::Dir,
|
||||||
mode: ModeType::from_bits_truncate(0o777),
|
mode: ModeType::from_bits_truncate(0o777),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
|
@ -22,7 +22,7 @@ use crate::{
|
|||||||
use self::callback::{KernCallbackData, KernFSCallback, KernInodePrivateData};
|
use self::callback::{KernCallbackData, KernFSCallback, KernInodePrivateData};
|
||||||
|
|
||||||
use super::vfs::{
|
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,
|
FileType, FsInfo, IndexNode, InodeId, Magic, Metadata, SuperBlock,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -94,6 +94,7 @@ impl KernFS {
|
|||||||
atime: PosixTimeSpec::new(0, 0),
|
atime: PosixTimeSpec::new(0, 0),
|
||||||
mtime: PosixTimeSpec::new(0, 0),
|
mtime: PosixTimeSpec::new(0, 0),
|
||||||
ctime: PosixTimeSpec::new(0, 0),
|
ctime: PosixTimeSpec::new(0, 0),
|
||||||
|
btime: PosixTimeSpec::new(0, 0),
|
||||||
dev_id: 0,
|
dev_id: 0,
|
||||||
inode_id: generate_inode_id(),
|
inode_id: generate_inode_id(),
|
||||||
file_type: FileType::Dir,
|
file_type: FileType::Dir,
|
||||||
@ -525,6 +526,7 @@ impl KernFSInode {
|
|||||||
atime: PosixTimeSpec::new(0, 0),
|
atime: PosixTimeSpec::new(0, 0),
|
||||||
mtime: PosixTimeSpec::new(0, 0),
|
mtime: PosixTimeSpec::new(0, 0),
|
||||||
ctime: PosixTimeSpec::new(0, 0),
|
ctime: PosixTimeSpec::new(0, 0),
|
||||||
|
btime: PosixTimeSpec::new(0, 0),
|
||||||
dev_id: 0,
|
dev_id: 0,
|
||||||
inode_id: generate_inode_id(),
|
inode_id: generate_inode_id(),
|
||||||
file_type: file_type.into(),
|
file_type: file_type.into(),
|
||||||
|
@ -15,7 +15,7 @@ use crate::{
|
|||||||
arch::mm::LockedFrameAllocator,
|
arch::mm::LockedFrameAllocator,
|
||||||
driver::base::device::device_number::DeviceNumber,
|
driver::base::device::device_number::DeviceNumber,
|
||||||
filesystem::vfs::{
|
filesystem::vfs::{
|
||||||
core::{generate_inode_id, ROOT_INODE},
|
vcore::{generate_inode_id, ROOT_INODE},
|
||||||
FileType,
|
FileType,
|
||||||
},
|
},
|
||||||
libs::{
|
libs::{
|
||||||
@ -361,6 +361,7 @@ impl ProcFS {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type: FileType::Dir,
|
file_type: FileType::Dir,
|
||||||
mode: ModeType::from_bits_truncate(0o555),
|
mode: ModeType::from_bits_truncate(0o555),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
@ -656,6 +657,7 @@ impl IndexNode for LockedProcFSInode {
|
|||||||
inode.metadata.atime = metadata.atime;
|
inode.metadata.atime = metadata.atime;
|
||||||
inode.metadata.mtime = metadata.mtime;
|
inode.metadata.mtime = metadata.mtime;
|
||||||
inode.metadata.ctime = metadata.ctime;
|
inode.metadata.ctime = metadata.ctime;
|
||||||
|
inode.metadata.btime = metadata.btime;
|
||||||
inode.metadata.mode = metadata.mode;
|
inode.metadata.mode = metadata.mode;
|
||||||
inode.metadata.uid = metadata.uid;
|
inode.metadata.uid = metadata.uid;
|
||||||
inode.metadata.gid = metadata.gid;
|
inode.metadata.gid = metadata.gid;
|
||||||
@ -708,6 +710,7 @@ impl IndexNode for LockedProcFSInode {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type,
|
file_type,
|
||||||
mode,
|
mode,
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
|
@ -5,7 +5,7 @@ use crate::filesystem::vfs::{FileSystemMakerData, FSMAKER};
|
|||||||
use crate::libs::rwlock::RwLock;
|
use crate::libs::rwlock::RwLock;
|
||||||
use crate::{
|
use crate::{
|
||||||
driver::base::device::device_number::DeviceNumber,
|
driver::base::device::device_number::DeviceNumber,
|
||||||
filesystem::vfs::{core::generate_inode_id, FileType},
|
filesystem::vfs::{vcore::generate_inode_id, FileType},
|
||||||
ipc::pipe::LockedPipeInode,
|
ipc::pipe::LockedPipeInode,
|
||||||
libs::casting::DowncastArc,
|
libs::casting::DowncastArc,
|
||||||
libs::spinlock::{SpinLock, SpinLockGuard},
|
libs::spinlock::{SpinLock, SpinLockGuard},
|
||||||
@ -86,6 +86,7 @@ impl RamFSInode {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type: FileType::Dir,
|
file_type: FileType::Dir,
|
||||||
mode: ModeType::from_bits_truncate(0o777),
|
mode: ModeType::from_bits_truncate(0o777),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
@ -281,6 +282,7 @@ impl IndexNode for LockedRamFSInode {
|
|||||||
inode.metadata.atime = metadata.atime;
|
inode.metadata.atime = metadata.atime;
|
||||||
inode.metadata.mtime = metadata.mtime;
|
inode.metadata.mtime = metadata.mtime;
|
||||||
inode.metadata.ctime = metadata.ctime;
|
inode.metadata.ctime = metadata.ctime;
|
||||||
|
inode.metadata.btime = metadata.btime;
|
||||||
inode.metadata.mode = metadata.mode;
|
inode.metadata.mode = metadata.mode;
|
||||||
inode.metadata.uid = metadata.uid;
|
inode.metadata.uid = metadata.uid;
|
||||||
inode.metadata.gid = metadata.gid;
|
inode.metadata.gid = metadata.gid;
|
||||||
@ -332,6 +334,7 @@ impl IndexNode for LockedRamFSInode {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type,
|
file_type,
|
||||||
mode,
|
mode,
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
@ -594,6 +597,7 @@ impl IndexNode for LockedRamFSInode {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type: FileType::Pipe,
|
file_type: FileType::Pipe,
|
||||||
mode,
|
mode,
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
|
@ -101,6 +101,8 @@ bitflags! {
|
|||||||
/// 应用于整个子树。
|
/// 应用于整个子树。
|
||||||
/// AT_RECURSIVE: 0x8000
|
/// AT_RECURSIVE: 0x8000
|
||||||
const AT_RECURSIVE = 0x8000;
|
const AT_RECURSIVE = 0x8000;
|
||||||
|
|
||||||
|
const AT_GETATTR_NOSEC = i32::MIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
pub mod core;
|
|
||||||
pub mod fcntl;
|
pub mod fcntl;
|
||||||
pub mod file;
|
pub mod file;
|
||||||
pub mod mount;
|
pub mod mount;
|
||||||
pub mod open;
|
pub mod open;
|
||||||
|
pub mod stat;
|
||||||
pub mod syscall;
|
pub mod syscall;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
pub mod vcore;
|
||||||
|
|
||||||
use ::core::{any::Any, fmt::Debug, sync::atomic::AtomicUsize};
|
use ::core::{any::Any, fmt::Debug, sync::atomic::AtomicUsize};
|
||||||
use alloc::{string::String, sync::Arc, vec::Vec};
|
use alloc::{string::String, sync::Arc, vec::Vec};
|
||||||
|
use derive_builder::Builder;
|
||||||
use intertrait::CastFromSync;
|
use intertrait::CastFromSync;
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
@ -25,8 +27,8 @@ use crate::{
|
|||||||
time::PosixTimeSpec,
|
time::PosixTimeSpec,
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::{core::generate_inode_id, file::FileMode, syscall::ModeType, utils::DName};
|
use self::{file::FileMode, syscall::ModeType, utils::DName, vcore::generate_inode_id};
|
||||||
pub use self::{core::ROOT_INODE, file::FilePrivateData, mount::MountFS};
|
pub use self::{file::FilePrivateData, mount::MountFS, vcore::ROOT_INODE};
|
||||||
|
|
||||||
use super::page_cache::PageCache;
|
use super::page_cache::PageCache;
|
||||||
|
|
||||||
@ -59,6 +61,22 @@ pub enum FileType {
|
|||||||
Socket,
|
Socket,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<FileType> 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)]
|
#[allow(dead_code)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum SpecialNodeData {
|
pub enum SpecialNodeData {
|
||||||
@ -781,7 +799,8 @@ impl dyn IndexNode {
|
|||||||
/// IndexNode的元数据
|
/// IndexNode的元数据
|
||||||
///
|
///
|
||||||
/// 对应Posix2008中的sys/stat.h中的定义 https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_stat.h.html
|
/// 对应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 {
|
pub struct Metadata {
|
||||||
/// 当前inode所在的文件系统的设备号
|
/// 当前inode所在的文件系统的设备号
|
||||||
pub dev_id: usize,
|
pub dev_id: usize,
|
||||||
@ -803,12 +822,15 @@ pub struct Metadata {
|
|||||||
/// inode最后一次被访问的时间
|
/// inode最后一次被访问的时间
|
||||||
pub atime: PosixTimeSpec,
|
pub atime: PosixTimeSpec,
|
||||||
|
|
||||||
/// inode最后一次修改的时间
|
/// inode的文件数据最后一次修改的时间
|
||||||
pub mtime: PosixTimeSpec,
|
pub mtime: PosixTimeSpec,
|
||||||
|
|
||||||
/// inode的创建时间
|
/// inode的元数据、权限或文件内容最后一次发生改变的时间
|
||||||
pub ctime: PosixTimeSpec,
|
pub ctime: PosixTimeSpec,
|
||||||
|
|
||||||
|
/// inode的创建时间
|
||||||
|
pub btime: PosixTimeSpec,
|
||||||
|
|
||||||
/// 文件类型
|
/// 文件类型
|
||||||
pub file_type: FileType,
|
pub file_type: FileType,
|
||||||
|
|
||||||
@ -839,6 +861,7 @@ impl Default for Metadata {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type: FileType::File,
|
file_type: FileType::File,
|
||||||
mode: ModeType::empty(),
|
mode: ModeType::empty(),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
@ -975,6 +998,7 @@ impl Metadata {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type,
|
file_type,
|
||||||
mode,
|
mode,
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
|
@ -749,3 +749,18 @@ impl Debug for MountList {
|
|||||||
f.debug_map().entries(MOUNT_LIST().0.read().iter()).finish()
|
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<dyn IndexNode>) -> bool {
|
||||||
|
let mnt_inode = inode.as_any_ref().downcast_ref::<MountFSInode>();
|
||||||
|
if let Some(mnt) = mnt_inode {
|
||||||
|
return mnt.is_mountpoint_root().unwrap_or(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
398
kernel/src/filesystem/vfs/stat.rs
Normal file
398
kernel/src/filesystem/vfs/stat.rs
Normal file
@ -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<AtFlags> 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<KStat, SystemError> {
|
||||||
|
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<dyn IndexNode>,
|
||||||
|
request_mask: PosixStatxMask,
|
||||||
|
mut at_flags: AtFlags,
|
||||||
|
) -> Result<KStat, SystemError> {
|
||||||
|
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::<PosixStatx>(),
|
||||||
|
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(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,7 @@ use crate::producefs;
|
|||||||
use crate::syscall::user_access::UserBufferReader;
|
use crate::syscall::user_access::UserBufferReader;
|
||||||
use crate::{
|
use crate::{
|
||||||
driver::base::{block::SeekFrom, device::device_number::DeviceNumber},
|
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,
|
libs::rwlock::RwLockWriteGuard,
|
||||||
mm::{verify_area, VirtAddr},
|
mm::{verify_area, VirtAddr},
|
||||||
process::ProcessManager,
|
process::ProcessManager,
|
||||||
@ -21,15 +21,16 @@ use crate::{
|
|||||||
time::{syscall::PosixTimeval, PosixTimeSpec},
|
time::{syscall::PosixTimeval, PosixTimeSpec},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::core::do_symlinkat;
|
use super::stat::{do_statx, PosixKstat};
|
||||||
|
use super::vcore::do_symlinkat;
|
||||||
use super::{
|
use super::{
|
||||||
core::{do_mkdir_at, do_remove_dir, do_unlink_at},
|
|
||||||
fcntl::{AtFlags, FcntlCommand, FD_CLOEXEC},
|
fcntl::{AtFlags, FcntlCommand, FD_CLOEXEC},
|
||||||
file::{File, FileMode},
|
file::{File, FileMode},
|
||||||
open::{
|
open::{
|
||||||
do_faccessat, do_fchmodat, do_fchownat, do_sys_open, do_utimensat, do_utimes, ksys_fchown,
|
do_faccessat, do_fchmodat, do_fchownat, do_sys_open, do_utimensat, do_utimes, ksys_fchown,
|
||||||
},
|
},
|
||||||
utils::{rsplit_path, user_path_at},
|
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,
|
Dirent, FileType, IndexNode, SuperBlock, FSMAKER, MAX_PATHLEN, ROOT_INODE,
|
||||||
VFS_MAX_FOLLOW_SYMLINK_TIMES,
|
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)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
/// # 文件信息结构体X
|
/// # 文件信息结构体X
|
||||||
pub struct PosixStatx {
|
pub struct PosixStatx {
|
||||||
/* 0x00 */
|
/* 0x00 */
|
||||||
stx_mask: PosixStatxMask,
|
pub stx_mask: PosixStatxMask,
|
||||||
/// 文件系统块大小
|
/// 文件系统块大小
|
||||||
stx_blksize: u32,
|
pub stx_blksize: u32,
|
||||||
/// Flags conveying information about the file [uncond]
|
/// Flags conveying information about the file [uncond]
|
||||||
stx_attributes: StxAttributes,
|
pub stx_attributes: StxAttributes,
|
||||||
/* 0x10 */
|
/* 0x10 */
|
||||||
/// 硬链接数
|
/// 硬链接数
|
||||||
stx_nlink: u32,
|
pub stx_nlink: u32,
|
||||||
/// 所有者用户ID
|
/// 所有者用户ID
|
||||||
stx_uid: u32,
|
pub stx_uid: u32,
|
||||||
/// 所有者组ID
|
/// 所有者组ID
|
||||||
stx_gid: u32,
|
pub stx_gid: u32,
|
||||||
/// 文件权限
|
/// 文件权限
|
||||||
stx_mode: ModeType,
|
pub stx_mode: ModeType,
|
||||||
|
|
||||||
/* 0x20 */
|
/* 0x20 */
|
||||||
/// inode号
|
/// inode号
|
||||||
stx_inode: u64,
|
pub stx_inode: u64,
|
||||||
/// 文件大小
|
/// 文件大小
|
||||||
stx_size: i64,
|
pub stx_size: i64,
|
||||||
/// 分配的512B块数
|
/// 分配的512B块数
|
||||||
stx_blocks: u64,
|
pub stx_blocks: u64,
|
||||||
/// Mask to show what's supported in stx_attributes
|
/// Mask to show what's supported in stx_attributes
|
||||||
stx_attributes_mask: StxAttributes,
|
pub stx_attributes_mask: StxAttributes,
|
||||||
|
|
||||||
/* 0x40 */
|
/* 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 */
|
/* 0x80 */
|
||||||
/// 主设备ID
|
/// 主设备ID
|
||||||
stx_rdev_major: u32,
|
pub stx_rdev_major: u32,
|
||||||
/// 次设备ID
|
/// 次设备ID
|
||||||
stx_rdev_minor: u32,
|
pub stx_rdev_minor: u32,
|
||||||
/// 主硬件设备ID
|
/// 主硬件设备ID
|
||||||
stx_dev_major: u32,
|
pub stx_dev_major: u32,
|
||||||
/// 次硬件设备ID
|
/// 次硬件设备ID
|
||||||
stx_dev_minor: u32,
|
pub stx_dev_minor: u32,
|
||||||
|
|
||||||
/* 0x90 */
|
/* 0x90 */
|
||||||
stx_mnt_id: u64,
|
pub stx_mnt_id: u64,
|
||||||
stx_dio_mem_align: u32,
|
pub stx_dio_mem_align: u32,
|
||||||
stx_dio_offset_align: u32,
|
pub stx_dio_offset_align: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PosixStatx {
|
impl PosixStatx {
|
||||||
fn new() -> Self {
|
#[inline(never)]
|
||||||
|
pub(super) fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
stx_mask: PosixStatxMask::STATX_BASIC_STATS,
|
stx_mask: PosixStatxMask::STATX_BASIC_STATS,
|
||||||
stx_blksize: 0,
|
stx_blksize: 0,
|
||||||
@ -301,6 +241,9 @@ bitflags! {
|
|||||||
|
|
||||||
/// Reserved for future struct statx expansion
|
/// Reserved for future struct statx expansion
|
||||||
const STATX_RESERVED = 0x80000000;
|
const STATX_RESERVED = 0x80000000;
|
||||||
|
|
||||||
|
/// Want/got stx_change_attr
|
||||||
|
const STATX_CHANGE_COOKIE = 0x40000000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,6 +267,8 @@ bitflags! {
|
|||||||
const STATX_ATTR_VERITY = 0x00100000;
|
const STATX_ATTR_VERITY = 0x00100000;
|
||||||
/// 文件当前处于 DAX 状态 CPU直接访问
|
/// 文件当前处于 DAX 状态 CPU直接访问
|
||||||
const STATX_ATTR_DAX = 0x00200000;
|
const STATX_ATTR_DAX = 0x00200000;
|
||||||
|
/// version monotonically increases
|
||||||
|
const STATX_ATTR_CHANGE_MONOTONIC = 0x8000000000000000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1411,112 +1356,22 @@ impl Syscall {
|
|||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_statx(
|
#[inline(never)]
|
||||||
fd: i32,
|
pub fn statx(
|
||||||
path: *const u8,
|
dfd: i32,
|
||||||
|
filename_ptr: usize,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
mask: u32,
|
mask: u32,
|
||||||
usr_kstat: *mut PosixStatx,
|
user_kstat_ptr: usize,
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
if usr_kstat.is_null() {
|
if user_kstat_ptr == 0 {
|
||||||
return Err(SystemError::EFAULT);
|
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) {
|
do_statx(dfd, filename_str, flags, mask, user_kstat_ptr).map(|_| 0)
|
||||||
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::<PosixStatx>(), 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mknod(
|
pub fn mknod(
|
||||||
|
@ -26,6 +26,7 @@ use super::{
|
|||||||
fcntl::AtFlags,
|
fcntl::AtFlags,
|
||||||
file::FileMode,
|
file::FileMode,
|
||||||
mount::{init_mountlist, MOUNT_LIST},
|
mount::{init_mountlist, MOUNT_LIST},
|
||||||
|
stat::LookUpFlags,
|
||||||
syscall::UmountFlag,
|
syscall::UmountFlag,
|
||||||
utils::{rsplit_path, user_path_at},
|
utils::{rsplit_path, user_path_at},
|
||||||
FilePrivateData, IndexNode, InodeId, VFS_MAX_FOLLOW_SYMLINK_TIMES,
|
FilePrivateData, IndexNode, InodeId, VFS_MAX_FOLLOW_SYMLINK_TIMES,
|
||||||
@ -396,3 +397,13 @@ pub fn do_umount2(
|
|||||||
};
|
};
|
||||||
return do_umount();
|
return do_umount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn do_file_lookup_at(
|
||||||
|
dfd: i32,
|
||||||
|
path: &str,
|
||||||
|
lookup_flags: LookUpFlags,
|
||||||
|
) -> Result<Arc<dyn IndexNode>, 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);
|
||||||
|
}
|
@ -9,7 +9,7 @@ use crate::{
|
|||||||
video::VideoRefreshManager,
|
video::VideoRefreshManager,
|
||||||
},
|
},
|
||||||
exception::{init::irq_init, softirq::softirq_init, InterruptArch},
|
exception::{init::irq_init, softirq::softirq_init, InterruptArch},
|
||||||
filesystem::vfs::core::vfs_init,
|
filesystem::vfs::vcore::vfs_init,
|
||||||
init::init_intertrait,
|
init::init_intertrait,
|
||||||
libs::{
|
libs::{
|
||||||
futex::futex::Futex,
|
futex::futex::Futex,
|
||||||
|
@ -9,7 +9,7 @@ use system_error::SystemError;
|
|||||||
use crate::{
|
use crate::{
|
||||||
arch::{interrupt::TrapFrame, process::arch_switch_to_user},
|
arch::{interrupt::TrapFrame, process::arch_switch_to_user},
|
||||||
driver::net::e1000e::e1000e::e1000e_init,
|
driver::net::e1000e::e1000e::e1000e_init,
|
||||||
filesystem::vfs::core::mount_root_fs,
|
filesystem::vfs::vcore::mount_root_fs,
|
||||||
namespaces::NsProxy,
|
namespaces::NsProxy,
|
||||||
net::net_core::net_init,
|
net::net_core::net_init,
|
||||||
process::{
|
process::{
|
||||||
|
@ -3,7 +3,7 @@ use core::sync::atomic::compiler_fence;
|
|||||||
use crate::{
|
use crate::{
|
||||||
arch::ipc::signal::{SigCode, Signal},
|
arch::ipc::signal::{SigCode, Signal},
|
||||||
filesystem::vfs::{
|
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,
|
FileType, IndexNode, Metadata, PollableInode,
|
||||||
},
|
},
|
||||||
libs::{
|
libs::{
|
||||||
@ -128,6 +128,7 @@ impl LockedPipeInode {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type: FileType::Pipe,
|
file_type: FileType::Pipe,
|
||||||
mode: ModeType::from_bits_truncate(0o666),
|
mode: ModeType::from_bits_truncate(0o666),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
|
@ -5,7 +5,7 @@ use core::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::{ipc::signal::SigSet, syscall::nr::*},
|
arch::{ipc::signal::SigSet, syscall::nr::*},
|
||||||
filesystem::vfs::syscall::{PosixStatfs, PosixStatx},
|
filesystem::vfs::syscall::PosixStatfs,
|
||||||
ipc::shm::{ShmCtlCmd, ShmFlags, ShmId, ShmKey},
|
ipc::shm::{ShmCtlCmd, ShmFlags, ShmId, ShmKey},
|
||||||
libs::{futex::constant::FutexFlag, rand::GRandFlags},
|
libs::{futex::constant::FutexFlag, rand::GRandFlags},
|
||||||
mm::{page::PAGE_4K_SIZE, syscall::MremapFlags},
|
mm::{page::PAGE_4K_SIZE, syscall::MremapFlags},
|
||||||
@ -29,7 +29,8 @@ use crate::{
|
|||||||
filesystem::vfs::{
|
filesystem::vfs::{
|
||||||
fcntl::{AtFlags, FcntlCommand},
|
fcntl::{AtFlags, FcntlCommand},
|
||||||
file::FileMode,
|
file::FileMode,
|
||||||
syscall::{ModeType, PosixKstat, UtimensFlags},
|
stat::PosixKstat,
|
||||||
|
syscall::{ModeType, UtimensFlags},
|
||||||
MAX_PATHLEN,
|
MAX_PATHLEN,
|
||||||
},
|
},
|
||||||
libs::align::page_align_up,
|
libs::align::page_align_up,
|
||||||
@ -811,15 +812,13 @@ impl Syscall {
|
|||||||
Self::fstatfs(fd, statfs)
|
Self::fstatfs(fd, statfs)
|
||||||
}
|
}
|
||||||
|
|
||||||
SYS_STATX => {
|
SYS_STATX => Self::statx(
|
||||||
let fd = args[0] as i32;
|
args[0] as i32,
|
||||||
let path = args[1] as *const u8;
|
args[1],
|
||||||
let flags = args[2] as u32;
|
args[2] as u32,
|
||||||
let mask = args[3] as u32;
|
args[3] as u32,
|
||||||
let kstat = args[4] as *mut PosixStatx;
|
args[4],
|
||||||
|
),
|
||||||
Self::do_statx(fd, path, flags, mask, kstat)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
SYS_EPOLL_CREATE => Self::epoll_create(args[0] as i32),
|
SYS_EPOLL_CREATE => Self::epoll_create(args[0] as i32),
|
||||||
|
@ -65,6 +65,10 @@ impl PosixTimeSpec {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.tv_nsec == 0 && self.tv_sec == 0
|
||||||
|
}
|
||||||
|
|
||||||
/// 获取当前时间
|
/// 获取当前时间
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn now() -> Self {
|
pub fn now() -> Self {
|
||||||
|
@ -13,9 +13,9 @@ use crate::{
|
|||||||
filesystem::{
|
filesystem::{
|
||||||
devfs::{devfs_register, DevFS, DeviceINode},
|
devfs::{devfs_register, DevFS, DeviceINode},
|
||||||
vfs::{
|
vfs::{
|
||||||
core::generate_inode_id,
|
|
||||||
file::{File, FileMode},
|
file::{File, FileMode},
|
||||||
syscall::ModeType,
|
syscall::ModeType,
|
||||||
|
vcore::generate_inode_id,
|
||||||
FileType, IndexNode, Metadata,
|
FileType, IndexNode, Metadata,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -61,6 +61,7 @@ impl LockedKvmInode {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type: FileType::KvmDevice, // 文件夹,block设备,char设备
|
file_type: FileType::KvmDevice, // 文件夹,block设备,char设备
|
||||||
mode: ModeType::S_IALLUGO,
|
mode: ModeType::S_IALLUGO,
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
@ -202,6 +203,7 @@ impl KvmInstance {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type: FileType::KvmDevice,
|
file_type: FileType::KvmDevice,
|
||||||
mode: ModeType::S_IALLUGO,
|
mode: ModeType::S_IALLUGO,
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
@ -332,6 +334,7 @@ impl KvmVcpuDev {
|
|||||||
atime: PosixTimeSpec::default(),
|
atime: PosixTimeSpec::default(),
|
||||||
mtime: PosixTimeSpec::default(),
|
mtime: PosixTimeSpec::default(),
|
||||||
ctime: PosixTimeSpec::default(),
|
ctime: PosixTimeSpec::default(),
|
||||||
|
btime: PosixTimeSpec::default(),
|
||||||
file_type: FileType::KvmDevice, // 文件夹,block设备,char设备
|
file_type: FileType::KvmDevice, // 文件夹,block设备,char设备
|
||||||
mode: ModeType::S_IALLUGO,
|
mode: ModeType::S_IALLUGO,
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user