Ver Fonte

feat(syscall): impl fstatat

greatbridf há 7 meses atrás
pai
commit
73a10e4727

+ 1 - 0
crates/posix_types/src/lib.rs

@@ -3,4 +3,5 @@
 pub mod constants;
 pub mod result;
 pub mod signal;
+pub mod stat;
 pub mod syscall_no;

+ 96 - 0
crates/posix_types/src/stat.rs

@@ -0,0 +1,96 @@
+#[repr(C)]
+#[derive(Debug, Default, Copy, Clone)]
+pub struct StatXTimestamp {
+    pub tv_sec: i64,
+    pub tv_nsec: u32,
+    pub __reserved: i32,
+}
+
+#[repr(C)]
+#[derive(Debug, Default, Copy, Clone)]
+pub struct StatX {
+    pub stx_mask: u32,
+    pub stx_blksize: u32,
+    pub stx_attributes: u64,
+    pub stx_nlink: u32,
+    pub stx_uid: u32,
+    pub stx_gid: u32,
+    pub stx_mode: u16,
+    pub __spare0: [u16; 1usize],
+    pub stx_ino: u64,
+    pub stx_size: u64,
+    pub stx_blocks: u64,
+    pub stx_attributes_mask: u64,
+    pub stx_atime: StatXTimestamp,
+    pub stx_btime: StatXTimestamp,
+    pub stx_ctime: StatXTimestamp,
+    pub stx_mtime: StatXTimestamp,
+    pub stx_rdev_major: u32,
+    pub stx_rdev_minor: u32,
+    pub stx_dev_major: u32,
+    pub stx_dev_minor: u32,
+    pub stx_mnt_id: u64,
+    pub stx_dio_alignment: [u64; 13usize],
+}
+
+#[repr(C)]
+#[derive(Debug, Default, Copy, Clone)]
+pub struct TimeSpec {
+    pub tv_sec: u64,
+    pub tv_nsec: u64,
+}
+
+#[repr(C)]
+#[derive(Debug, Default, Copy, Clone)]
+pub struct Stat {
+    pub st_dev: u64,
+    pub st_ino: u64,
+    pub st_mode: u32,
+    pub st_nlink: usize,
+    pub st_uid: u32,
+    pub st_gid: u32,
+    pub st_rdev: u64,
+    __padding: usize,
+
+    pub st_size: u64,
+    pub st_blksize: usize,
+    __padding2: u32,
+
+    pub st_blocks: u64,
+    pub st_atime: TimeSpec,
+    pub st_mtime: TimeSpec,
+    pub st_ctime: TimeSpec,
+}
+
+impl From<StatX> for Stat {
+    fn from(statx: StatX) -> Self {
+        Self {
+            st_dev: statx.stx_dev_major as u64 | ((statx.stx_dev_minor as u64) << 32),
+            st_ino: statx.stx_ino,
+            st_mode: statx.stx_mode as u32,
+            st_nlink: statx.stx_nlink as usize,
+            st_uid: statx.stx_uid,
+            st_gid: statx.stx_gid,
+            st_rdev: statx.stx_rdev_major as u64 | ((statx.stx_rdev_minor as u64) << 32),
+            __padding: 0,
+
+            st_size: statx.stx_size,
+            st_blksize: statx.stx_blksize as usize,
+            __padding2: 0,
+
+            st_blocks: statx.stx_blocks,
+            st_atime: TimeSpec {
+                tv_sec: statx.stx_atime.tv_sec as u64,
+                tv_nsec: statx.stx_atime.tv_nsec as u64,
+            },
+            st_mtime: TimeSpec {
+                tv_sec: statx.stx_mtime.tv_sec as u64,
+                tv_nsec: statx.stx_mtime.tv_nsec as u64,
+            },
+            st_ctime: TimeSpec {
+                tv_sec: statx.stx_ctime.tv_sec as u64,
+                tv_nsec: statx.stx_ctime.tv_nsec as u64,
+            },
+        }
+    }
+}

+ 21 - 35
src/kernel/syscall/file_rw.rs

@@ -22,6 +22,7 @@ use crate::{
 use alloc::sync::Arc;
 use core::mem::MaybeUninit;
 use eonix_runtime::task::Task;
+use posix_types::stat::{Stat, StatX};
 use posix_types::syscall_no::*;
 
 fn dentry_from(
@@ -52,41 +53,6 @@ fn dentry_from(
     }
 }
 
-#[repr(C)]
-#[derive(Debug, Copy, Clone)]
-pub struct StatXTimestamp {
-    pub tv_sec: i64,
-    pub tv_nsec: u32,
-    pub __reserved: i32,
-}
-
-#[repr(C)]
-#[derive(Debug, Copy, Clone)]
-pub struct StatX {
-    pub stx_mask: u32,
-    pub stx_blksize: u32,
-    pub stx_attributes: u64,
-    pub stx_nlink: u32,
-    pub stx_uid: u32,
-    pub stx_gid: u32,
-    pub stx_mode: u16,
-    pub __spare0: [u16; 1usize],
-    pub stx_ino: u64,
-    pub stx_size: u64,
-    pub stx_blocks: u64,
-    pub stx_attributes_mask: u64,
-    pub stx_atime: StatXTimestamp,
-    pub stx_btime: StatXTimestamp,
-    pub stx_ctime: StatXTimestamp,
-    pub stx_mtime: StatXTimestamp,
-    pub stx_rdev_major: u32,
-    pub stx_rdev_minor: u32,
-    pub stx_dev_major: u32,
-    pub stx_dev_minor: u32,
-    pub stx_mnt_id: u64,
-    pub stx_dio_alignment: [u64; 13usize],
-}
-
 #[eonix_macros::define_syscall(SYS_READ)]
 fn read(fd: u32, buffer: *mut u8, bufsize: usize) -> KResult<usize> {
     let mut buffer = UserBuffer::new(buffer, bufsize)?;
@@ -159,6 +125,26 @@ fn getdents64(fd: u32, buffer: *mut u8, bufsize: usize) -> KResult<usize> {
     Ok(buffer.wrote())
 }
 
+#[eonix_macros::define_syscall(SYS_NEWFSTATAT)]
+fn newfstatat(dirfd: u32, pathname: *const u8, statbuf: *mut Stat, flags: u32) -> KResult<()> {
+    let dentry = if (flags & AT_EMPTY_PATH) != 0 {
+        let file = thread.files.get(dirfd).ok_or(EBADF)?;
+        file.as_path().ok_or(EBADF)?.clone()
+    } else {
+        let follow_symlink = (flags & AT_SYMLINK_NOFOLLOW) != AT_SYMLINK_NOFOLLOW;
+        dentry_from(thread, dirfd, pathname, follow_symlink)?
+    };
+
+    let statbuf = UserPointerMut::new(statbuf)?;
+
+    let mut statx = StatX::default();
+    dentry.statx(&mut statx, u32::MAX)?;
+
+    statbuf.write(statx.into())?;
+
+    Ok(())
+}
+
 #[eonix_macros::define_syscall(SYS_STATX)]
 fn statx(dirfd: u32, path: *const u8, flags: u32, mask: u32, buffer: *mut u8) -> KResult<()> {
     if (flags & AT_STATX_SYNC_TYPE) != AT_STATX_SYNC_AS_STAT {

+ 2 - 1
src/kernel/vfs/dentry.rs

@@ -10,7 +10,7 @@ use crate::kernel::constants::{
 use crate::{
     hash::KernelHasher,
     io::{Buffer, ByteBuffer},
-    kernel::{block::BlockDevice, syscall::file_rw::StatX, CharDevice},
+    kernel::{block::BlockDevice, CharDevice},
     path::{Path, PathComponent},
     prelude::*,
     rcu::{RCUNode, RCUPointer},
@@ -23,6 +23,7 @@ use core::{
     sync::atomic::{AtomicPtr, Ordering},
 };
 use eonix_sync::LazyLock;
+use posix_types::stat::StatX;
 
 struct DentryData {
     inode: Arc<dyn Inode>,

+ 3 - 3
src/kernel/vfs/file.rs

@@ -3,9 +3,8 @@ use super::{
     inode::{Mode, WriteOffset},
     s_isblk, s_isdir, s_isreg,
 };
-use crate::kernel::{
-    constants::{EBADF, EFAULT, EINTR, EINVAL, ENOTDIR, ENOTTY, EOVERFLOW, EPIPE, ESPIPE, S_IFMT},
-    syscall::file_rw::StatX,
+use crate::kernel::constants::{
+    EBADF, EFAULT, EINTR, EINVAL, ENOTDIR, ENOTTY, EOVERFLOW, EPIPE, ESPIPE, S_IFMT,
 };
 use crate::{
     io::{Buffer, BufferFill, ByteBuffer, Chunks},
@@ -25,6 +24,7 @@ use bitflags::bitflags;
 use core::{ops::ControlFlow, sync::atomic::Ordering};
 use eonix_runtime::task::Task;
 use eonix_sync::Mutex;
+use posix_types::stat::StatX;
 
 pub struct InodeFile {
     read: bool,

+ 2 - 1
src/kernel/vfs/inode.rs

@@ -3,7 +3,7 @@ use crate::kernel::constants::{
     EINVAL, EISDIR, ENOTDIR, EPERM, STATX_ATIME, STATX_BLOCKS, STATX_CTIME, STATX_GID, STATX_INO,
     STATX_MODE, STATX_MTIME, STATX_NLINK, STATX_SIZE, STATX_TYPE, STATX_UID, S_IFDIR, S_IFMT,
 };
-use crate::{io::Buffer, kernel::syscall::file_rw::StatX, prelude::*};
+use crate::{io::Buffer, prelude::*};
 use alloc::sync::{Arc, Weak};
 use core::{
     mem::MaybeUninit,
@@ -13,6 +13,7 @@ use core::{
 };
 use eonix_runtime::task::Task;
 use eonix_sync::RwLock;
+use posix_types::stat::StatX;
 
 pub type Ino = u64;
 pub type AtomicIno = AtomicU64;