11d37ca6dSDonkey Kane use core::ffi::c_void; 282df0a13Shmt use core::mem::size_of; 32dbef785SGnoCiYeH 482df0a13Shmt use alloc::{string::String, sync::Arc, vec::Vec}; 52eab6dd7S曾俊 use log::warn; 691e9d4abSLoGin use system_error::SystemError; 7004e86ffSlogin 81d37ca6dSDonkey Kane use crate::producefs; 96f189d27Slinfeng use crate::syscall::user_access::UserBufferReader; 10004e86ffSlogin use crate::{ 11c566df45SLoGin driver::base::{block::SeekFrom, device::device_number::DeviceNumber}, 121d37ca6dSDonkey Kane filesystem::vfs::{core as Vcore, file::FileDescriptorVec}, 131496ba7bSLoGin libs::rwlock::RwLockWriteGuard, 144fda81ceSLoGin mm::{verify_area, VirtAddr}, 151496ba7bSLoGin process::ProcessManager, 16709498caSLoGin syscall::{ 171d37ca6dSDonkey Kane user_access::{self, check_and_clone_cstr, UserBufferWriter}, 1891e9d4abSLoGin Syscall, 19709498caSLoGin }, 206f189d27Slinfeng time::{syscall::PosixTimeval, PosixTimeSpec}, 21004e86ffSlogin }; 22004e86ffSlogin 23004e86ffSlogin use super::{ 241074eb34SSamuel Dai core::{do_mkdir_at, do_remove_dir, do_unlink_at}, 25709498caSLoGin fcntl::{AtFlags, FcntlCommand, FD_CLOEXEC}, 26004e86ffSlogin file::{File, FileMode}, 276f189d27Slinfeng open::{do_faccessat, do_fchmodat, do_sys_open, do_utimensat, do_utimes}, 289b0abe6dSLoGin utils::{rsplit_path, user_path_at}, 291074eb34SSamuel Dai Dirent, FileType, IndexNode, SuperBlock, FSMAKER, MAX_PATHLEN, ROOT_INODE, 301074eb34SSamuel Dai VFS_MAX_FOLLOW_SYMLINK_TIMES, 31004e86ffSlogin }; 32004e86ffSlogin 33ab5c8ca4Slogin pub const SEEK_SET: u32 = 0; 34ab5c8ca4Slogin pub const SEEK_CUR: u32 = 1; 35ab5c8ca4Slogin pub const SEEK_END: u32 = 2; 36ab5c8ca4Slogin pub const SEEK_MAX: u32 = 3; 37004e86ffSlogin 3867b48188Shoumkh bitflags! { 3967b48188Shoumkh /// 文件类型和权限 406b4e7a29SLoGin #[repr(C)] 4167b48188Shoumkh pub struct ModeType: u32 { 4267b48188Shoumkh /// 掩码 4367b48188Shoumkh const S_IFMT = 0o0_170_000; 4467b48188Shoumkh /// 文件类型 4567b48188Shoumkh const S_IFSOCK = 0o140000; 4667b48188Shoumkh const S_IFLNK = 0o120000; 4767b48188Shoumkh const S_IFREG = 0o100000; 4867b48188Shoumkh const S_IFBLK = 0o060000; 4967b48188Shoumkh const S_IFDIR = 0o040000; 5067b48188Shoumkh const S_IFCHR = 0o020000; 5167b48188Shoumkh const S_IFIFO = 0o010000; 5267b48188Shoumkh 5367b48188Shoumkh const S_ISUID = 0o004000; 5467b48188Shoumkh const S_ISGID = 0o002000; 5567b48188Shoumkh const S_ISVTX = 0o001000; 5667b48188Shoumkh /// 文件用户权限 5767b48188Shoumkh const S_IRWXU = 0o0700; 5867b48188Shoumkh const S_IRUSR = 0o0400; 5967b48188Shoumkh const S_IWUSR = 0o0200; 6067b48188Shoumkh const S_IXUSR = 0o0100; 6167b48188Shoumkh /// 文件组权限 6267b48188Shoumkh const S_IRWXG = 0o0070; 6367b48188Shoumkh const S_IRGRP = 0o0040; 6467b48188Shoumkh const S_IWGRP = 0o0020; 6567b48188Shoumkh const S_IXGRP = 0o0010; 6667b48188Shoumkh /// 文件其他用户权限 6767b48188Shoumkh const S_IRWXO = 0o0007; 6867b48188Shoumkh const S_IROTH = 0o0004; 6967b48188Shoumkh const S_IWOTH = 0o0002; 7067b48188Shoumkh const S_IXOTH = 0o0001; 7106d5e247SLoGin 7206d5e247SLoGin /// 0o777 7306d5e247SLoGin const S_IRWXUGO = Self::S_IRWXU.bits | Self::S_IRWXG.bits | Self::S_IRWXO.bits; 7406d5e247SLoGin /// 0o7777 7506d5e247SLoGin const S_IALLUGO = Self::S_ISUID.bits | Self::S_ISGID.bits | Self::S_ISVTX.bits| Self::S_IRWXUGO.bits; 7606d5e247SLoGin /// 0o444 7706d5e247SLoGin const S_IRUGO = Self::S_IRUSR.bits | Self::S_IRGRP.bits | Self::S_IROTH.bits; 7806d5e247SLoGin /// 0o222 7906d5e247SLoGin const S_IWUGO = Self::S_IWUSR.bits | Self::S_IWGRP.bits | Self::S_IWOTH.bits; 8006d5e247SLoGin /// 0o111 8106d5e247SLoGin const S_IXUGO = Self::S_IXUSR.bits | Self::S_IXGRP.bits | Self::S_IXOTH.bits; 8206d5e247SLoGin 8306d5e247SLoGin 8467b48188Shoumkh } 8567b48188Shoumkh } 8667b48188Shoumkh 8767b48188Shoumkh #[repr(C)] 8882df0a13Shmt #[derive(Clone, Copy)] 8967b48188Shoumkh /// # 文件信息结构体 9067b48188Shoumkh pub struct PosixKstat { 9167b48188Shoumkh /// 硬件设备ID 9267b48188Shoumkh dev_id: u64, 9367b48188Shoumkh /// inode号 9467b48188Shoumkh inode: u64, 9567b48188Shoumkh /// 硬链接数 9667b48188Shoumkh nlink: u64, 9767b48188Shoumkh /// 文件权限 9867b48188Shoumkh mode: ModeType, 9967b48188Shoumkh /// 所有者用户ID 10067b48188Shoumkh uid: i32, 10167b48188Shoumkh /// 所有者组ID 10267b48188Shoumkh gid: i32, 10367b48188Shoumkh /// 设备ID 10467b48188Shoumkh rdev: i64, 10567b48188Shoumkh /// 文件大小 10667b48188Shoumkh size: i64, 10767b48188Shoumkh /// 文件系统块大小 10867b48188Shoumkh blcok_size: i64, 10967b48188Shoumkh /// 分配的512B块数 11067b48188Shoumkh blocks: u64, 11167b48188Shoumkh /// 最后访问时间 1126fc066acSJomo atime: PosixTimeSpec, 11367b48188Shoumkh /// 最后修改时间 1146fc066acSJomo mtime: PosixTimeSpec, 11567b48188Shoumkh /// 最后状态变化时间 1166fc066acSJomo ctime: PosixTimeSpec, 11767b48188Shoumkh /// 用于填充结构体大小的空白数据 11867b48188Shoumkh pub _pad: [i8; 24], 11967b48188Shoumkh } 12067b48188Shoumkh impl PosixKstat { new() -> Self12167b48188Shoumkh fn new() -> Self { 12267b48188Shoumkh Self { 12367b48188Shoumkh inode: 0, 12467b48188Shoumkh dev_id: 0, 12567b48188Shoumkh mode: ModeType { bits: 0 }, 12667b48188Shoumkh nlink: 0, 12767b48188Shoumkh uid: 0, 12867b48188Shoumkh gid: 0, 12967b48188Shoumkh rdev: 0, 13067b48188Shoumkh size: 0, 1316fc066acSJomo atime: PosixTimeSpec { 13267b48188Shoumkh tv_sec: 0, 13367b48188Shoumkh tv_nsec: 0, 13467b48188Shoumkh }, 1356fc066acSJomo mtime: PosixTimeSpec { 13667b48188Shoumkh tv_sec: 0, 13767b48188Shoumkh tv_nsec: 0, 13867b48188Shoumkh }, 1396fc066acSJomo ctime: PosixTimeSpec { 14067b48188Shoumkh tv_sec: 0, 14167b48188Shoumkh tv_nsec: 0, 14267b48188Shoumkh }, 14367b48188Shoumkh blcok_size: 0, 14467b48188Shoumkh blocks: 0, 14567b48188Shoumkh _pad: Default::default(), 14667b48188Shoumkh } 14767b48188Shoumkh } 14867b48188Shoumkh } 1490fb515b0SLoGin 150b4eb05a1STTaq #[repr(C)] 151b4eb05a1STTaq #[derive(Clone, Copy)] 152b4eb05a1STTaq /// # 文件信息结构体X 153b4eb05a1STTaq pub struct PosixStatx { 154b4eb05a1STTaq /* 0x00 */ 155b4eb05a1STTaq stx_mask: PosixStatxMask, 156b4eb05a1STTaq /// 文件系统块大小 157b4eb05a1STTaq stx_blksize: u32, 158b4eb05a1STTaq /// Flags conveying information about the file [uncond] 159b4eb05a1STTaq stx_attributes: StxAttributes, 160b4eb05a1STTaq /* 0x10 */ 161b4eb05a1STTaq /// 硬链接数 162b4eb05a1STTaq stx_nlink: u32, 163b4eb05a1STTaq /// 所有者用户ID 164b4eb05a1STTaq stx_uid: u32, 165b4eb05a1STTaq /// 所有者组ID 166b4eb05a1STTaq stx_gid: u32, 167b4eb05a1STTaq /// 文件权限 168b4eb05a1STTaq stx_mode: ModeType, 169b4eb05a1STTaq 170b4eb05a1STTaq /* 0x20 */ 171b4eb05a1STTaq /// inode号 172b4eb05a1STTaq stx_inode: u64, 173b4eb05a1STTaq /// 文件大小 174b4eb05a1STTaq stx_size: i64, 175b4eb05a1STTaq /// 分配的512B块数 176b4eb05a1STTaq stx_blocks: u64, 177b4eb05a1STTaq /// Mask to show what's supported in stx_attributes 178b4eb05a1STTaq stx_attributes_mask: StxAttributes, 179b4eb05a1STTaq 180b4eb05a1STTaq /* 0x40 */ 181b4eb05a1STTaq /// 最后访问时间 1826fc066acSJomo stx_atime: PosixTimeSpec, 183b4eb05a1STTaq /// 文件创建时间 1846fc066acSJomo stx_btime: PosixTimeSpec, 185b4eb05a1STTaq /// 最后状态变化时间 1866fc066acSJomo stx_ctime: PosixTimeSpec, 187b4eb05a1STTaq /// 最后修改时间 1886fc066acSJomo stx_mtime: PosixTimeSpec, 189b4eb05a1STTaq 190b4eb05a1STTaq /* 0x80 */ 191b4eb05a1STTaq /// 主设备ID 192b4eb05a1STTaq stx_rdev_major: u32, 193b4eb05a1STTaq /// 次设备ID 194b4eb05a1STTaq stx_rdev_minor: u32, 195b4eb05a1STTaq /// 主硬件设备ID 196b4eb05a1STTaq stx_dev_major: u32, 197b4eb05a1STTaq /// 次硬件设备ID 198b4eb05a1STTaq stx_dev_minor: u32, 199b4eb05a1STTaq 200b4eb05a1STTaq /* 0x90 */ 201b4eb05a1STTaq stx_mnt_id: u64, 202b4eb05a1STTaq stx_dio_mem_align: u32, 203b4eb05a1STTaq stx_dio_offset_align: u32, 204b4eb05a1STTaq } 205b4eb05a1STTaq impl PosixStatx { new() -> Self206b4eb05a1STTaq fn new() -> Self { 207b4eb05a1STTaq Self { 208b4eb05a1STTaq stx_mask: PosixStatxMask::STATX_BASIC_STATS, 209b4eb05a1STTaq stx_blksize: 0, 210b4eb05a1STTaq stx_attributes: StxAttributes::STATX_ATTR_APPEND, 211b4eb05a1STTaq stx_nlink: 0, 212b4eb05a1STTaq stx_uid: 0, 213b4eb05a1STTaq stx_gid: 0, 214b4eb05a1STTaq stx_mode: ModeType { bits: 0 }, 215b4eb05a1STTaq stx_inode: 0, 216b4eb05a1STTaq stx_size: 0, 217b4eb05a1STTaq stx_blocks: 0, 218b4eb05a1STTaq stx_attributes_mask: StxAttributes::STATX_ATTR_APPEND, 2196fc066acSJomo stx_atime: PosixTimeSpec { 220b4eb05a1STTaq tv_sec: 0, 221b4eb05a1STTaq tv_nsec: 0, 222b4eb05a1STTaq }, 2236fc066acSJomo stx_btime: PosixTimeSpec { 224b4eb05a1STTaq tv_sec: 0, 225b4eb05a1STTaq tv_nsec: 0, 226b4eb05a1STTaq }, 2276fc066acSJomo stx_ctime: PosixTimeSpec { 228b4eb05a1STTaq tv_sec: 0, 229b4eb05a1STTaq tv_nsec: 0, 230b4eb05a1STTaq }, 2316fc066acSJomo stx_mtime: PosixTimeSpec { 232b4eb05a1STTaq tv_sec: 0, 233b4eb05a1STTaq tv_nsec: 0, 234b4eb05a1STTaq }, 235b4eb05a1STTaq stx_rdev_major: 0, 236b4eb05a1STTaq stx_rdev_minor: 0, 237b4eb05a1STTaq stx_dev_major: 0, 238b4eb05a1STTaq stx_dev_minor: 0, 239b4eb05a1STTaq stx_mnt_id: 0, 240b4eb05a1STTaq stx_dio_mem_align: 0, 241b4eb05a1STTaq stx_dio_offset_align: 0, 242b4eb05a1STTaq } 243b4eb05a1STTaq } 244b4eb05a1STTaq } 245b4eb05a1STTaq 246b4eb05a1STTaq bitflags! { 247b4eb05a1STTaq pub struct PosixStatxMask: u32{ 248b4eb05a1STTaq /// Want stx_mode & S_IFMT 249b4eb05a1STTaq const STATX_TYPE = 0x00000001; 250b4eb05a1STTaq 251b4eb05a1STTaq /// Want stx_mode & ~S_IFMT 252b4eb05a1STTaq const STATX_MODE = 0x00000002; 253b4eb05a1STTaq 254b4eb05a1STTaq /// Want stx_nlink 255b4eb05a1STTaq const STATX_NLINK = 0x00000004; 256b4eb05a1STTaq 257b4eb05a1STTaq /// Want stx_uid 258b4eb05a1STTaq const STATX_UID = 0x00000008; 259b4eb05a1STTaq 260b4eb05a1STTaq /// Want stx_gid 261b4eb05a1STTaq const STATX_GID = 0x00000010; 262b4eb05a1STTaq 263b4eb05a1STTaq /// Want stx_atime 264b4eb05a1STTaq const STATX_ATIME = 0x00000020; 265b4eb05a1STTaq 266b4eb05a1STTaq /// Want stx_mtime 267b4eb05a1STTaq const STATX_MTIME = 0x00000040; 268b4eb05a1STTaq 269b4eb05a1STTaq /// Want stx_ctime 270b4eb05a1STTaq const STATX_CTIME = 0x00000080; 271b4eb05a1STTaq 272b4eb05a1STTaq /// Want stx_ino 273b4eb05a1STTaq const STATX_INO = 0x00000100; 274b4eb05a1STTaq 275b4eb05a1STTaq /// Want stx_size 276b4eb05a1STTaq const STATX_SIZE = 0x00000200; 277b4eb05a1STTaq 278b4eb05a1STTaq /// Want stx_blocks 279b4eb05a1STTaq const STATX_BLOCKS = 0x00000400; 280b4eb05a1STTaq 281b4eb05a1STTaq /// [All of the above] 282b4eb05a1STTaq const STATX_BASIC_STATS = 0x000007ff; 283b4eb05a1STTaq 284b4eb05a1STTaq /// Want stx_btime 285b4eb05a1STTaq const STATX_BTIME = 0x00000800; 286b4eb05a1STTaq 287b4eb05a1STTaq /// The same as STATX_BASIC_STATS | STATX_BTIME. 288b4eb05a1STTaq /// It is deprecated and should not be used. 289b4eb05a1STTaq const STATX_ALL = 0x00000fff; 290b4eb05a1STTaq 291b4eb05a1STTaq /// Want stx_mnt_id (since Linux 5.8) 292b4eb05a1STTaq const STATX_MNT_ID = 0x00001000; 293b4eb05a1STTaq 294b4eb05a1STTaq /// Want stx_dio_mem_align and stx_dio_offset_align 295b4eb05a1STTaq /// (since Linux 6.1; support varies by filesystem) 296b4eb05a1STTaq const STATX_DIOALIGN = 0x00002000; 297b4eb05a1STTaq 298b4eb05a1STTaq /// Reserved for future struct statx expansion 299b4eb05a1STTaq const STATX_RESERVED = 0x80000000; 300b4eb05a1STTaq } 301b4eb05a1STTaq } 302b4eb05a1STTaq 303b4eb05a1STTaq bitflags! { 304b4eb05a1STTaq pub struct StxAttributes: u64 { 305b4eb05a1STTaq /// 文件被文件系统压缩 306b4eb05a1STTaq const STATX_ATTR_COMPRESSED = 0x00000004; 307b4eb05a1STTaq /// 文件被标记为不可修改 308b4eb05a1STTaq const STATX_ATTR_IMMUTABLE = 0x00000010; 309b4eb05a1STTaq /// 文件是只追加写入的 310b4eb05a1STTaq const STATX_ATTR_APPEND = 0x00000020; 311b4eb05a1STTaq /// 文件不会被备份 312b4eb05a1STTaq const STATX_ATTR_NODUMP = 0x00000040; 313b4eb05a1STTaq /// 文件需要密钥才能在文件系统中解密 314b4eb05a1STTaq const STATX_ATTR_ENCRYPTED = 0x00000800; 315b4eb05a1STTaq /// 目录是自动挂载触发器 316b4eb05a1STTaq const STATX_ATTR_AUTOMOUNT = 0x00001000; 317b4eb05a1STTaq /// 目录是挂载点的根目录 318b4eb05a1STTaq const STATX_ATTR_MOUNT_ROOT = 0x00002000; 319b4eb05a1STTaq /// 文件受到 Verity 保护 320b4eb05a1STTaq const STATX_ATTR_VERITY = 0x00100000; 321b4eb05a1STTaq /// 文件当前处于 DAX 状态 CPU直接访问 322b4eb05a1STTaq const STATX_ATTR_DAX = 0x00200000; 323b4eb05a1STTaq } 324b4eb05a1STTaq } 325b4eb05a1STTaq 3266f189d27Slinfeng bitflags! { 3276f189d27Slinfeng pub struct UtimensFlags: u32 { 3286f189d27Slinfeng /// 不需要解释符号链接 3296f189d27Slinfeng const AT_SYMLINK_NOFOLLOW = 0x100; 3306f189d27Slinfeng } 3316f189d27Slinfeng } 3326f189d27Slinfeng 333597ecc08STTaq #[repr(C)] 334597ecc08STTaq #[derive(Debug, Clone, Copy)] 335597ecc08STTaq pub struct PosixStatfs { 336597ecc08STTaq f_type: u64, 337597ecc08STTaq f_bsize: u64, 338597ecc08STTaq f_blocks: u64, 339597ecc08STTaq f_bfree: u64, 340597ecc08STTaq f_bavail: u64, 341597ecc08STTaq f_files: u64, 342597ecc08STTaq f_ffree: u64, 343597ecc08STTaq f_fsid: u64, 344597ecc08STTaq f_namelen: u64, 345597ecc08STTaq f_frsize: u64, 346597ecc08STTaq f_flags: u64, 347597ecc08STTaq f_spare: [u64; 4], 348597ecc08STTaq } 349597ecc08STTaq 350597ecc08STTaq impl From<SuperBlock> for PosixStatfs { from(super_block: SuperBlock) -> Self351597ecc08STTaq fn from(super_block: SuperBlock) -> Self { 352597ecc08STTaq Self { 353597ecc08STTaq f_type: super_block.magic.bits, 354597ecc08STTaq f_bsize: super_block.bsize, 355597ecc08STTaq f_blocks: super_block.blocks, 356597ecc08STTaq f_bfree: super_block.bfree, 357597ecc08STTaq f_bavail: super_block.bavail, 358597ecc08STTaq f_files: super_block.files, 359597ecc08STTaq f_ffree: super_block.ffree, 360597ecc08STTaq f_fsid: super_block.fsid, 361597ecc08STTaq f_namelen: super_block.namelen, 362597ecc08STTaq f_frsize: super_block.frsize, 363597ecc08STTaq f_flags: super_block.flags, 364597ecc08STTaq f_spare: [0u64; 4], 365597ecc08STTaq } 366597ecc08STTaq } 367597ecc08STTaq } 3680fb515b0SLoGin /// 3690fb515b0SLoGin /// Arguments for how openat2(2) should open the target path. If only @flags and 3700fb515b0SLoGin /// @mode are non-zero, then openat2(2) operates very similarly to openat(2). 3710fb515b0SLoGin /// 3720fb515b0SLoGin /// However, unlike openat(2), unknown or invalid bits in @flags result in 3730fb515b0SLoGin /// -EINVAL rather than being silently ignored. @mode must be zero unless one of 3740fb515b0SLoGin /// {O_CREAT, O_TMPFILE} are set. 3750fb515b0SLoGin /// 3760fb515b0SLoGin /// ## 成员变量 3770fb515b0SLoGin /// 3780fb515b0SLoGin /// - flags: O_* flags. 3790fb515b0SLoGin /// - mode: O_CREAT/O_TMPFILE file mode. 3800fb515b0SLoGin /// - resolve: RESOLVE_* flags. 3810fb515b0SLoGin #[derive(Debug, Clone, Copy)] 3820fb515b0SLoGin #[repr(C)] 3830fb515b0SLoGin pub struct PosixOpenHow { 3840fb515b0SLoGin pub flags: u64, 3850fb515b0SLoGin pub mode: u64, 3860fb515b0SLoGin pub resolve: u64, 3870fb515b0SLoGin } 3880fb515b0SLoGin 3890fb515b0SLoGin impl PosixOpenHow { 3900fb515b0SLoGin #[allow(dead_code)] new(flags: u64, mode: u64, resolve: u64) -> Self3910fb515b0SLoGin pub fn new(flags: u64, mode: u64, resolve: u64) -> Self { 3920fb515b0SLoGin Self { 3930fb515b0SLoGin flags, 3940fb515b0SLoGin mode, 3950fb515b0SLoGin resolve, 3960fb515b0SLoGin } 3970fb515b0SLoGin } 3980fb515b0SLoGin } 3990fb515b0SLoGin 400bd70d2d1SLoGin #[allow(dead_code)] 4010fb515b0SLoGin #[derive(Debug, Clone, Copy)] 4020fb515b0SLoGin pub struct OpenHow { 4030fb515b0SLoGin pub o_flags: FileMode, 4040fb515b0SLoGin pub mode: ModeType, 4050fb515b0SLoGin pub resolve: OpenHowResolve, 4060fb515b0SLoGin } 4070fb515b0SLoGin 4080fb515b0SLoGin impl OpenHow { new(mut o_flags: FileMode, mut mode: ModeType, resolve: OpenHowResolve) -> Self4090fb515b0SLoGin pub fn new(mut o_flags: FileMode, mut mode: ModeType, resolve: OpenHowResolve) -> Self { 4100fb515b0SLoGin if !o_flags.contains(FileMode::O_CREAT) { 4110fb515b0SLoGin mode = ModeType::empty(); 4120fb515b0SLoGin } 4130fb515b0SLoGin 4140fb515b0SLoGin if o_flags.contains(FileMode::O_PATH) { 4150fb515b0SLoGin o_flags = o_flags.intersection(FileMode::O_PATH_FLAGS); 4160fb515b0SLoGin } 4170fb515b0SLoGin 4180fb515b0SLoGin Self { 4190fb515b0SLoGin o_flags, 4200fb515b0SLoGin mode, 4210fb515b0SLoGin resolve, 4220fb515b0SLoGin } 4230fb515b0SLoGin } 4240fb515b0SLoGin } 4250fb515b0SLoGin 4260fb515b0SLoGin impl From<PosixOpenHow> for OpenHow { from(posix_open_how: PosixOpenHow) -> Self4270fb515b0SLoGin fn from(posix_open_how: PosixOpenHow) -> Self { 4280fb515b0SLoGin let o_flags = FileMode::from_bits_truncate(posix_open_how.flags as u32); 4290fb515b0SLoGin let mode = ModeType::from_bits_truncate(posix_open_how.mode as u32); 430b5b571e0SLoGin let resolve = OpenHowResolve::from_bits_truncate(posix_open_how.resolve); 4310fb515b0SLoGin return Self::new(o_flags, mode, resolve); 4320fb515b0SLoGin } 4330fb515b0SLoGin } 4340fb515b0SLoGin 4350fb515b0SLoGin bitflags! { 4360fb515b0SLoGin pub struct OpenHowResolve: u64{ 4370fb515b0SLoGin /// Block mount-point crossings 4380fb515b0SLoGin /// (including bind-mounts). 4390fb515b0SLoGin const RESOLVE_NO_XDEV = 0x01; 4400fb515b0SLoGin 4410fb515b0SLoGin /// Block traversal through procfs-style 4420fb515b0SLoGin /// "magic-links" 4430fb515b0SLoGin const RESOLVE_NO_MAGICLINKS = 0x02; 4440fb515b0SLoGin 4450fb515b0SLoGin /// Block traversal through all symlinks 4460fb515b0SLoGin /// (implies OEXT_NO_MAGICLINKS) 4470fb515b0SLoGin const RESOLVE_NO_SYMLINKS = 0x04; 4480fb515b0SLoGin /// Block "lexical" trickery like 4490fb515b0SLoGin /// "..", symlinks, and absolute 4500fb515b0SLoGin const RESOLVE_BENEATH = 0x08; 4510fb515b0SLoGin /// Make all jumps to "/" and ".." 4520fb515b0SLoGin /// be scoped inside the dirfd 4530fb515b0SLoGin /// (similar to chroot(2)). 4540fb515b0SLoGin const RESOLVE_IN_ROOT = 0x10; 4550fb515b0SLoGin // Only complete if resolution can be 4560fb515b0SLoGin // completed through cached lookup. May 4570fb515b0SLoGin // return -EAGAIN if that's not 4580fb515b0SLoGin // possible. 4590fb515b0SLoGin const RESOLVE_CACHED = 0x20; 4600fb515b0SLoGin } 4610fb515b0SLoGin } 4621074eb34SSamuel Dai 4631074eb34SSamuel Dai bitflags! { 4641074eb34SSamuel Dai pub struct UmountFlag: i32 { 4651074eb34SSamuel Dai const DEFAULT = 0; /* Default call to umount. */ 4661074eb34SSamuel Dai const MNT_FORCE = 1; /* Force unmounting. */ 4671074eb34SSamuel Dai const MNT_DETACH = 2; /* Just detach from the tree. */ 4681074eb34SSamuel Dai const MNT_EXPIRE = 4; /* Mark for expiry. */ 4691074eb34SSamuel Dai const UMOUNT_NOFOLLOW = 8; /* Don't follow symlink on umount. */ 4701074eb34SSamuel Dai } 4711074eb34SSamuel Dai } 4721074eb34SSamuel Dai 473ab5c8ca4Slogin impl Syscall { 474ab5c8ca4Slogin /// @brief 为当前进程打开一个文件 475ab5c8ca4Slogin /// 476ab5c8ca4Slogin /// @param path 文件路径 477ab5c8ca4Slogin /// @param o_flags 打开文件的标志位 478ab5c8ca4Slogin /// 479ab5c8ca4Slogin /// @return 文件描述符编号,或者是错误码 open( path: *const u8, o_flags: u32, mode: u32, follow_symlink: bool, ) -> Result<usize, SystemError>4800fb515b0SLoGin pub fn open( 48182df0a13Shmt path: *const u8, 48282df0a13Shmt o_flags: u32, 48382df0a13Shmt mode: u32, 4840fb515b0SLoGin follow_symlink: bool, 4850fb515b0SLoGin ) -> Result<usize, SystemError> { 486703ce5a7SLoGin let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))? 487703ce5a7SLoGin .into_string() 488703ce5a7SLoGin .map_err(|_| SystemError::EINVAL)?; 489703ce5a7SLoGin 49082df0a13Shmt let open_flags: FileMode = FileMode::from_bits(o_flags).ok_or(SystemError::EINVAL)?; 491b5b571e0SLoGin let mode = ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?; 49282df0a13Shmt return do_sys_open( 49382df0a13Shmt AtFlags::AT_FDCWD.bits(), 49482df0a13Shmt &path, 49582df0a13Shmt open_flags, 49682df0a13Shmt mode, 49782df0a13Shmt follow_symlink, 49882df0a13Shmt ); 499ab5c8ca4Slogin } 500ab5c8ca4Slogin openat( dirfd: i32, path: *const u8, o_flags: u32, mode: u32, follow_symlink: bool, ) -> Result<usize, SystemError>5010fb515b0SLoGin pub fn openat( 5020fb515b0SLoGin dirfd: i32, 50382df0a13Shmt path: *const u8, 50482df0a13Shmt o_flags: u32, 50582df0a13Shmt mode: u32, 5060fb515b0SLoGin follow_symlink: bool, 5070fb515b0SLoGin ) -> Result<usize, SystemError> { 508703ce5a7SLoGin let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))? 509703ce5a7SLoGin .into_string() 510703ce5a7SLoGin .map_err(|_| SystemError::EINVAL)?; 511703ce5a7SLoGin 51282df0a13Shmt let open_flags: FileMode = FileMode::from_bits(o_flags).ok_or(SystemError::EINVAL)?; 513b5b571e0SLoGin let mode = ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?; 51482df0a13Shmt return do_sys_open(dirfd, &path, open_flags, mode, follow_symlink); 515ab5c8ca4Slogin } 516ab5c8ca4Slogin 517ab5c8ca4Slogin /// @brief 关闭文件 518ab5c8ca4Slogin /// 519ab5c8ca4Slogin /// @param fd 文件描述符编号 520ab5c8ca4Slogin /// 521ab5c8ca4Slogin /// @return 成功返回0,失败返回错误码 close(fd: usize) -> Result<usize, SystemError>522ab5c8ca4Slogin pub fn close(fd: usize) -> Result<usize, SystemError> { 5231496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 5241496ba7bSLoGin let mut fd_table_guard = binding.write(); 525*4afc5b7bSlinfeng let _file = fd_table_guard.drop_fd(fd as i32)?; 526*4afc5b7bSlinfeng drop(fd_table_guard); 527*4afc5b7bSlinfeng Ok(0) 528ab5c8ca4Slogin } 529ab5c8ca4Slogin 53040314b30SXiaoye Zheng /// @brief 发送命令到文件描述符对应的设备, 53140314b30SXiaoye Zheng /// 53240314b30SXiaoye Zheng /// @param fd 文件描述符编号 53340314b30SXiaoye Zheng /// @param cmd 设备相关的请求类型 53440314b30SXiaoye Zheng /// 53540314b30SXiaoye Zheng /// @return Ok(usize) 成功返回0 53640314b30SXiaoye Zheng /// @return Err(SystemError) 读取失败,返回posix错误码 ioctl(fd: usize, cmd: u32, data: usize) -> Result<usize, SystemError>53740314b30SXiaoye Zheng pub fn ioctl(fd: usize, cmd: u32, data: usize) -> Result<usize, SystemError> { 53840314b30SXiaoye Zheng let binding = ProcessManager::current_pcb().fd_table(); 53940314b30SXiaoye Zheng let fd_table_guard = binding.read(); 54040314b30SXiaoye Zheng 54140314b30SXiaoye Zheng let file = fd_table_guard 54240314b30SXiaoye Zheng .get_file_by_fd(fd as i32) 54340314b30SXiaoye Zheng .ok_or(SystemError::EBADF)?; 54440314b30SXiaoye Zheng 54540314b30SXiaoye Zheng // drop guard 以避免无法调度的问题 54640314b30SXiaoye Zheng drop(fd_table_guard); 547dfe53cf0SGnoCiYeH let r = file.inode().ioctl(cmd, data, &file.private_data.lock()); 54840314b30SXiaoye Zheng return r; 54940314b30SXiaoye Zheng } 55040314b30SXiaoye Zheng 551ab5c8ca4Slogin /// @brief 根据文件描述符,读取文件数据。尝试读取的数据长度与buf的长度相同。 552ab5c8ca4Slogin /// 553ab5c8ca4Slogin /// @param fd 文件描述符编号 55427b967a3S裕依 /// @param buf 输出缓冲区 555ab5c8ca4Slogin /// 556ab5c8ca4Slogin /// @return Ok(usize) 成功读取的数据的字节数 557ab5c8ca4Slogin /// @return Err(SystemError) 读取失败,返回posix错误码 read(fd: i32, buf: &mut [u8]) -> Result<usize, SystemError>558ab5c8ca4Slogin pub fn read(fd: i32, buf: &mut [u8]) -> Result<usize, SystemError> { 5591496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 5601496ba7bSLoGin let fd_table_guard = binding.read(); 5611496ba7bSLoGin 5621496ba7bSLoGin let file = fd_table_guard.get_file_by_fd(fd); 563ab5c8ca4Slogin if file.is_none() { 564ab5c8ca4Slogin return Err(SystemError::EBADF); 565ab5c8ca4Slogin } 5661496ba7bSLoGin // drop guard 以避免无法调度的问题 5671496ba7bSLoGin drop(fd_table_guard); 5681496ba7bSLoGin let file = file.unwrap(); 569ab5c8ca4Slogin 570dfe53cf0SGnoCiYeH return file.read(buf.len(), buf); 571ab5c8ca4Slogin } 572ab5c8ca4Slogin 573ab5c8ca4Slogin /// @brief 根据文件描述符,向文件写入数据。尝试写入的数据长度与buf的长度相同。 574ab5c8ca4Slogin /// 575ab5c8ca4Slogin /// @param fd 文件描述符编号 57627b967a3S裕依 /// @param buf 输入缓冲区 577ab5c8ca4Slogin /// 578ab5c8ca4Slogin /// @return Ok(usize) 成功写入的数据的字节数 579ab5c8ca4Slogin /// @return Err(SystemError) 写入失败,返回posix错误码 write(fd: i32, buf: &[u8]) -> Result<usize, SystemError>580ab5c8ca4Slogin pub fn write(fd: i32, buf: &[u8]) -> Result<usize, SystemError> { 5811496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 5821496ba7bSLoGin let fd_table_guard = binding.read(); 583ab5c8ca4Slogin 5841496ba7bSLoGin let file = fd_table_guard 5851496ba7bSLoGin .get_file_by_fd(fd) 5861496ba7bSLoGin .ok_or(SystemError::EBADF)?; 5871496ba7bSLoGin 5881496ba7bSLoGin // drop guard 以避免无法调度的问题 5891496ba7bSLoGin drop(fd_table_guard); 590dfe53cf0SGnoCiYeH return file.write(buf.len(), buf); 591ab5c8ca4Slogin } 592ab5c8ca4Slogin 593ab5c8ca4Slogin /// @brief 调整文件操作指针的位置 594ab5c8ca4Slogin /// 595ab5c8ca4Slogin /// @param fd 文件描述符编号 596ab5c8ca4Slogin /// @param seek 调整的方式 597ab5c8ca4Slogin /// 598ab5c8ca4Slogin /// @return Ok(usize) 调整后,文件访问指针相对于文件头部的偏移量 599ab5c8ca4Slogin /// @return Err(SystemError) 调整失败,返回posix错误码 lseek(fd: i32, offset: i64, seek: u32) -> Result<usize, SystemError>60082df0a13Shmt pub fn lseek(fd: i32, offset: i64, seek: u32) -> Result<usize, SystemError> { 60182df0a13Shmt let seek = match seek { 60282df0a13Shmt SEEK_SET => Ok(SeekFrom::SeekSet(offset)), 60382df0a13Shmt SEEK_CUR => Ok(SeekFrom::SeekCurrent(offset)), 60482df0a13Shmt SEEK_END => Ok(SeekFrom::SeekEnd(offset)), 60582df0a13Shmt SEEK_MAX => Ok(SeekFrom::SeekEnd(0)), 60682df0a13Shmt _ => Err(SystemError::EINVAL), 60782df0a13Shmt }?; 60882df0a13Shmt 6091496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 6101496ba7bSLoGin let fd_table_guard = binding.read(); 6111496ba7bSLoGin let file = fd_table_guard 6121496ba7bSLoGin .get_file_by_fd(fd) 6131496ba7bSLoGin .ok_or(SystemError::EBADF)?; 6141496ba7bSLoGin 6151496ba7bSLoGin // drop guard 以避免无法调度的问题 6161496ba7bSLoGin drop(fd_table_guard); 617dfe53cf0SGnoCiYeH return file.lseek(seek); 618004e86ffSlogin } 619004e86ffSlogin 62027b967a3S裕依 /// # sys_pread64 系统调用的实际执行函数 62127b967a3S裕依 /// 62227b967a3S裕依 /// ## 参数 62327b967a3S裕依 /// - `fd`: 文件描述符 62427b967a3S裕依 /// - `buf`: 读出缓冲区 62527b967a3S裕依 /// - `len`: 要读取的字节数 62627b967a3S裕依 /// - `offset`: 文件偏移量 pread(fd: i32, buf: &mut [u8], len: usize, offset: usize) -> Result<usize, SystemError>62727b967a3S裕依 pub fn pread(fd: i32, buf: &mut [u8], len: usize, offset: usize) -> Result<usize, SystemError> { 62827b967a3S裕依 let binding = ProcessManager::current_pcb().fd_table(); 62927b967a3S裕依 let fd_table_guard = binding.read(); 63027b967a3S裕依 63127b967a3S裕依 let file = fd_table_guard.get_file_by_fd(fd); 63227b967a3S裕依 if file.is_none() { 63327b967a3S裕依 return Err(SystemError::EBADF); 63427b967a3S裕依 } 63527b967a3S裕依 // drop guard 以避免无法调度的问题 63627b967a3S裕依 drop(fd_table_guard); 63727b967a3S裕依 let file = file.unwrap(); 63827b967a3S裕依 639dfe53cf0SGnoCiYeH return file.pread(offset, len, buf); 64027b967a3S裕依 } 64127b967a3S裕依 64227b967a3S裕依 /// # sys_pwrite64 系统调用的实际执行函数 64327b967a3S裕依 /// 64427b967a3S裕依 /// ## 参数 64527b967a3S裕依 /// - `fd`: 文件描述符 64627b967a3S裕依 /// - `buf`: 写入缓冲区 64727b967a3S裕依 /// - `len`: 要写入的字节数 64827b967a3S裕依 /// - `offset`: 文件偏移量 pwrite(fd: i32, buf: &[u8], len: usize, offset: usize) -> Result<usize, SystemError>64927b967a3S裕依 pub fn pwrite(fd: i32, buf: &[u8], len: usize, offset: usize) -> Result<usize, SystemError> { 65027b967a3S裕依 let binding = ProcessManager::current_pcb().fd_table(); 65127b967a3S裕依 let fd_table_guard = binding.read(); 65227b967a3S裕依 65327b967a3S裕依 let file = fd_table_guard.get_file_by_fd(fd); 65427b967a3S裕依 if file.is_none() { 65527b967a3S裕依 return Err(SystemError::EBADF); 65627b967a3S裕依 } 65727b967a3S裕依 // drop guard 以避免无法调度的问题 65827b967a3S裕依 drop(fd_table_guard); 65927b967a3S裕依 let file = file.unwrap(); 66027b967a3S裕依 661dfe53cf0SGnoCiYeH return file.pwrite(offset, len, buf); 66227b967a3S裕依 } 66327b967a3S裕依 664004e86ffSlogin /// @brief 切换工作目录 665004e86ffSlogin /// 666004e86ffSlogin /// @param dest_path 目标路径 667004e86ffSlogin /// 668004e86ffSlogin /// @return 返回码 描述 669004e86ffSlogin /// 0 | 成功 670004e86ffSlogin /// 671004e86ffSlogin /// EACCESS | 权限不足 672004e86ffSlogin /// 673004e86ffSlogin /// ELOOP | 解析path时遇到路径循环 674004e86ffSlogin /// 675004e86ffSlogin /// ENAMETOOLONG | 路径名过长 676004e86ffSlogin /// 677004e86ffSlogin /// ENOENT | 目标文件或目录不存在 678004e86ffSlogin /// 679004e86ffSlogin /// ENODIR | 检索期间发现非目录项 680004e86ffSlogin /// 681004e86ffSlogin /// ENOMEM | 系统内存不足 682004e86ffSlogin /// 683004e86ffSlogin /// EFAULT | 错误的地址 684004e86ffSlogin /// 685004e86ffSlogin /// ENAMETOOLONG | 路径过长 chdir(path: *const u8) -> Result<usize, SystemError>68682df0a13Shmt pub fn chdir(path: *const u8) -> Result<usize, SystemError> { 68782df0a13Shmt if path.is_null() { 68882df0a13Shmt return Err(SystemError::EFAULT); 68982df0a13Shmt } 69082df0a13Shmt 691703ce5a7SLoGin let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))? 692703ce5a7SLoGin .into_string() 693703ce5a7SLoGin .map_err(|_| SystemError::EINVAL)?; 694703ce5a7SLoGin 6951496ba7bSLoGin let proc = ProcessManager::current_pcb(); 696ab5c8ca4Slogin // Copy path to kernel space to avoid some security issues 6971496ba7bSLoGin let mut new_path = String::from(""); 698b5b571e0SLoGin if !path.is_empty() { 6991496ba7bSLoGin let cwd = match path.as_bytes()[0] { 7001496ba7bSLoGin b'/' => String::from("/"), 7011496ba7bSLoGin _ => proc.basic().cwd(), 7021496ba7bSLoGin }; 703b5b571e0SLoGin let mut cwd_vec: Vec<_> = cwd.split('/').filter(|&x| !x.is_empty()).collect(); 704b5b571e0SLoGin let path_split = path.split('/').filter(|&x| !x.is_empty()); 7051496ba7bSLoGin for seg in path_split { 7061496ba7bSLoGin if seg == ".." { 7071496ba7bSLoGin cwd_vec.pop(); 7081496ba7bSLoGin } else if seg == "." { 7091496ba7bSLoGin // 当前目录 7101496ba7bSLoGin } else { 7111496ba7bSLoGin cwd_vec.push(seg); 7121496ba7bSLoGin } 7131496ba7bSLoGin } 7141496ba7bSLoGin //proc.basic().set_path(String::from("")); 7151496ba7bSLoGin for seg in cwd_vec { 716b5b571e0SLoGin new_path.push('/'); 7171496ba7bSLoGin new_path.push_str(seg); 7181496ba7bSLoGin } 719b5b571e0SLoGin if new_path.is_empty() { 7201496ba7bSLoGin new_path = String::from("/"); 7211496ba7bSLoGin } 7221496ba7bSLoGin } 723a03c4f9dSLoGin let inode = 724a03c4f9dSLoGin match ROOT_INODE().lookup_follow_symlink(&new_path, VFS_MAX_FOLLOW_SYMLINK_TIMES) { 72582df0a13Shmt Err(_) => { 726ab5c8ca4Slogin return Err(SystemError::ENOENT); 727004e86ffSlogin } 728004e86ffSlogin Ok(i) => i, 729004e86ffSlogin }; 7301496ba7bSLoGin let metadata = inode.metadata()?; 7311496ba7bSLoGin if metadata.file_type == FileType::Dir { 732b5b571e0SLoGin proc.basic_mut().set_cwd(new_path); 733ab5c8ca4Slogin return Ok(0); 734004e86ffSlogin } else { 735ab5c8ca4Slogin return Err(SystemError::ENOTDIR); 736004e86ffSlogin } 737004e86ffSlogin } 7381496ba7bSLoGin 7391496ba7bSLoGin /// @brief 获取当前进程的工作目录路径 7401496ba7bSLoGin /// 7411496ba7bSLoGin /// @param buf 指向缓冲区的指针 7421496ba7bSLoGin /// @param size 缓冲区的大小 7431496ba7bSLoGin /// 7441496ba7bSLoGin /// @return 成功,返回的指针指向包含工作目录路径的字符串 7451496ba7bSLoGin /// @return 错误,没有足够的空间 getcwd(buf: &mut [u8]) -> Result<VirtAddr, SystemError>7461496ba7bSLoGin pub fn getcwd(buf: &mut [u8]) -> Result<VirtAddr, SystemError> { 7471496ba7bSLoGin let proc = ProcessManager::current_pcb(); 7481496ba7bSLoGin let cwd = proc.basic().cwd(); 7491496ba7bSLoGin 7501496ba7bSLoGin let cwd_bytes = cwd.as_bytes(); 7511496ba7bSLoGin let cwd_len = cwd_bytes.len(); 7521496ba7bSLoGin if cwd_len + 1 > buf.len() { 7531496ba7bSLoGin return Err(SystemError::ENOMEM); 754004e86ffSlogin } 7551496ba7bSLoGin buf[..cwd_len].copy_from_slice(cwd_bytes); 7561496ba7bSLoGin buf[cwd_len] = 0; 7571496ba7bSLoGin 7581496ba7bSLoGin return Ok(VirtAddr::new(buf.as_ptr() as usize)); 759004e86ffSlogin } 760004e86ffSlogin 761004e86ffSlogin /// @brief 获取目录中的数据 762004e86ffSlogin /// 763ab5c8ca4Slogin /// TODO: 这个函数的语义与Linux不一致,需要修改!!! 764ab5c8ca4Slogin /// 765004e86ffSlogin /// @param fd 文件描述符号 766ab5c8ca4Slogin /// @param buf 输出缓冲区 767ab5c8ca4Slogin /// 768ab5c8ca4Slogin /// @return 成功返回读取的字节数,失败返回错误码 getdents(fd: i32, buf: &mut [u8]) -> Result<usize, SystemError>769ab5c8ca4Slogin pub fn getdents(fd: i32, buf: &mut [u8]) -> Result<usize, SystemError> { 770ab5c8ca4Slogin let dirent = 771ab5c8ca4Slogin unsafe { (buf.as_mut_ptr() as *mut Dirent).as_mut() }.ok_or(SystemError::EFAULT)?; 772004e86ffSlogin 77346e234aeSLoGin if fd < 0 || fd as usize > FileDescriptorVec::PROCESS_MAX_FD { 774ab5c8ca4Slogin return Err(SystemError::EBADF); 775004e86ffSlogin } 776004e86ffSlogin 777004e86ffSlogin // 获取fd 7781496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 7791496ba7bSLoGin let fd_table_guard = binding.read(); 7801496ba7bSLoGin let file = fd_table_guard 7811496ba7bSLoGin .get_file_by_fd(fd) 7821496ba7bSLoGin .ok_or(SystemError::EBADF)?; 783004e86ffSlogin 7841496ba7bSLoGin // drop guard 以避免无法调度的问题 7851496ba7bSLoGin drop(fd_table_guard); 78634e6d6c8Syuyi2439 787dfe53cf0SGnoCiYeH let res = file.readdir(dirent).map(|x| x as usize); 78834e6d6c8Syuyi2439 78934e6d6c8Syuyi2439 return res; 790004e86ffSlogin } 791004e86ffSlogin 792004e86ffSlogin /// @brief 创建文件夹 793004e86ffSlogin /// 794004e86ffSlogin /// @param path(r8) 路径 / mode(r9) 模式 795004e86ffSlogin /// 796004e86ffSlogin /// @return uint64_t 负数错误码 / 0表示成功 mkdir(path: *const u8, mode: usize) -> Result<usize, SystemError>79782df0a13Shmt pub fn mkdir(path: *const u8, mode: usize) -> Result<usize, SystemError> { 798703ce5a7SLoGin let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))? 799703ce5a7SLoGin .into_string() 800703ce5a7SLoGin .map_err(|_| SystemError::EINVAL)?; 801703ce5a7SLoGin 8021074eb34SSamuel Dai do_mkdir_at( 8031074eb34SSamuel Dai AtFlags::AT_FDCWD.bits(), 8041074eb34SSamuel Dai &path, 8051074eb34SSamuel Dai FileMode::from_bits_truncate(mode as u32), 8061074eb34SSamuel Dai )?; 8071074eb34SSamuel Dai return Ok(0); 808004e86ffSlogin } 809004e86ffSlogin 8104695947eSChenzx /// **创建硬连接的系统调用** 8114695947eSChenzx /// 8124695947eSChenzx /// ## 参数 8134695947eSChenzx /// 8144695947eSChenzx /// - 'oldfd': 用于解析源文件路径的文件描述符 8154695947eSChenzx /// - 'old': 源文件路径 8164695947eSChenzx /// - 'newfd': 用于解析新文件路径的文件描述符 8174695947eSChenzx /// - 'new': 新文件将创建的路径 8184695947eSChenzx /// - 'flags': 标志位,仅以位或方式包含AT_EMPTY_PATH和AT_SYMLINK_FOLLOW 8194695947eSChenzx /// 8204695947eSChenzx /// do_linkat( oldfd: i32, old: &str, newfd: i32, new: &str, flags: AtFlags, ) -> Result<usize, SystemError>8214695947eSChenzx pub fn do_linkat( 8224695947eSChenzx oldfd: i32, 8234695947eSChenzx old: &str, 8244695947eSChenzx newfd: i32, 8254695947eSChenzx new: &str, 8264695947eSChenzx flags: AtFlags, 8274695947eSChenzx ) -> Result<usize, SystemError> { 8284695947eSChenzx // flag包含其他未规定值时返回EINVAL 8294695947eSChenzx if !(AtFlags::AT_EMPTY_PATH | AtFlags::AT_SYMLINK_FOLLOW).contains(flags) { 8304695947eSChenzx return Err(SystemError::EINVAL); 8314695947eSChenzx } 8324695947eSChenzx // TODO AT_EMPTY_PATH标志启用时,进行调用者CAP_DAC_READ_SEARCH或相似的检查 8334695947eSChenzx let symlink_times = if flags.contains(AtFlags::AT_SYMLINK_FOLLOW) { 8344e4c8c41SLoGin 0_usize 8354695947eSChenzx } else { 8364695947eSChenzx VFS_MAX_FOLLOW_SYMLINK_TIMES 8374695947eSChenzx }; 8384695947eSChenzx let pcb = ProcessManager::current_pcb(); 8394695947eSChenzx 8404695947eSChenzx // 得到源路径的inode 8414695947eSChenzx let old_inode: Arc<dyn IndexNode> = if old.is_empty() { 8424695947eSChenzx if flags.contains(AtFlags::AT_EMPTY_PATH) { 8434695947eSChenzx // 在AT_EMPTY_PATH启用时,old可以为空,old_inode实际为oldfd所指文件,但该文件不能为目录。 8444695947eSChenzx let binding = pcb.fd_table(); 8454695947eSChenzx let fd_table_guard = binding.read(); 8464695947eSChenzx let file = fd_table_guard 8474695947eSChenzx .get_file_by_fd(oldfd) 8484695947eSChenzx .ok_or(SystemError::EBADF)?; 849dfe53cf0SGnoCiYeH let old_inode = file.inode(); 8504695947eSChenzx old_inode 8514695947eSChenzx } else { 8524695947eSChenzx return Err(SystemError::ENONET); 8534695947eSChenzx } 8544695947eSChenzx } else { 8554695947eSChenzx let (old_begin_inode, old_remain_path) = user_path_at(&pcb, oldfd, old)?; 8564695947eSChenzx old_begin_inode.lookup_follow_symlink(&old_remain_path, symlink_times)? 8574695947eSChenzx }; 8584695947eSChenzx 8594695947eSChenzx // old_inode为目录时返回EPERM 8604695947eSChenzx if old_inode.metadata().unwrap().file_type == FileType::Dir { 8614695947eSChenzx return Err(SystemError::EPERM); 8624695947eSChenzx } 8634695947eSChenzx 8644695947eSChenzx // 得到新创建节点的父节点 8654695947eSChenzx let (new_begin_inode, new_remain_path) = user_path_at(&pcb, newfd, new)?; 8664695947eSChenzx let (new_name, new_parent_path) = rsplit_path(&new_remain_path); 8674e4c8c41SLoGin let new_parent = 8684e4c8c41SLoGin new_begin_inode.lookup_follow_symlink(new_parent_path.unwrap_or("/"), symlink_times)?; 8694695947eSChenzx 8704695947eSChenzx // 被调用者利用downcast_ref判断两inode是否为同一文件系统 8714e4c8c41SLoGin return new_parent.link(new_name, &old_inode).map(|_| 0); 8724695947eSChenzx } 8734695947eSChenzx link(old: *const u8, new: *const u8) -> Result<usize, SystemError>8744695947eSChenzx pub fn link(old: *const u8, new: *const u8) -> Result<usize, SystemError> { 8754695947eSChenzx let get_path = |cstr: *const u8| -> Result<String, SystemError> { 876703ce5a7SLoGin let res = check_and_clone_cstr(cstr, Some(MAX_PATHLEN))? 877703ce5a7SLoGin .into_string() 878703ce5a7SLoGin .map_err(|_| SystemError::EINVAL)?; 879703ce5a7SLoGin 8804695947eSChenzx if res.len() >= MAX_PATHLEN { 8814695947eSChenzx return Err(SystemError::ENAMETOOLONG); 8824695947eSChenzx } 8834695947eSChenzx if res.is_empty() { 8844695947eSChenzx return Err(SystemError::ENOENT); 8854695947eSChenzx } 8864695947eSChenzx Ok(res) 8874695947eSChenzx }; 8884695947eSChenzx let old = get_path(old)?; 8894695947eSChenzx let new = get_path(new)?; 8904695947eSChenzx return Self::do_linkat( 8914e4c8c41SLoGin AtFlags::AT_FDCWD.bits(), 8924695947eSChenzx &old, 8934e4c8c41SLoGin AtFlags::AT_FDCWD.bits(), 8944695947eSChenzx &new, 8954695947eSChenzx AtFlags::empty(), 8964695947eSChenzx ); 8974695947eSChenzx } 8984695947eSChenzx linkat( oldfd: i32, old: *const u8, newfd: i32, new: *const u8, flags: i32, ) -> Result<usize, SystemError>8994695947eSChenzx pub fn linkat( 9004695947eSChenzx oldfd: i32, 9014695947eSChenzx old: *const u8, 9024695947eSChenzx newfd: i32, 9034695947eSChenzx new: *const u8, 9044695947eSChenzx flags: i32, 9054695947eSChenzx ) -> Result<usize, SystemError> { 906703ce5a7SLoGin let old = check_and_clone_cstr(old, Some(MAX_PATHLEN))? 907703ce5a7SLoGin .into_string() 908703ce5a7SLoGin .map_err(|_| SystemError::EINVAL)?; 909703ce5a7SLoGin let new = check_and_clone_cstr(new, Some(MAX_PATHLEN))? 910703ce5a7SLoGin .into_string() 911703ce5a7SLoGin .map_err(|_| SystemError::EINVAL)?; 9124695947eSChenzx if old.len() >= MAX_PATHLEN || new.len() >= MAX_PATHLEN { 9134695947eSChenzx return Err(SystemError::ENAMETOOLONG); 9144695947eSChenzx } 9154695947eSChenzx // old 根据flags & AtFlags::AT_EMPTY_PATH判空 9164695947eSChenzx if new.is_empty() { 9174695947eSChenzx return Err(SystemError::ENOENT); 9184695947eSChenzx } 9194695947eSChenzx let flags = AtFlags::from_bits(flags).ok_or(SystemError::EINVAL)?; 9204695947eSChenzx Self::do_linkat(oldfd, &old, newfd, &new, flags) 9214695947eSChenzx } 9224695947eSChenzx 923ab5c8ca4Slogin /// **删除文件夹、取消文件的链接、删除文件的系统调用** 924004e86ffSlogin /// 925ab5c8ca4Slogin /// ## 参数 926004e86ffSlogin /// 927ab5c8ca4Slogin /// - `dirfd`:文件夹的文件描述符.目前暂未实现 928ab5c8ca4Slogin /// - `pathname`:文件夹的路径 929ab5c8ca4Slogin /// - `flags`:标志位 930004e86ffSlogin /// 931004e86ffSlogin /// unlinkat(dirfd: i32, path: *const u8, flags: u32) -> Result<usize, SystemError>93282df0a13Shmt pub fn unlinkat(dirfd: i32, path: *const u8, flags: u32) -> Result<usize, SystemError> { 933bf4a4899SLoGin let flags = AtFlags::from_bits(flags as i32).ok_or(SystemError::EINVAL)?; 934004e86ffSlogin 935703ce5a7SLoGin let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))? 936703ce5a7SLoGin .into_string() 937703ce5a7SLoGin .map_err(|_| SystemError::EINVAL)?; 93882df0a13Shmt 939bf4a4899SLoGin if flags.contains(AtFlags::AT_REMOVEDIR) { 9402eab6dd7S曾俊 // debug!("rmdir"); 94182df0a13Shmt match do_remove_dir(dirfd, &path) { 942004e86ffSlogin Err(err) => { 943ab5c8ca4Slogin return Err(err); 944004e86ffSlogin } 945004e86ffSlogin Ok(_) => { 946ab5c8ca4Slogin return Ok(0); 947004e86ffSlogin } 948004e86ffSlogin } 949004e86ffSlogin } 950004e86ffSlogin 95182df0a13Shmt match do_unlink_at(dirfd, &path) { 952004e86ffSlogin Err(err) => { 953ab5c8ca4Slogin return Err(err); 954004e86ffSlogin } 955004e86ffSlogin Ok(_) => { 956ab5c8ca4Slogin return Ok(0); 957004e86ffSlogin } 958004e86ffSlogin } 959004e86ffSlogin } 9602b771e32SGou Ngai rmdir(path: *const u8) -> Result<usize, SystemError>96182df0a13Shmt pub fn rmdir(path: *const u8) -> Result<usize, SystemError> { 962703ce5a7SLoGin let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))? 963703ce5a7SLoGin .into_string() 964703ce5a7SLoGin .map_err(|_| SystemError::EINVAL)?; 96582df0a13Shmt return do_remove_dir(AtFlags::AT_FDCWD.bits(), &path).map(|v| v as usize); 9665eeefb8cSChenzx } 9675eeefb8cSChenzx unlink(path: *const u8) -> Result<usize, SystemError>96882df0a13Shmt pub fn unlink(path: *const u8) -> Result<usize, SystemError> { 969703ce5a7SLoGin let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))? 970703ce5a7SLoGin .into_string() 971703ce5a7SLoGin .map_err(|_| SystemError::EINVAL)?; 97282df0a13Shmt return do_unlink_at(AtFlags::AT_FDCWD.bits(), &path).map(|v| v as usize); 973bf4a4899SLoGin } 974bf4a4899SLoGin 9759e481b3bSTTaq /// # 修改文件名 9769e481b3bSTTaq /// 9779e481b3bSTTaq /// 9789e481b3bSTTaq /// ## 参数 9799e481b3bSTTaq /// 9801074eb34SSamuel Dai /// - oldfd: 源文件夹文件描述符 9819e481b3bSTTaq /// - filename_from: 源文件路径 9821074eb34SSamuel Dai /// - newfd: 目标文件夹文件描述符 9839e481b3bSTTaq /// - filename_to: 目标文件路径 9849e481b3bSTTaq /// - flags: 标志位 9859e481b3bSTTaq /// 9869e481b3bSTTaq /// 9879e481b3bSTTaq /// ## 返回值 9889e481b3bSTTaq /// - Ok(返回值类型): 返回值的说明 9899e481b3bSTTaq /// - Err(错误值类型): 错误的说明 9909e481b3bSTTaq /// do_renameat2( oldfd: i32, filename_from: *const u8, newfd: i32, filename_to: *const u8, _flags: u32, ) -> Result<usize, SystemError>9919e481b3bSTTaq pub fn do_renameat2( 9929e481b3bSTTaq oldfd: i32, 9939e481b3bSTTaq filename_from: *const u8, 9949e481b3bSTTaq newfd: i32, 9959e481b3bSTTaq filename_to: *const u8, 9969e481b3bSTTaq _flags: u32, 9979e481b3bSTTaq ) -> Result<usize, SystemError> { 998703ce5a7SLoGin let filename_from = check_and_clone_cstr(filename_from, Some(MAX_PATHLEN)) 999703ce5a7SLoGin .unwrap() 1000703ce5a7SLoGin .into_string() 1001703ce5a7SLoGin .map_err(|_| SystemError::EINVAL)?; 1002703ce5a7SLoGin let filename_to = check_and_clone_cstr(filename_to, Some(MAX_PATHLEN)) 1003703ce5a7SLoGin .unwrap() 1004703ce5a7SLoGin .into_string() 1005703ce5a7SLoGin .map_err(|_| SystemError::EINVAL)?; 10069e481b3bSTTaq // 文件名过长 1007b5b571e0SLoGin if filename_from.len() > MAX_PATHLEN || filename_to.len() > MAX_PATHLEN { 10089e481b3bSTTaq return Err(SystemError::ENAMETOOLONG); 10099e481b3bSTTaq } 10109e481b3bSTTaq 10119e481b3bSTTaq //获取pcb,文件节点 10129e481b3bSTTaq let pcb = ProcessManager::current_pcb(); 10139e481b3bSTTaq let (_old_inode_begin, old_remain_path) = user_path_at(&pcb, oldfd, &filename_from)?; 10149e481b3bSTTaq let (_new_inode_begin, new_remain_path) = user_path_at(&pcb, newfd, &filename_to)?; 10159e481b3bSTTaq //获取父目录 10169e481b3bSTTaq let (old_filename, old_parent_path) = rsplit_path(&old_remain_path); 10179e481b3bSTTaq let old_parent_inode = ROOT_INODE() 10189e481b3bSTTaq .lookup_follow_symlink(old_parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 10199e481b3bSTTaq let (new_filename, new_parent_path) = rsplit_path(&new_remain_path); 10209e481b3bSTTaq let new_parent_inode = ROOT_INODE() 10219e481b3bSTTaq .lookup_follow_symlink(new_parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 10229e481b3bSTTaq old_parent_inode.move_to(old_filename, &new_parent_inode, new_filename)?; 10239e481b3bSTTaq return Ok(0); 10249e481b3bSTTaq } 10259e481b3bSTTaq 1026ab5c8ca4Slogin /// @brief 根据提供的文件描述符的fd,复制对应的文件结构体,并返回新复制的文件结构体对应的fd dup(oldfd: i32) -> Result<usize, SystemError>1027ab5c8ca4Slogin pub fn dup(oldfd: i32) -> Result<usize, SystemError> { 10281496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 10291496ba7bSLoGin let mut fd_table_guard = binding.write(); 1030ab5c8ca4Slogin 10311496ba7bSLoGin let old_file = fd_table_guard 10321496ba7bSLoGin .get_file_by_fd(oldfd) 10331496ba7bSLoGin .ok_or(SystemError::EBADF)?; 10341496ba7bSLoGin 1035dfe53cf0SGnoCiYeH let new_file = old_file.try_clone().ok_or(SystemError::EBADF)?; 10369365e801SGnoCiYeH // dup默认非cloexec 10379365e801SGnoCiYeH new_file.set_close_on_exec(false); 10382b771e32SGou Ngai // 申请文件描述符,并把文件对象存入其中 10391496ba7bSLoGin let res = fd_table_guard.alloc_fd(new_file, None).map(|x| x as usize); 10402b771e32SGou Ngai return res; 10412b771e32SGou Ngai } 10422b771e32SGou Ngai 1043ab5c8ca4Slogin /// 根据提供的文件描述符的fd,和指定新fd,复制对应的文件结构体, 1044ab5c8ca4Slogin /// 并返回新复制的文件结构体对应的fd. 1045ab5c8ca4Slogin /// 如果新fd已经打开,则会先关闭新fd. 1046ab5c8ca4Slogin /// 1047ab5c8ca4Slogin /// ## 参数 1048ab5c8ca4Slogin /// 1049ab5c8ca4Slogin /// - `oldfd`:旧文件描述符 1050ab5c8ca4Slogin /// - `newfd`:新文件描述符 1051ab5c8ca4Slogin /// 1052ab5c8ca4Slogin /// ## 返回值 1053ab5c8ca4Slogin /// 1054ab5c8ca4Slogin /// - 成功:新文件描述符 1055ab5c8ca4Slogin /// - 失败:错误码 dup2(oldfd: i32, newfd: i32) -> Result<usize, SystemError>1056ab5c8ca4Slogin pub fn dup2(oldfd: i32, newfd: i32) -> Result<usize, SystemError> { 10571496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 10581496ba7bSLoGin let mut fd_table_guard = binding.write(); 10591496ba7bSLoGin return Self::do_dup2(oldfd, newfd, &mut fd_table_guard); 10601496ba7bSLoGin } 10611496ba7bSLoGin dup3(oldfd: i32, newfd: i32, flags: u32) -> Result<usize, SystemError>106240348dd8Szwb0x00 pub fn dup3(oldfd: i32, newfd: i32, flags: u32) -> Result<usize, SystemError> { 106340348dd8Szwb0x00 let flags = FileMode::from_bits_truncate(flags); 106440348dd8Szwb0x00 if (flags.bits() & !FileMode::O_CLOEXEC.bits()) != 0 { 106540348dd8Szwb0x00 return Err(SystemError::EINVAL); 106640348dd8Szwb0x00 } 106740348dd8Szwb0x00 106840348dd8Szwb0x00 if oldfd == newfd { 106940348dd8Szwb0x00 return Err(SystemError::EINVAL); 107040348dd8Szwb0x00 } 107140348dd8Szwb0x00 107240348dd8Szwb0x00 let binding = ProcessManager::current_pcb().fd_table(); 107340348dd8Szwb0x00 let mut fd_table_guard = binding.write(); 107440348dd8Szwb0x00 return Self::do_dup3(oldfd, newfd, flags, &mut fd_table_guard); 107540348dd8Szwb0x00 } 107640348dd8Szwb0x00 do_dup2( oldfd: i32, newfd: i32, fd_table_guard: &mut RwLockWriteGuard<'_, FileDescriptorVec>, ) -> Result<usize, SystemError>10771496ba7bSLoGin fn do_dup2( 10781496ba7bSLoGin oldfd: i32, 10791496ba7bSLoGin newfd: i32, 10801496ba7bSLoGin fd_table_guard: &mut RwLockWriteGuard<'_, FileDescriptorVec>, 10811496ba7bSLoGin ) -> Result<usize, SystemError> { 1082d623e902SGnoCiYeH Self::do_dup3(oldfd, newfd, FileMode::empty(), fd_table_guard) 1083d623e902SGnoCiYeH } 1084d623e902SGnoCiYeH do_dup3( oldfd: i32, newfd: i32, flags: FileMode, fd_table_guard: &mut RwLockWriteGuard<'_, FileDescriptorVec>, ) -> Result<usize, SystemError>1085d623e902SGnoCiYeH fn do_dup3( 1086d623e902SGnoCiYeH oldfd: i32, 1087d623e902SGnoCiYeH newfd: i32, 1088d623e902SGnoCiYeH flags: FileMode, 1089d623e902SGnoCiYeH fd_table_guard: &mut RwLockWriteGuard<'_, FileDescriptorVec>, 1090d623e902SGnoCiYeH ) -> Result<usize, SystemError> { 10912b771e32SGou Ngai // 确认oldfd, newid是否有效 10921496ba7bSLoGin if !(FileDescriptorVec::validate_fd(oldfd) && FileDescriptorVec::validate_fd(newfd)) { 10931496ba7bSLoGin return Err(SystemError::EBADF); 10941496ba7bSLoGin } 10951496ba7bSLoGin 10962b771e32SGou Ngai if oldfd == newfd { 10972b771e32SGou Ngai // 若oldfd与newfd相等 1098ab5c8ca4Slogin return Ok(newfd as usize); 10992b771e32SGou Ngai } 11001496ba7bSLoGin let new_exists = fd_table_guard.get_file_by_fd(newfd).is_some(); 11011496ba7bSLoGin if new_exists { 11022b771e32SGou Ngai // close newfd 1103b5b571e0SLoGin if fd_table_guard.drop_fd(newfd).is_err() { 11042b771e32SGou Ngai // An I/O error occurred while attempting to close fildes2. 11052b771e32SGou Ngai return Err(SystemError::EIO); 11062b771e32SGou Ngai } 11072b771e32SGou Ngai } 11082b771e32SGou Ngai 11091496ba7bSLoGin let old_file = fd_table_guard 11101496ba7bSLoGin .get_file_by_fd(oldfd) 11111496ba7bSLoGin .ok_or(SystemError::EBADF)?; 1112dfe53cf0SGnoCiYeH let new_file = old_file.try_clone().ok_or(SystemError::EBADF)?; 1113d623e902SGnoCiYeH 1114d623e902SGnoCiYeH if flags.contains(FileMode::O_CLOEXEC) { 1115d623e902SGnoCiYeH new_file.set_close_on_exec(true); 1116d623e902SGnoCiYeH } else { 11179365e801SGnoCiYeH new_file.set_close_on_exec(false); 1118d623e902SGnoCiYeH } 11192b771e32SGou Ngai // 申请文件描述符,并把文件对象存入其中 11201496ba7bSLoGin let res = fd_table_guard 11211496ba7bSLoGin .alloc_fd(new_file, Some(newfd)) 1122ab5c8ca4Slogin .map(|x| x as usize); 11232b771e32SGou Ngai return res; 11242b771e32SGou Ngai } 11256d81180bSLoGin 11266d81180bSLoGin /// # fcntl 11276d81180bSLoGin /// 11286d81180bSLoGin /// ## 参数 11296d81180bSLoGin /// 11306d81180bSLoGin /// - `fd`:文件描述符 11316d81180bSLoGin /// - `cmd`:命令 11326d81180bSLoGin /// - `arg`:参数 fcntl(fd: i32, cmd: FcntlCommand, arg: i32) -> Result<usize, SystemError>11336d81180bSLoGin pub fn fcntl(fd: i32, cmd: FcntlCommand, arg: i32) -> Result<usize, SystemError> { 11342eab6dd7S曾俊 // debug!("fcntl ({cmd:?}) fd: {fd}, arg={arg}"); 11356d81180bSLoGin match cmd { 1136d623e902SGnoCiYeH FcntlCommand::DupFd | FcntlCommand::DupFdCloexec => { 11376d81180bSLoGin if arg < 0 || arg as usize >= FileDescriptorVec::PROCESS_MAX_FD { 11386d81180bSLoGin return Err(SystemError::EBADF); 11396d81180bSLoGin } 11406d81180bSLoGin let arg = arg as usize; 11416d81180bSLoGin for i in arg..FileDescriptorVec::PROCESS_MAX_FD { 11421496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 11431496ba7bSLoGin let mut fd_table_guard = binding.write(); 114452da9a59SGnoCiYeH if fd_table_guard.get_file_by_fd(i as i32).is_none() { 1145d623e902SGnoCiYeH if cmd == FcntlCommand::DupFd { 11461496ba7bSLoGin return Self::do_dup2(fd, i as i32, &mut fd_table_guard); 1147d623e902SGnoCiYeH } else { 1148d623e902SGnoCiYeH return Self::do_dup3( 1149d623e902SGnoCiYeH fd, 1150d623e902SGnoCiYeH i as i32, 1151d623e902SGnoCiYeH FileMode::O_CLOEXEC, 1152d623e902SGnoCiYeH &mut fd_table_guard, 1153d623e902SGnoCiYeH ); 1154d623e902SGnoCiYeH } 11556d81180bSLoGin } 11566d81180bSLoGin } 11576d81180bSLoGin return Err(SystemError::EMFILE); 11586d81180bSLoGin } 11596d81180bSLoGin FcntlCommand::GetFd => { 11606d81180bSLoGin // Get file descriptor flags. 11611496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 11621496ba7bSLoGin let fd_table_guard = binding.read(); 1163d623e902SGnoCiYeH 11641496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 11651496ba7bSLoGin // drop guard 以避免无法调度的问题 11661496ba7bSLoGin drop(fd_table_guard); 11676d81180bSLoGin 1168dfe53cf0SGnoCiYeH if file.close_on_exec() { 11696d81180bSLoGin return Ok(FD_CLOEXEC as usize); 1170d623e902SGnoCiYeH } else { 1171d623e902SGnoCiYeH return Ok(0); 11726d81180bSLoGin } 11736d81180bSLoGin } 11746d81180bSLoGin return Err(SystemError::EBADF); 11756d81180bSLoGin } 11766d81180bSLoGin FcntlCommand::SetFd => { 11776d81180bSLoGin // Set file descriptor flags. 11781496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 11791496ba7bSLoGin let fd_table_guard = binding.write(); 11801496ba7bSLoGin 11811496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 11821496ba7bSLoGin // drop guard 以避免无法调度的问题 11831496ba7bSLoGin drop(fd_table_guard); 11846d81180bSLoGin let arg = arg as u32; 11856d81180bSLoGin if arg & FD_CLOEXEC != 0 { 1186dfe53cf0SGnoCiYeH file.set_close_on_exec(true); 11876d81180bSLoGin } else { 1188dfe53cf0SGnoCiYeH file.set_close_on_exec(false); 11896d81180bSLoGin } 11906d81180bSLoGin return Ok(0); 11916d81180bSLoGin } 11926d81180bSLoGin return Err(SystemError::EBADF); 11936d81180bSLoGin } 11946d81180bSLoGin 11956d81180bSLoGin FcntlCommand::GetFlags => { 11966d81180bSLoGin // Get file status flags. 11971496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 11981496ba7bSLoGin let fd_table_guard = binding.read(); 11991496ba7bSLoGin 12001496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 12011496ba7bSLoGin // drop guard 以避免无法调度的问题 12021496ba7bSLoGin drop(fd_table_guard); 1203dfe53cf0SGnoCiYeH return Ok(file.mode().bits() as usize); 12046d81180bSLoGin } 12051496ba7bSLoGin 12066d81180bSLoGin return Err(SystemError::EBADF); 12076d81180bSLoGin } 12086d81180bSLoGin FcntlCommand::SetFlags => { 12096d81180bSLoGin // Set file status flags. 12101496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 12111496ba7bSLoGin let fd_table_guard = binding.write(); 12121496ba7bSLoGin 12131496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 12146d81180bSLoGin let arg = arg as u32; 12156d81180bSLoGin let mode = FileMode::from_bits(arg).ok_or(SystemError::EINVAL)?; 12161496ba7bSLoGin // drop guard 以避免无法调度的问题 12171496ba7bSLoGin drop(fd_table_guard); 1218dfe53cf0SGnoCiYeH file.set_mode(mode)?; 12196d81180bSLoGin return Ok(0); 12206d81180bSLoGin } 12211496ba7bSLoGin 12226d81180bSLoGin return Err(SystemError::EBADF); 12236d81180bSLoGin } 12246d81180bSLoGin _ => { 12256d81180bSLoGin // TODO: unimplemented 12266d81180bSLoGin // 未实现的命令,返回0,不报错。 12276d81180bSLoGin 12282eab6dd7S曾俊 warn!("fcntl: unimplemented command: {:?}, defaults to 0.", cmd); 1229d623e902SGnoCiYeH return Err(SystemError::ENOSYS); 12306d81180bSLoGin } 12316d81180bSLoGin } 12326d81180bSLoGin } 12336d81180bSLoGin 12346d81180bSLoGin /// # ftruncate 12356d81180bSLoGin /// 12366d81180bSLoGin /// ## 描述 12376d81180bSLoGin /// 12386d81180bSLoGin /// 改变文件大小. 12396d81180bSLoGin /// 如果文件大小大于原来的大小,那么文件的内容将会被扩展到指定的大小,新的空间将会用0填充. 12406d81180bSLoGin /// 如果文件大小小于原来的大小,那么文件的内容将会被截断到指定的大小. 12416d81180bSLoGin /// 12426d81180bSLoGin /// ## 参数 12436d81180bSLoGin /// 12446d81180bSLoGin /// - `fd`:文件描述符 12456d81180bSLoGin /// - `len`:文件大小 12466d81180bSLoGin /// 12476d81180bSLoGin /// ## 返回值 12486d81180bSLoGin /// 12496d81180bSLoGin /// 如果成功,返回0,否则返回错误码. ftruncate(fd: i32, len: usize) -> Result<usize, SystemError>12506d81180bSLoGin pub fn ftruncate(fd: i32, len: usize) -> Result<usize, SystemError> { 12511496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 12521496ba7bSLoGin let fd_table_guard = binding.read(); 12531496ba7bSLoGin 12541496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 12551496ba7bSLoGin // drop guard 以避免无法调度的问题 12561496ba7bSLoGin drop(fd_table_guard); 1257dfe53cf0SGnoCiYeH let r = file.ftruncate(len).map(|_| 0); 12586d81180bSLoGin return r; 12596d81180bSLoGin } 12601496ba7bSLoGin 12616d81180bSLoGin return Err(SystemError::EBADF); 12626d81180bSLoGin } 12631496ba7bSLoGin do_fstat(fd: i32) -> Result<PosixKstat, SystemError>126467b48188Shoumkh fn do_fstat(fd: i32) -> Result<PosixKstat, SystemError> { 12651496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 12661496ba7bSLoGin let fd_table_guard = binding.read(); 12671496ba7bSLoGin let file = fd_table_guard 12681496ba7bSLoGin .get_file_by_fd(fd) 12691496ba7bSLoGin .ok_or(SystemError::EBADF)?; 12701496ba7bSLoGin // drop guard 以避免无法调度的问题 12711496ba7bSLoGin drop(fd_table_guard); 12721496ba7bSLoGin 127367b48188Shoumkh let mut kstat = PosixKstat::new(); 127467b48188Shoumkh // 获取文件信息 1275dfe53cf0SGnoCiYeH let metadata = file.metadata()?; 1276b5b571e0SLoGin kstat.size = metadata.size; 127767b48188Shoumkh kstat.dev_id = metadata.dev_id as u64; 12786b4e7a29SLoGin kstat.inode = metadata.inode_id.into() as u64; 127967b48188Shoumkh kstat.blcok_size = metadata.blk_size as i64; 128067b48188Shoumkh kstat.blocks = metadata.blocks as u64; 128167b48188Shoumkh 128267b48188Shoumkh kstat.atime.tv_sec = metadata.atime.tv_sec; 128367b48188Shoumkh kstat.atime.tv_nsec = metadata.atime.tv_nsec; 128467b48188Shoumkh kstat.mtime.tv_sec = metadata.mtime.tv_sec; 128567b48188Shoumkh kstat.mtime.tv_nsec = metadata.mtime.tv_nsec; 128667b48188Shoumkh kstat.ctime.tv_sec = metadata.ctime.tv_sec; 128767b48188Shoumkh kstat.ctime.tv_nsec = metadata.ctime.tv_nsec; 128867b48188Shoumkh 128967b48188Shoumkh kstat.nlink = metadata.nlinks as u64; 129067b48188Shoumkh kstat.uid = metadata.uid as i32; 129167b48188Shoumkh kstat.gid = metadata.gid as i32; 129202343d0bSLoGin kstat.rdev = metadata.raw_dev.data() as i64; 12936b4e7a29SLoGin kstat.mode = metadata.mode; 1294dfe53cf0SGnoCiYeH match file.file_type() { 12957eda31b2SLoGin FileType::File => kstat.mode.insert(ModeType::S_IFREG), 129667b48188Shoumkh FileType::Dir => kstat.mode.insert(ModeType::S_IFDIR), 129767b48188Shoumkh FileType::BlockDevice => kstat.mode.insert(ModeType::S_IFBLK), 129867b48188Shoumkh FileType::CharDevice => kstat.mode.insert(ModeType::S_IFCHR), 129967b48188Shoumkh FileType::SymLink => kstat.mode.insert(ModeType::S_IFLNK), 130067b48188Shoumkh FileType::Socket => kstat.mode.insert(ModeType::S_IFSOCK), 130167b48188Shoumkh FileType::Pipe => kstat.mode.insert(ModeType::S_IFIFO), 130240314b30SXiaoye Zheng FileType::KvmDevice => kstat.mode.insert(ModeType::S_IFCHR), 130302343d0bSLoGin FileType::FramebufferDevice => kstat.mode.insert(ModeType::S_IFCHR), 130467b48188Shoumkh } 130567b48188Shoumkh 130667b48188Shoumkh return Ok(kstat); 130767b48188Shoumkh } 13081496ba7bSLoGin fstat(fd: i32, usr_kstat: *mut PosixKstat) -> Result<usize, SystemError>130967b48188Shoumkh pub fn fstat(fd: i32, usr_kstat: *mut PosixKstat) -> Result<usize, SystemError> { 131082df0a13Shmt let mut writer = UserBufferWriter::new(usr_kstat, size_of::<PosixKstat>(), true)?; 13111496ba7bSLoGin let kstat = Self::do_fstat(fd)?; 131282df0a13Shmt 131382df0a13Shmt writer.copy_one_to_user(&kstat, 0)?; 131467b48188Shoumkh return Ok(0); 131567b48188Shoumkh } 13162dbef785SGnoCiYeH stat(path: *const u8, user_kstat: *mut PosixKstat) -> Result<usize, SystemError>131782df0a13Shmt pub fn stat(path: *const u8, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> { 131882df0a13Shmt let fd = Self::open( 131982df0a13Shmt path, 132082df0a13Shmt FileMode::O_RDONLY.bits(), 132182df0a13Shmt ModeType::empty().bits(), 132282df0a13Shmt true, 132382df0a13Shmt )?; 1324bf4a4899SLoGin let r = Self::fstat(fd as i32, user_kstat); 1325971462beSGnoCiYeH Self::close(fd).ok(); 1326bf4a4899SLoGin return r; 1327bf4a4899SLoGin } 1328bf4a4899SLoGin lstat(path: *const u8, user_kstat: *mut PosixKstat) -> Result<usize, SystemError>132982df0a13Shmt pub fn lstat(path: *const u8, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> { 133082df0a13Shmt let fd = Self::open( 133182df0a13Shmt path, 133282df0a13Shmt FileMode::O_RDONLY.bits(), 133382df0a13Shmt ModeType::empty().bits(), 133482df0a13Shmt false, 133582df0a13Shmt )?; 1336bf4a4899SLoGin let r = Self::fstat(fd as i32, user_kstat); 1337bf4a4899SLoGin Self::close(fd).ok(); 1338bf4a4899SLoGin return r; 1339971462beSGnoCiYeH } 1340971462beSGnoCiYeH statfs(path: *const u8, user_statfs: *mut PosixStatfs) -> Result<usize, SystemError>1341597ecc08STTaq pub fn statfs(path: *const u8, user_statfs: *mut PosixStatfs) -> Result<usize, SystemError> { 1342597ecc08STTaq let mut writer = UserBufferWriter::new(user_statfs, size_of::<PosixStatfs>(), true)?; 1343597ecc08STTaq let fd = Self::open( 1344597ecc08STTaq path, 1345597ecc08STTaq FileMode::O_RDONLY.bits(), 1346597ecc08STTaq ModeType::empty().bits(), 1347597ecc08STTaq true, 1348597ecc08STTaq )?; 1349703ce5a7SLoGin let path = check_and_clone_cstr(path, Some(MAX_PATHLEN)) 1350703ce5a7SLoGin .unwrap() 1351703ce5a7SLoGin .into_string() 1352703ce5a7SLoGin .map_err(|_| SystemError::EINVAL)?; 1353597ecc08STTaq let pcb = ProcessManager::current_pcb(); 1354597ecc08STTaq let (_inode_begin, remain_path) = user_path_at(&pcb, fd as i32, &path)?; 1355597ecc08STTaq let inode = ROOT_INODE().lookup_follow_symlink(&remain_path, MAX_PATHLEN)?; 1356597ecc08STTaq let statfs = PosixStatfs::from(inode.fs().super_block()); 1357597ecc08STTaq writer.copy_one_to_user(&statfs, 0)?; 1358597ecc08STTaq return Ok(0); 1359597ecc08STTaq } 1360597ecc08STTaq fstatfs(fd: i32, user_statfs: *mut PosixStatfs) -> Result<usize, SystemError>1361597ecc08STTaq pub fn fstatfs(fd: i32, user_statfs: *mut PosixStatfs) -> Result<usize, SystemError> { 1362597ecc08STTaq let mut writer = UserBufferWriter::new(user_statfs, size_of::<PosixStatfs>(), true)?; 1363597ecc08STTaq let binding = ProcessManager::current_pcb().fd_table(); 1364597ecc08STTaq let fd_table_guard = binding.read(); 1365597ecc08STTaq let file = fd_table_guard 1366597ecc08STTaq .get_file_by_fd(fd) 1367597ecc08STTaq .ok_or(SystemError::EBADF)?; 1368597ecc08STTaq drop(fd_table_guard); 1369dfe53cf0SGnoCiYeH let statfs = PosixStatfs::from(file.inode().fs().super_block()); 1370597ecc08STTaq writer.copy_one_to_user(&statfs, 0)?; 1371597ecc08STTaq return Ok(0); 1372597ecc08STTaq } 1373597ecc08STTaq do_statx( fd: i32, path: *const u8, flags: u32, mask: u32, usr_kstat: *mut PosixStatx, ) -> Result<usize, SystemError>1374b4eb05a1STTaq pub fn do_statx( 1375b4eb05a1STTaq fd: i32, 1376b4eb05a1STTaq path: *const u8, 1377b4eb05a1STTaq flags: u32, 1378b4eb05a1STTaq mask: u32, 1379b4eb05a1STTaq usr_kstat: *mut PosixStatx, 1380b4eb05a1STTaq ) -> Result<usize, SystemError> { 1381b4eb05a1STTaq if usr_kstat.is_null() { 1382b4eb05a1STTaq return Err(SystemError::EFAULT); 1383b4eb05a1STTaq } 1384b4eb05a1STTaq 1385b4eb05a1STTaq let mask = PosixStatxMask::from_bits_truncate(mask); 1386b4eb05a1STTaq 1387b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_RESERVED) { 1388b4eb05a1STTaq return Err(SystemError::ENAVAIL); 1389b4eb05a1STTaq } 1390b4eb05a1STTaq 1391b4eb05a1STTaq let flags = FileMode::from_bits_truncate(flags); 1392b4eb05a1STTaq let ofd = Self::open(path, flags.bits(), ModeType::empty().bits, true)?; 1393b4eb05a1STTaq 1394b4eb05a1STTaq let binding = ProcessManager::current_pcb().fd_table(); 1395b4eb05a1STTaq let fd_table_guard = binding.read(); 1396b4eb05a1STTaq let file = fd_table_guard 1397b4eb05a1STTaq .get_file_by_fd(ofd as i32) 1398b4eb05a1STTaq .ok_or(SystemError::EBADF)?; 1399b4eb05a1STTaq // drop guard 以避免无法调度的问题 1400b4eb05a1STTaq drop(fd_table_guard); 1401b4eb05a1STTaq let mut writer = UserBufferWriter::new(usr_kstat, size_of::<PosixStatx>(), true)?; 1402b4eb05a1STTaq let mut tmp: PosixStatx = PosixStatx::new(); 1403b4eb05a1STTaq // 获取文件信息 1404dfe53cf0SGnoCiYeH let metadata = file.metadata()?; 1405b4eb05a1STTaq 1406b4eb05a1STTaq tmp.stx_mask |= PosixStatxMask::STATX_BASIC_STATS; 1407b4eb05a1STTaq tmp.stx_blksize = metadata.blk_size as u32; 1408b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_MODE) || mask.contains(PosixStatxMask::STATX_TYPE) { 1409b4eb05a1STTaq tmp.stx_mode = metadata.mode; 1410b4eb05a1STTaq } 1411b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_NLINK) { 1412b4eb05a1STTaq tmp.stx_nlink = metadata.nlinks as u32; 1413b4eb05a1STTaq } 1414b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_UID) { 1415b4eb05a1STTaq tmp.stx_uid = metadata.uid as u32; 1416b4eb05a1STTaq } 1417b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_GID) { 1418b4eb05a1STTaq tmp.stx_gid = metadata.gid as u32; 1419b4eb05a1STTaq } 1420b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_ATIME) { 1421b4eb05a1STTaq tmp.stx_atime.tv_sec = metadata.atime.tv_sec; 1422b4eb05a1STTaq tmp.stx_atime.tv_nsec = metadata.atime.tv_nsec; 1423b4eb05a1STTaq } 1424b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_MTIME) { 1425b4eb05a1STTaq tmp.stx_mtime.tv_sec = metadata.ctime.tv_sec; 1426b4eb05a1STTaq tmp.stx_mtime.tv_nsec = metadata.ctime.tv_nsec; 1427b4eb05a1STTaq } 1428b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_CTIME) { 1429b4eb05a1STTaq // ctime是文件上次修改状态的时间 1430b4eb05a1STTaq tmp.stx_ctime.tv_sec = metadata.mtime.tv_sec; 1431b4eb05a1STTaq tmp.stx_ctime.tv_nsec = metadata.mtime.tv_nsec; 1432b4eb05a1STTaq } 1433b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_INO) { 1434b4eb05a1STTaq tmp.stx_inode = metadata.inode_id.into() as u64; 1435b4eb05a1STTaq } 1436b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_SIZE) { 1437b4eb05a1STTaq tmp.stx_size = metadata.size; 1438b4eb05a1STTaq } 1439b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_BLOCKS) { 1440b4eb05a1STTaq tmp.stx_blocks = metadata.blocks as u64; 1441b4eb05a1STTaq } 1442b4eb05a1STTaq 1443b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_BTIME) { 1444b4eb05a1STTaq // btime是文件创建时间 1445b4eb05a1STTaq tmp.stx_btime.tv_sec = metadata.ctime.tv_sec; 1446b4eb05a1STTaq tmp.stx_btime.tv_nsec = metadata.ctime.tv_nsec; 1447b4eb05a1STTaq } 1448b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_ALL) { 1449b4eb05a1STTaq tmp.stx_attributes = StxAttributes::STATX_ATTR_APPEND; 1450b4eb05a1STTaq tmp.stx_attributes_mask |= 1451b4eb05a1STTaq StxAttributes::STATX_ATTR_AUTOMOUNT | StxAttributes::STATX_ATTR_DAX; 1452b4eb05a1STTaq tmp.stx_dev_major = metadata.dev_id as u32; 1453b4eb05a1STTaq tmp.stx_dev_minor = metadata.dev_id as u32; // 1454b5b571e0SLoGin tmp.stx_rdev_major = metadata.raw_dev.data(); 1455b5b571e0SLoGin tmp.stx_rdev_minor = metadata.raw_dev.data(); 1456b4eb05a1STTaq } 1457b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_MNT_ID) { 1458b4eb05a1STTaq tmp.stx_mnt_id = 0; 1459b4eb05a1STTaq } 1460b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_DIOALIGN) { 1461b4eb05a1STTaq tmp.stx_dio_mem_align = 0; 1462b4eb05a1STTaq tmp.stx_dio_offset_align = 0; 1463b4eb05a1STTaq } 1464b4eb05a1STTaq 1465dfe53cf0SGnoCiYeH match file.file_type() { 1466b4eb05a1STTaq FileType::File => tmp.stx_mode.insert(ModeType::S_IFREG), 1467b4eb05a1STTaq FileType::Dir => tmp.stx_mode.insert(ModeType::S_IFDIR), 1468b4eb05a1STTaq FileType::BlockDevice => tmp.stx_mode.insert(ModeType::S_IFBLK), 1469b4eb05a1STTaq FileType::CharDevice => tmp.stx_mode.insert(ModeType::S_IFCHR), 1470b4eb05a1STTaq FileType::SymLink => tmp.stx_mode.insert(ModeType::S_IFLNK), 1471b4eb05a1STTaq FileType::Socket => tmp.stx_mode.insert(ModeType::S_IFSOCK), 1472b4eb05a1STTaq FileType::Pipe => tmp.stx_mode.insert(ModeType::S_IFIFO), 1473b4eb05a1STTaq FileType::KvmDevice => tmp.stx_mode.insert(ModeType::S_IFCHR), 1474b4eb05a1STTaq FileType::FramebufferDevice => tmp.stx_mode.insert(ModeType::S_IFCHR), 1475b4eb05a1STTaq } 1476b4eb05a1STTaq 1477b4eb05a1STTaq writer.copy_one_to_user(&tmp, 0)?; 1478b4eb05a1STTaq Self::close(fd as usize).ok(); 1479b4eb05a1STTaq return Ok(0); 1480b4eb05a1STTaq } 1481b4eb05a1STTaq mknod( path: *const u8, mode: ModeType, dev_t: DeviceNumber, ) -> Result<usize, SystemError>14822dbef785SGnoCiYeH pub fn mknod( 148382df0a13Shmt path: *const u8, 14842dbef785SGnoCiYeH mode: ModeType, 14852dbef785SGnoCiYeH dev_t: DeviceNumber, 14862dbef785SGnoCiYeH ) -> Result<usize, SystemError> { 1487703ce5a7SLoGin let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))? 1488703ce5a7SLoGin .into_string() 1489703ce5a7SLoGin .map_err(|_| SystemError::EINVAL)?; 149082df0a13Shmt let path = path.as_str().trim(); 14912dbef785SGnoCiYeH 1492a03c4f9dSLoGin let inode: Result<Arc<dyn IndexNode>, SystemError> = 1493a03c4f9dSLoGin ROOT_INODE().lookup_follow_symlink(path, VFS_MAX_FOLLOW_SYMLINK_TIMES); 14942dbef785SGnoCiYeH 14952dbef785SGnoCiYeH if inode.is_ok() { 14962dbef785SGnoCiYeH return Err(SystemError::EEXIST); 14972dbef785SGnoCiYeH } 14982dbef785SGnoCiYeH 14992dbef785SGnoCiYeH let (filename, parent_path) = rsplit_path(path); 15002dbef785SGnoCiYeH 15012dbef785SGnoCiYeH // 查找父目录 1502a03c4f9dSLoGin let parent_inode: Arc<dyn IndexNode> = ROOT_INODE() 1503a03c4f9dSLoGin .lookup_follow_symlink(parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 15042dbef785SGnoCiYeH // 创建nod 15052dbef785SGnoCiYeH parent_inode.mknod(filename, mode, dev_t)?; 15062dbef785SGnoCiYeH 15072dbef785SGnoCiYeH return Ok(0); 15082dbef785SGnoCiYeH } 1509971462beSGnoCiYeH writev(fd: i32, iov: usize, count: usize) -> Result<usize, SystemError>1510971462beSGnoCiYeH pub fn writev(fd: i32, iov: usize, count: usize) -> Result<usize, SystemError> { 1511971462beSGnoCiYeH // IoVecs会进行用户态检验 1512971462beSGnoCiYeH let iovecs = unsafe { IoVecs::from_user(iov as *const IoVec, count, false) }?; 1513971462beSGnoCiYeH 1514971462beSGnoCiYeH let data = iovecs.gather(); 1515971462beSGnoCiYeH 1516971462beSGnoCiYeH Self::write(fd, &data) 1517971462beSGnoCiYeH } 1518709498caSLoGin readv(fd: i32, iov: usize, count: usize) -> Result<usize, SystemError>1519bf4a4899SLoGin pub fn readv(fd: i32, iov: usize, count: usize) -> Result<usize, SystemError> { 1520bf4a4899SLoGin // IoVecs会进行用户态检验 1521bf4a4899SLoGin let mut iovecs = unsafe { IoVecs::from_user(iov as *const IoVec, count, true) }?; 1522bf4a4899SLoGin 1523b5b571e0SLoGin let mut data = vec![0; iovecs.0.iter().map(|x| x.len()).sum()]; 1524bf4a4899SLoGin 1525bf4a4899SLoGin let len = Self::read(fd, &mut data)?; 1526bf4a4899SLoGin 1527bf4a4899SLoGin iovecs.scatter(&data[..len]); 1528bf4a4899SLoGin 1529bf4a4899SLoGin return Ok(len); 1530bf4a4899SLoGin } 1531bf4a4899SLoGin readlink_at( dirfd: i32, path: *const u8, user_buf: *mut u8, buf_size: usize, ) -> Result<usize, SystemError>1532709498caSLoGin pub fn readlink_at( 1533709498caSLoGin dirfd: i32, 1534709498caSLoGin path: *const u8, 1535709498caSLoGin user_buf: *mut u8, 1536709498caSLoGin buf_size: usize, 1537709498caSLoGin ) -> Result<usize, SystemError> { 1538703ce5a7SLoGin let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))? 1539703ce5a7SLoGin .into_string() 1540703ce5a7SLoGin .map_err(|_| SystemError::EINVAL)?; 154182df0a13Shmt let path = path.as_str().trim(); 1542709498caSLoGin let mut user_buf = UserBufferWriter::new(user_buf, buf_size, true)?; 1543709498caSLoGin 1544b5b571e0SLoGin let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, path)?; 1545709498caSLoGin 1546709498caSLoGin let inode = inode.lookup(path.as_str())?; 1547709498caSLoGin if inode.metadata()?.file_type != FileType::SymLink { 1548709498caSLoGin return Err(SystemError::EINVAL); 1549709498caSLoGin } 1550709498caSLoGin 1551709498caSLoGin let ubuf = user_buf.buffer::<u8>(0).unwrap(); 1552709498caSLoGin 1553dfe53cf0SGnoCiYeH let file = File::new(inode, FileMode::O_RDONLY)?; 1554709498caSLoGin 1555709498caSLoGin let len = file.read(buf_size, ubuf)?; 1556709498caSLoGin 1557709498caSLoGin return Ok(len); 1558709498caSLoGin } 1559709498caSLoGin readlink( path: *const u8, user_buf: *mut u8, buf_size: usize, ) -> Result<usize, SystemError>1560709498caSLoGin pub fn readlink( 1561709498caSLoGin path: *const u8, 1562709498caSLoGin user_buf: *mut u8, 1563709498caSLoGin buf_size: usize, 1564709498caSLoGin ) -> Result<usize, SystemError> { 15659b0abe6dSLoGin return Self::readlink_at(AtFlags::AT_FDCWD.bits(), path, user_buf, buf_size); 15669b0abe6dSLoGin } 15679b0abe6dSLoGin access(pathname: *const u8, mode: u32) -> Result<usize, SystemError>15689b0abe6dSLoGin pub fn access(pathname: *const u8, mode: u32) -> Result<usize, SystemError> { 15699b0abe6dSLoGin return do_faccessat( 15709b0abe6dSLoGin AtFlags::AT_FDCWD.bits(), 15719b0abe6dSLoGin pathname, 1572bf4a4899SLoGin ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?, 15739b0abe6dSLoGin 0, 15749b0abe6dSLoGin ); 15759b0abe6dSLoGin } 15769b0abe6dSLoGin faccessat2( dirfd: i32, pathname: *const u8, mode: u32, flags: u32, ) -> Result<usize, SystemError>15779b0abe6dSLoGin pub fn faccessat2( 15789b0abe6dSLoGin dirfd: i32, 15799b0abe6dSLoGin pathname: *const u8, 15809b0abe6dSLoGin mode: u32, 15819b0abe6dSLoGin flags: u32, 15829b0abe6dSLoGin ) -> Result<usize, SystemError> { 1583bf4a4899SLoGin return do_faccessat( 1584bf4a4899SLoGin dirfd, 1585bf4a4899SLoGin pathname, 1586bf4a4899SLoGin ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?, 1587bf4a4899SLoGin flags, 1588bf4a4899SLoGin ); 1589bf4a4899SLoGin } 1590bf4a4899SLoGin chmod(pathname: *const u8, mode: u32) -> Result<usize, SystemError>1591bf4a4899SLoGin pub fn chmod(pathname: *const u8, mode: u32) -> Result<usize, SystemError> { 1592bf4a4899SLoGin return do_fchmodat( 1593bf4a4899SLoGin AtFlags::AT_FDCWD.bits(), 1594bf4a4899SLoGin pathname, 1595bf4a4899SLoGin ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?, 1596bf4a4899SLoGin ); 1597bf4a4899SLoGin } 1598bf4a4899SLoGin fchmodat(dirfd: i32, pathname: *const u8, mode: u32) -> Result<usize, SystemError>1599bf4a4899SLoGin pub fn fchmodat(dirfd: i32, pathname: *const u8, mode: u32) -> Result<usize, SystemError> { 1600bf4a4899SLoGin return do_fchmodat( 1601bf4a4899SLoGin dirfd, 1602bf4a4899SLoGin pathname, 1603bf4a4899SLoGin ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?, 1604bf4a4899SLoGin ); 1605bf4a4899SLoGin } 1606bf4a4899SLoGin fchmod(fd: i32, mode: u32) -> Result<usize, SystemError>1607bf4a4899SLoGin pub fn fchmod(fd: i32, mode: u32) -> Result<usize, SystemError> { 1608bf4a4899SLoGin let _mode = ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?; 1609bf4a4899SLoGin let binding = ProcessManager::current_pcb().fd_table(); 1610bf4a4899SLoGin let fd_table_guard = binding.read(); 1611bf4a4899SLoGin let _file = fd_table_guard 1612bf4a4899SLoGin .get_file_by_fd(fd) 1613bf4a4899SLoGin .ok_or(SystemError::EBADF)?; 1614bf4a4899SLoGin 1615bf4a4899SLoGin // fchmod没完全实现,因此不修改文件的权限 1616bf4a4899SLoGin // todo: 实现fchmod 16172eab6dd7S曾俊 warn!("fchmod not fully implemented"); 1618bf4a4899SLoGin return Ok(0); 1619709498caSLoGin } 16201d37ca6dSDonkey Kane /// #挂载文件系统 16211d37ca6dSDonkey Kane /// 16221d37ca6dSDonkey Kane /// 用于挂载文件系统,目前仅支持ramfs挂载 16231d37ca6dSDonkey Kane /// 16241d37ca6dSDonkey Kane /// ## 参数: 16251d37ca6dSDonkey Kane /// 16261d37ca6dSDonkey Kane /// - source 挂载设备(暂时不支持) 16271d37ca6dSDonkey Kane /// - target 挂载目录 16281d37ca6dSDonkey Kane /// - filesystemtype 文件系统 16291d37ca6dSDonkey Kane /// - mountflags 挂载选项(暂未实现) 16301d37ca6dSDonkey Kane /// - data 带数据挂载 16311d37ca6dSDonkey Kane /// 16321d37ca6dSDonkey Kane /// ## 返回值 16331d37ca6dSDonkey Kane /// - Ok(0): 挂载成功 16341d37ca6dSDonkey Kane /// - Err(SystemError) :挂载过程中出错 mount( _source: *const u8, target: *const u8, filesystemtype: *const u8, _mountflags: usize, _data: *const c_void, ) -> Result<usize, SystemError>16351d37ca6dSDonkey Kane pub fn mount( 16361d37ca6dSDonkey Kane _source: *const u8, 16371d37ca6dSDonkey Kane target: *const u8, 16381d37ca6dSDonkey Kane filesystemtype: *const u8, 16391d37ca6dSDonkey Kane _mountflags: usize, 16401d37ca6dSDonkey Kane _data: *const c_void, 16411d37ca6dSDonkey Kane ) -> Result<usize, SystemError> { 1642703ce5a7SLoGin let target = user_access::check_and_clone_cstr(target, Some(MAX_PATHLEN))? 1643703ce5a7SLoGin .into_string() 1644703ce5a7SLoGin .map_err(|_| SystemError::EINVAL)?; 16451d37ca6dSDonkey Kane 1646703ce5a7SLoGin let fstype_str = user_access::check_and_clone_cstr(filesystemtype, Some(MAX_PATHLEN))?; 1647703ce5a7SLoGin let fstype_str = fstype_str.to_str().map_err(|_| SystemError::EINVAL)?; 16481d37ca6dSDonkey Kane 1649703ce5a7SLoGin let fstype = producefs!(FSMAKER, fstype_str)?; 16501d37ca6dSDonkey Kane 1651703ce5a7SLoGin Vcore::do_mount(fstype, &target)?; 16521074eb34SSamuel Dai 16531074eb34SSamuel Dai return Ok(0); 16541d37ca6dSDonkey Kane } 16551d37ca6dSDonkey Kane 16561d37ca6dSDonkey Kane // 想法:可以在VFS中实现一个文件系统分发器,流程如下: 16571d37ca6dSDonkey Kane // 1. 接受从上方传来的文件类型字符串 16581d37ca6dSDonkey Kane // 2. 将传入值与启动时准备好的字符串数组逐个比较(probe) 16591d37ca6dSDonkey Kane // 3. 直接在函数内调用构造方法并直接返回文件系统对象 16601074eb34SSamuel Dai 16611074eb34SSamuel Dai /// src/linux/mount.c `umount` & `umount2` 16621074eb34SSamuel Dai /// 16631074eb34SSamuel Dai /// [umount(2) — Linux manual page](https://www.man7.org/linux/man-pages/man2/umount.2.html) umount2(target: *const u8, flags: i32) -> Result<(), SystemError>16641074eb34SSamuel Dai pub fn umount2(target: *const u8, flags: i32) -> Result<(), SystemError> { 1665703ce5a7SLoGin let target = user_access::check_and_clone_cstr(target, Some(MAX_PATHLEN))? 1666703ce5a7SLoGin .into_string() 1667703ce5a7SLoGin .map_err(|_| SystemError::EINVAL)?; 16681074eb34SSamuel Dai Vcore::do_umount2( 16691074eb34SSamuel Dai AtFlags::AT_FDCWD.bits(), 16701074eb34SSamuel Dai &target, 16711074eb34SSamuel Dai UmountFlag::from_bits(flags).ok_or(SystemError::EINVAL)?, 16721074eb34SSamuel Dai )?; 16731074eb34SSamuel Dai return Ok(()); 16741074eb34SSamuel Dai } 16756f189d27Slinfeng sys_utimensat( dirfd: i32, pathname: *const u8, times: *const PosixTimeSpec, flags: u32, ) -> Result<usize, SystemError>16766f189d27Slinfeng pub fn sys_utimensat( 16776f189d27Slinfeng dirfd: i32, 16786f189d27Slinfeng pathname: *const u8, 16796f189d27Slinfeng times: *const PosixTimeSpec, 16806f189d27Slinfeng flags: u32, 16816f189d27Slinfeng ) -> Result<usize, SystemError> { 16826f189d27Slinfeng let pathname = if pathname.is_null() { 16836f189d27Slinfeng None 16846f189d27Slinfeng } else { 1685703ce5a7SLoGin let pathname = check_and_clone_cstr(pathname, Some(MAX_PATHLEN))? 1686703ce5a7SLoGin .into_string() 1687703ce5a7SLoGin .map_err(|_| SystemError::EINVAL)?; 16886f189d27Slinfeng Some(pathname) 16896f189d27Slinfeng }; 16906f189d27Slinfeng let flags = UtimensFlags::from_bits(flags).ok_or(SystemError::EINVAL)?; 16916f189d27Slinfeng let times = if times.is_null() { 16926f189d27Slinfeng None 16936f189d27Slinfeng } else { 16946f189d27Slinfeng let times_reader = UserBufferReader::new(times, size_of::<PosixTimeSpec>() * 2, true)?; 16956f189d27Slinfeng let times = times_reader.read_from_user::<PosixTimeSpec>(0)?; 16966f189d27Slinfeng Some([times[0], times[1]]) 16976f189d27Slinfeng }; 16986f189d27Slinfeng do_utimensat(dirfd, pathname, times, flags) 16996f189d27Slinfeng } 17006f189d27Slinfeng sys_utimes( pathname: *const u8, times: *const PosixTimeval, ) -> Result<usize, SystemError>17016f189d27Slinfeng pub fn sys_utimes( 17026f189d27Slinfeng pathname: *const u8, 17036f189d27Slinfeng times: *const PosixTimeval, 17046f189d27Slinfeng ) -> Result<usize, SystemError> { 1705703ce5a7SLoGin let pathname = check_and_clone_cstr(pathname, Some(MAX_PATHLEN))? 1706703ce5a7SLoGin .into_string() 1707703ce5a7SLoGin .map_err(|_| SystemError::EINVAL)?; 17086f189d27Slinfeng let times = if times.is_null() { 17096f189d27Slinfeng None 17106f189d27Slinfeng } else { 17116f189d27Slinfeng let times_reader = UserBufferReader::new(times, size_of::<PosixTimeval>() * 2, true)?; 17126f189d27Slinfeng let times = times_reader.read_from_user::<PosixTimeval>(0)?; 17136f189d27Slinfeng Some([times[0], times[1]]) 17146f189d27Slinfeng }; 17156f189d27Slinfeng do_utimes(&pathname, times) 17166f189d27Slinfeng } 1717709498caSLoGin } 1718709498caSLoGin 1719cde5492fSlogin #[repr(C)] 1720cde5492fSlogin #[derive(Debug, Clone, Copy)] 1721cde5492fSlogin pub struct IoVec { 1722cde5492fSlogin /// 缓冲区的起始地址 1723cde5492fSlogin pub iov_base: *mut u8, 1724cde5492fSlogin /// 缓冲区的长度 1725cde5492fSlogin pub iov_len: usize, 1726cde5492fSlogin } 1727cde5492fSlogin 1728cde5492fSlogin /// 用于存储多个来自用户空间的IoVec 1729cde5492fSlogin /// 1730cde5492fSlogin /// 由于目前内核中的文件系统还不支持分散读写,所以暂时只支持将用户空间的IoVec聚合成一个缓冲区,然后进行操作。 1731cde5492fSlogin /// TODO:支持分散读写 1732cde5492fSlogin #[derive(Debug)] 1733cde5492fSlogin pub struct IoVecs(Vec<&'static mut [u8]>); 1734cde5492fSlogin 1735cde5492fSlogin impl IoVecs { 1736cde5492fSlogin /// 从用户空间的IoVec中构造IoVecs 1737cde5492fSlogin /// 1738cde5492fSlogin /// @param iov 用户空间的IoVec 1739cde5492fSlogin /// @param iovcnt 用户空间的IoVec的数量 1740cde5492fSlogin /// @param readv 是否为readv系统调用 1741cde5492fSlogin /// 1742cde5492fSlogin /// @return 构造成功返回IoVecs,否则返回错误码 from_user( iov: *const IoVec, iovcnt: usize, _readv: bool, ) -> Result<Self, SystemError>1743cde5492fSlogin pub unsafe fn from_user( 1744cde5492fSlogin iov: *const IoVec, 1745cde5492fSlogin iovcnt: usize, 1746cde5492fSlogin _readv: bool, 1747cde5492fSlogin ) -> Result<Self, SystemError> { 1748cde5492fSlogin // 检查iov指针所在空间是否合法 17494fda81ceSLoGin verify_area( 17504fda81ceSLoGin VirtAddr::new(iov as usize), 17514fda81ceSLoGin iovcnt * core::mem::size_of::<IoVec>(), 17524fda81ceSLoGin ) 17534fda81ceSLoGin .map_err(|_| SystemError::EFAULT)?; 1754cde5492fSlogin 1755cde5492fSlogin // 将用户空间的IoVec转换为引用(注意:这里的引用是静态的,因为用户空间的IoVec不会被释放) 1756cde5492fSlogin let iovs: &[IoVec] = core::slice::from_raw_parts(iov, iovcnt); 1757cde5492fSlogin 1758bd70d2d1SLoGin let mut slices: Vec<&mut [u8]> = Vec::with_capacity(iovs.len()); 1759cde5492fSlogin 1760cde5492fSlogin for iov in iovs.iter() { 1761cde5492fSlogin if iov.iov_len == 0 { 1762cde5492fSlogin continue; 1763cde5492fSlogin } 1764cde5492fSlogin 17654fda81ceSLoGin verify_area( 17664fda81ceSLoGin VirtAddr::new(iov.iov_base as usize), 17674fda81ceSLoGin iovcnt * core::mem::size_of::<IoVec>(), 17684fda81ceSLoGin ) 17694fda81ceSLoGin .map_err(|_| SystemError::EFAULT)?; 1770cde5492fSlogin 1771cde5492fSlogin slices.push(core::slice::from_raw_parts_mut(iov.iov_base, iov.iov_len)); 1772cde5492fSlogin } 1773cde5492fSlogin 1774cde5492fSlogin return Ok(Self(slices)); 1775cde5492fSlogin } 1776cde5492fSlogin 1777cde5492fSlogin /// @brief 将IoVecs中的数据聚合到一个缓冲区中 1778cde5492fSlogin /// 1779cde5492fSlogin /// @return 返回聚合后的缓冲区 gather(&self) -> Vec<u8>1780cde5492fSlogin pub fn gather(&self) -> Vec<u8> { 1781cde5492fSlogin let mut buf = Vec::new(); 1782cde5492fSlogin for slice in self.0.iter() { 1783cde5492fSlogin buf.extend_from_slice(slice); 1784cde5492fSlogin } 1785cde5492fSlogin return buf; 1786cde5492fSlogin } 1787cde5492fSlogin 1788cde5492fSlogin /// @brief 将给定的数据分散写入到IoVecs中 scatter(&mut self, data: &[u8])1789cde5492fSlogin pub fn scatter(&mut self, data: &[u8]) { 1790cde5492fSlogin let mut data: &[u8] = data; 1791cde5492fSlogin for slice in self.0.iter_mut() { 1792cde5492fSlogin let len = core::cmp::min(slice.len(), data.len()); 1793cde5492fSlogin if len == 0 { 1794cde5492fSlogin continue; 1795cde5492fSlogin } 1796cde5492fSlogin 1797cde5492fSlogin slice[..len].copy_from_slice(&data[..len]); 1798cde5492fSlogin data = &data[len..]; 1799cde5492fSlogin } 1800cde5492fSlogin } 1801cde5492fSlogin 1802cde5492fSlogin /// @brief 创建与IoVecs等长的缓冲区 1803cde5492fSlogin /// 1804cde5492fSlogin /// @param set_len 是否设置返回的Vec的len。 1805cde5492fSlogin /// 如果为true,则返回的Vec的len为所有IoVec的长度之和; 1806cde5492fSlogin /// 否则返回的Vec的len为0,capacity为所有IoVec的长度之和. 1807cde5492fSlogin /// 1808cde5492fSlogin /// @return 返回创建的缓冲区 new_buf(&self, set_len: bool) -> Vec<u8>1809cde5492fSlogin pub fn new_buf(&self, set_len: bool) -> Vec<u8> { 1810cde5492fSlogin let total_len: usize = self.0.iter().map(|slice| slice.len()).sum(); 1811cde5492fSlogin let mut buf: Vec<u8> = Vec::with_capacity(total_len); 1812cde5492fSlogin 1813cde5492fSlogin if set_len { 18147ae679ddSLoGin buf.resize(total_len, 0); 1815cde5492fSlogin } 1816cde5492fSlogin return buf; 1817cde5492fSlogin } 1818cde5492fSlogin } 1819