Jelajahi Sumber

refactor(vfs): 移除PosixKstat并优化文件系统调用

- 移除PosixKstat结构体及相关代码
- 优化fstat、stat、lstat等系统调用实现

Signed-off-by: longjin <longjin@DragonOS.org>
longjin 12 jam lalu
induk
melakukan
a18c8be41c

+ 2 - 1
kernel/src/filesystem/vfs/open.rs

@@ -42,6 +42,7 @@ pub(super) fn do_faccessat(
 
     let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
     let path = path.to_str().map_err(|_| SystemError::EINVAL)?;
+    // log::debug!("do_faccessat path: {:?}", path);
 
     let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, path)?;
 
@@ -166,7 +167,7 @@ fn do_sys_openat2(
     how: OpenHow,
     follow_symlink: bool,
 ) -> Result<usize, SystemError> {
-    // debug!("open path: {}, how: {:?}", path, how);
+    // log::debug!("openat2: dirfd: {}, path: {}, how: {:?}",dirfd, path, how);
     let path = path.trim();
 
     let (inode_begin, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, path)?;

+ 2 - 65
kernel/src/filesystem/vfs/stat.rs

@@ -273,6 +273,7 @@ pub fn vfs_getattr(
 /// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/fs/stat.c#274
 #[inline(never)]
 pub fn vfs_fstatat(dfd: i32, filename: &str, flags: AtFlags) -> Result<KStat, SystemError> {
+    // log::debug!("vfs_fstatat: dfd={}, filename={}", dfd, filename);
     let statx_flags = flags | AtFlags::AT_NO_AUTOMOUNT;
     if dfd >= 0 && flags == AtFlags::AT_EMPTY_PATH {
         return vfs_fstat(dfd);
@@ -322,7 +323,7 @@ pub(super) fn do_newfstatat(
 
 /// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/fs/stat.c#393
 #[inline(never)]
-fn cp_new_stat(kstat: KStat, user_buf_ptr: usize) -> Result<(), SystemError> {
+pub(super) fn cp_new_stat(kstat: KStat, user_buf_ptr: usize) -> Result<(), SystemError> {
     let posix_stat = PosixStat::try_from(kstat)?;
     let mut ubuf_writer =
         UserBufferWriter::new(user_buf_ptr as *mut PosixStat, size_of::<PosixStat>(), true)?;
@@ -397,70 +398,6 @@ fn cp_statx(kstat: KStat, user_buf_ptr: usize) -> Result<(), SystemError> {
     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(),
-        }
-    }
-}
-
 /// 通用的PosixStat
 #[allow(unused)]
 #[repr(C)]

+ 23 - 61
kernel/src/filesystem/vfs/syscall.rs

@@ -21,7 +21,7 @@ use crate::{
     time::{syscall::PosixTimeval, PosixTimeSpec},
 };
 
-use super::stat::{do_newfstatat, do_statx, PosixKstat};
+use super::stat::{do_newfstatat, do_statx, vfs_fstat};
 use super::vcore::do_symlinkat;
 use super::{
     fcntl::{AtFlags, FcntlCommand, FD_CLOEXEC},
@@ -1248,79 +1248,31 @@ impl Syscall {
         return Err(SystemError::EBADF);
     }
 
-    fn do_fstat(fd: i32) -> Result<PosixKstat, SystemError> {
-        let binding = ProcessManager::current_pcb().fd_table();
-        let fd_table_guard = binding.read();
-        let file = fd_table_guard
-            .get_file_by_fd(fd)
-            .ok_or(SystemError::EBADF)?;
-        // drop guard 以避免无法调度的问题
-        drop(fd_table_guard);
-
-        let mut kstat = PosixKstat::new();
-        // 获取文件信息
-        let metadata = file.metadata()?;
-        kstat.size = metadata.size;
-        kstat.dev_id = metadata.dev_id as u64;
-        kstat.inode = metadata.inode_id.into() as u64;
-        kstat.blcok_size = metadata.blk_size as i64;
-        kstat.blocks = metadata.blocks as u64;
-
-        kstat.atime.tv_sec = metadata.atime.tv_sec;
-        kstat.atime.tv_nsec = metadata.atime.tv_nsec;
-        kstat.mtime.tv_sec = metadata.mtime.tv_sec;
-        kstat.mtime.tv_nsec = metadata.mtime.tv_nsec;
-        kstat.ctime.tv_sec = metadata.ctime.tv_sec;
-        kstat.ctime.tv_nsec = metadata.ctime.tv_nsec;
-
-        kstat.nlink = metadata.nlinks as u64;
-        kstat.uid = metadata.uid as i32;
-        kstat.gid = metadata.gid as i32;
-        kstat.rdev = metadata.raw_dev.data() as i64;
-        kstat.mode = metadata.mode;
-        match file.file_type() {
-            FileType::File => kstat.mode.insert(ModeType::S_IFREG),
-            FileType::Dir => kstat.mode.insert(ModeType::S_IFDIR),
-            FileType::BlockDevice => kstat.mode.insert(ModeType::S_IFBLK),
-            FileType::CharDevice => kstat.mode.insert(ModeType::S_IFCHR),
-            FileType::SymLink => kstat.mode.insert(ModeType::S_IFLNK),
-            FileType::Socket => kstat.mode.insert(ModeType::S_IFSOCK),
-            FileType::Pipe => kstat.mode.insert(ModeType::S_IFIFO),
-            FileType::KvmDevice => kstat.mode.insert(ModeType::S_IFCHR),
-            FileType::FramebufferDevice => kstat.mode.insert(ModeType::S_IFCHR),
-        }
-
-        return Ok(kstat);
-    }
-
-    pub fn fstat(fd: i32, usr_kstat: *mut PosixKstat) -> Result<usize, SystemError> {
-        let mut writer = UserBufferWriter::new(usr_kstat, size_of::<PosixKstat>(), true)?;
-        let kstat = Self::do_fstat(fd)?;
-
-        writer.copy_one_to_user(&kstat, 0)?;
-        return Ok(0);
+    #[inline(never)]
+    pub fn fstat(fd: i32, user_stat_ptr: usize) -> Result<usize, SystemError> {
+        Self::newfstat(fd, user_stat_ptr)
     }
 
-    pub fn stat(path: *const u8, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> {
+    pub fn stat(path: *const u8, user_stat_ptr: usize) -> Result<usize, SystemError> {
         let fd = Self::open(
             path,
             FileMode::O_RDONLY.bits(),
             ModeType::empty().bits(),
             true,
         )?;
-        let r = Self::fstat(fd as i32, user_kstat);
+        let r = Self::fstat(fd as i32, user_stat_ptr);
         Self::close(fd).ok();
         return r;
     }
 
-    pub fn lstat(path: *const u8, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> {
+    pub fn lstat(path: *const u8, user_stat_ptr: usize) -> Result<usize, SystemError> {
         let fd = Self::open(
             path,
             FileMode::O_RDONLY.bits(),
             ModeType::empty().bits(),
             false,
         )?;
-        let r = Self::fstat(fd as i32, user_kstat);
+        let r = Self::fstat(fd as i32, user_stat_ptr);
         Self::close(fd).ok();
         return r;
     }
@@ -1393,6 +1345,16 @@ impl Syscall {
         do_newfstatat(dfd, filename_str, user_stat_buf_ptr, flags).map(|_| 0)
     }
 
+    #[inline(never)]
+    pub fn newfstat(fd: i32, user_stat_buf_ptr: usize) -> Result<usize, SystemError> {
+        if user_stat_buf_ptr == 0 {
+            return Err(SystemError::EFAULT);
+        }
+        let stat = vfs_fstat(fd)?;
+        // log::debug!("newfstat fd: {}, stat.size: {:?}",fd,stat.size);
+        super::stat::cp_new_stat(stat, user_stat_buf_ptr).map(|_| 0)
+    }
+
     pub fn mknod(
         path: *const u8,
         mode: ModeType,
@@ -1426,6 +1388,9 @@ impl Syscall {
         let iovecs = unsafe { IoVecs::from_user(iov as *const IoVec, count, false) }?;
 
         let data = iovecs.gather();
+        if ProcessManager::current_pid().data() >= 9 {
+            log::debug!("writev: fd = {}, data.len() = {:?}", fd, data.len());
+        }
 
         Self::write(fd, &data)
     }
@@ -1722,11 +1687,8 @@ impl IoVecs {
                 continue;
             }
 
-            verify_area(
-                VirtAddr::new(iov.iov_base as usize),
-                iovcnt * core::mem::size_of::<IoVec>(),
-            )
-            .map_err(|_| SystemError::EFAULT)?;
+            verify_area(VirtAddr::new(iov.iov_base as usize), iov.iov_len)
+                .map_err(|_| SystemError::EFAULT)?;
 
             slices.push(core::slice::from_raw_parts_mut(iov.iov_base, iov.iov_len));
         }

+ 3 - 13
kernel/src/syscall/mod.rs

@@ -29,7 +29,6 @@ use crate::{
     filesystem::vfs::{
         fcntl::{AtFlags, FcntlCommand},
         file::FileMode,
-        stat::PosixKstat,
         syscall::{ModeType, UtimensFlags},
         MAX_PATHLEN,
     },
@@ -676,14 +675,7 @@ impl Syscall {
             #[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
             SYS_FSTAT => {
                 let fd = args[0] as i32;
-                let kstat: *mut PosixKstat = args[1] as *mut PosixKstat;
-                let vaddr = VirtAddr::new(kstat as usize);
-                // FIXME 由于c中的verify_area与rust中的verify_area重名,所以在引入时加了前缀区分
-                // TODO 应该将用了c版本的verify_area都改为rust的verify_area
-                match verify_area(vaddr, core::mem::size_of::<PosixKstat>()) {
-                    Ok(_) => Self::fstat(fd, kstat),
-                    Err(e) => Err(e),
-                }
+                Self::fstat(fd, args[1])
             }
 
             SYS_FCNTL => {
@@ -789,15 +781,13 @@ impl Syscall {
             #[cfg(target_arch = "x86_64")]
             SYS_LSTAT => {
                 let path = args[0] as *const u8;
-                let kstat = args[1] as *mut PosixKstat;
-                Self::lstat(path, kstat)
+                Self::lstat(path, args[1])
             }
 
             #[cfg(target_arch = "x86_64")]
             SYS_STAT => {
                 let path = args[0] as *const u8;
-                let kstat = args[1] as *mut PosixKstat;
-                Self::stat(path, kstat)
+                Self::stat(path, args[1])
             }
 
             SYS_STATFS => {