11d37ca6dSDonkey Kane use core::ffi::c_void; 282df0a13Shmt use core::mem::size_of; 32dbef785SGnoCiYeH 482df0a13Shmt use alloc::{string::String, sync::Arc, vec::Vec}; 591e9d4abSLoGin use system_error::SystemError; 6004e86ffSlogin 71d37ca6dSDonkey Kane use crate::producefs; 8004e86ffSlogin use crate::{ 9c566df45SLoGin driver::base::{block::SeekFrom, device::device_number::DeviceNumber}, 101d37ca6dSDonkey Kane filesystem::vfs::{core as Vcore, file::FileDescriptorVec}, 111d37ca6dSDonkey Kane kerror, 121496ba7bSLoGin libs::rwlock::RwLockWriteGuard, 134fda81ceSLoGin mm::{verify_area, VirtAddr}, 141496ba7bSLoGin process::ProcessManager, 15709498caSLoGin syscall::{ 161d37ca6dSDonkey Kane user_access::{self, check_and_clone_cstr, UserBufferWriter}, 1791e9d4abSLoGin Syscall, 18709498caSLoGin }, 1967b48188Shoumkh time::TimeSpec, 20004e86ffSlogin }; 21004e86ffSlogin 22004e86ffSlogin use super::{ 23ab5c8ca4Slogin core::{do_mkdir, do_remove_dir, do_unlink_at}, 24709498caSLoGin fcntl::{AtFlags, FcntlCommand, FD_CLOEXEC}, 25004e86ffSlogin file::{File, FileMode}, 260fb515b0SLoGin open::{do_faccessat, do_fchmodat, do_sys_open}, 279b0abe6dSLoGin utils::{rsplit_path, user_path_at}, 281d37ca6dSDonkey Kane Dirent, FileType, IndexNode, FSMAKER, MAX_PATHLEN, ROOT_INODE, VFS_MAX_FOLLOW_SYMLINK_TIMES, 29004e86ffSlogin }; 3040314b30SXiaoye Zheng // use crate::kdebug; 31004e86ffSlogin 32ab5c8ca4Slogin pub const SEEK_SET: u32 = 0; 33ab5c8ca4Slogin pub const SEEK_CUR: u32 = 1; 34ab5c8ca4Slogin pub const SEEK_END: u32 = 2; 35ab5c8ca4Slogin pub const SEEK_MAX: u32 = 3; 36004e86ffSlogin 3767b48188Shoumkh bitflags! { 3867b48188Shoumkh /// 文件类型和权限 396b4e7a29SLoGin #[repr(C)] 4067b48188Shoumkh pub struct ModeType: u32 { 4167b48188Shoumkh /// 掩码 4267b48188Shoumkh const S_IFMT = 0o0_170_000; 4367b48188Shoumkh /// 文件类型 4467b48188Shoumkh const S_IFSOCK = 0o140000; 4567b48188Shoumkh const S_IFLNK = 0o120000; 4667b48188Shoumkh const S_IFREG = 0o100000; 4767b48188Shoumkh const S_IFBLK = 0o060000; 4867b48188Shoumkh const S_IFDIR = 0o040000; 4967b48188Shoumkh const S_IFCHR = 0o020000; 5067b48188Shoumkh const S_IFIFO = 0o010000; 5167b48188Shoumkh 5267b48188Shoumkh const S_ISUID = 0o004000; 5367b48188Shoumkh const S_ISGID = 0o002000; 5467b48188Shoumkh const S_ISVTX = 0o001000; 5567b48188Shoumkh /// 文件用户权限 5667b48188Shoumkh const S_IRWXU = 0o0700; 5767b48188Shoumkh const S_IRUSR = 0o0400; 5867b48188Shoumkh const S_IWUSR = 0o0200; 5967b48188Shoumkh const S_IXUSR = 0o0100; 6067b48188Shoumkh /// 文件组权限 6167b48188Shoumkh const S_IRWXG = 0o0070; 6267b48188Shoumkh const S_IRGRP = 0o0040; 6367b48188Shoumkh const S_IWGRP = 0o0020; 6467b48188Shoumkh const S_IXGRP = 0o0010; 6567b48188Shoumkh /// 文件其他用户权限 6667b48188Shoumkh const S_IRWXO = 0o0007; 6767b48188Shoumkh const S_IROTH = 0o0004; 6867b48188Shoumkh const S_IWOTH = 0o0002; 6967b48188Shoumkh const S_IXOTH = 0o0001; 7006d5e247SLoGin 7106d5e247SLoGin /// 0o777 7206d5e247SLoGin const S_IRWXUGO = Self::S_IRWXU.bits | Self::S_IRWXG.bits | Self::S_IRWXO.bits; 7306d5e247SLoGin /// 0o7777 7406d5e247SLoGin const S_IALLUGO = Self::S_ISUID.bits | Self::S_ISGID.bits | Self::S_ISVTX.bits| Self::S_IRWXUGO.bits; 7506d5e247SLoGin /// 0o444 7606d5e247SLoGin const S_IRUGO = Self::S_IRUSR.bits | Self::S_IRGRP.bits | Self::S_IROTH.bits; 7706d5e247SLoGin /// 0o222 7806d5e247SLoGin const S_IWUGO = Self::S_IWUSR.bits | Self::S_IWGRP.bits | Self::S_IWOTH.bits; 7906d5e247SLoGin /// 0o111 8006d5e247SLoGin const S_IXUGO = Self::S_IXUSR.bits | Self::S_IXGRP.bits | Self::S_IXOTH.bits; 8106d5e247SLoGin 8206d5e247SLoGin 8367b48188Shoumkh } 8467b48188Shoumkh } 8567b48188Shoumkh 8667b48188Shoumkh #[repr(C)] 8782df0a13Shmt #[derive(Clone, Copy)] 8867b48188Shoumkh /// # 文件信息结构体 8967b48188Shoumkh pub struct PosixKstat { 9067b48188Shoumkh /// 硬件设备ID 9167b48188Shoumkh dev_id: u64, 9267b48188Shoumkh /// inode号 9367b48188Shoumkh inode: u64, 9467b48188Shoumkh /// 硬链接数 9567b48188Shoumkh nlink: u64, 9667b48188Shoumkh /// 文件权限 9767b48188Shoumkh mode: ModeType, 9867b48188Shoumkh /// 所有者用户ID 9967b48188Shoumkh uid: i32, 10067b48188Shoumkh /// 所有者组ID 10167b48188Shoumkh gid: i32, 10267b48188Shoumkh /// 设备ID 10367b48188Shoumkh rdev: i64, 10467b48188Shoumkh /// 文件大小 10567b48188Shoumkh size: i64, 10667b48188Shoumkh /// 文件系统块大小 10767b48188Shoumkh blcok_size: i64, 10867b48188Shoumkh /// 分配的512B块数 10967b48188Shoumkh blocks: u64, 11067b48188Shoumkh /// 最后访问时间 11167b48188Shoumkh atime: TimeSpec, 11267b48188Shoumkh /// 最后修改时间 11367b48188Shoumkh mtime: TimeSpec, 11467b48188Shoumkh /// 最后状态变化时间 11567b48188Shoumkh ctime: TimeSpec, 11667b48188Shoumkh /// 用于填充结构体大小的空白数据 11767b48188Shoumkh pub _pad: [i8; 24], 11867b48188Shoumkh } 11967b48188Shoumkh impl PosixKstat { 12067b48188Shoumkh fn new() -> Self { 12167b48188Shoumkh Self { 12267b48188Shoumkh inode: 0, 12367b48188Shoumkh dev_id: 0, 12467b48188Shoumkh mode: ModeType { bits: 0 }, 12567b48188Shoumkh nlink: 0, 12667b48188Shoumkh uid: 0, 12767b48188Shoumkh gid: 0, 12867b48188Shoumkh rdev: 0, 12967b48188Shoumkh size: 0, 13067b48188Shoumkh atime: TimeSpec { 13167b48188Shoumkh tv_sec: 0, 13267b48188Shoumkh tv_nsec: 0, 13367b48188Shoumkh }, 13467b48188Shoumkh mtime: TimeSpec { 13567b48188Shoumkh tv_sec: 0, 13667b48188Shoumkh tv_nsec: 0, 13767b48188Shoumkh }, 13867b48188Shoumkh ctime: TimeSpec { 13967b48188Shoumkh tv_sec: 0, 14067b48188Shoumkh tv_nsec: 0, 14167b48188Shoumkh }, 14267b48188Shoumkh blcok_size: 0, 14367b48188Shoumkh blocks: 0, 14467b48188Shoumkh _pad: Default::default(), 14567b48188Shoumkh } 14667b48188Shoumkh } 14767b48188Shoumkh } 1480fb515b0SLoGin 149*b4eb05a1STTaq #[repr(C)] 150*b4eb05a1STTaq #[derive(Clone, Copy)] 151*b4eb05a1STTaq /// # 文件信息结构体X 152*b4eb05a1STTaq pub struct PosixStatx { 153*b4eb05a1STTaq /* 0x00 */ 154*b4eb05a1STTaq stx_mask: PosixStatxMask, 155*b4eb05a1STTaq /// 文件系统块大小 156*b4eb05a1STTaq stx_blksize: u32, 157*b4eb05a1STTaq /// Flags conveying information about the file [uncond] 158*b4eb05a1STTaq stx_attributes: StxAttributes, 159*b4eb05a1STTaq /* 0x10 */ 160*b4eb05a1STTaq /// 硬链接数 161*b4eb05a1STTaq stx_nlink: u32, 162*b4eb05a1STTaq /// 所有者用户ID 163*b4eb05a1STTaq stx_uid: u32, 164*b4eb05a1STTaq /// 所有者组ID 165*b4eb05a1STTaq stx_gid: u32, 166*b4eb05a1STTaq /// 文件权限 167*b4eb05a1STTaq stx_mode: ModeType, 168*b4eb05a1STTaq 169*b4eb05a1STTaq /* 0x20 */ 170*b4eb05a1STTaq /// inode号 171*b4eb05a1STTaq stx_inode: u64, 172*b4eb05a1STTaq /// 文件大小 173*b4eb05a1STTaq stx_size: i64, 174*b4eb05a1STTaq /// 分配的512B块数 175*b4eb05a1STTaq stx_blocks: u64, 176*b4eb05a1STTaq /// Mask to show what's supported in stx_attributes 177*b4eb05a1STTaq stx_attributes_mask: StxAttributes, 178*b4eb05a1STTaq 179*b4eb05a1STTaq /* 0x40 */ 180*b4eb05a1STTaq /// 最后访问时间 181*b4eb05a1STTaq stx_atime: TimeSpec, 182*b4eb05a1STTaq /// 文件创建时间 183*b4eb05a1STTaq stx_btime: TimeSpec, 184*b4eb05a1STTaq /// 最后状态变化时间 185*b4eb05a1STTaq stx_ctime: TimeSpec, 186*b4eb05a1STTaq /// 最后修改时间 187*b4eb05a1STTaq stx_mtime: TimeSpec, 188*b4eb05a1STTaq 189*b4eb05a1STTaq /* 0x80 */ 190*b4eb05a1STTaq /// 主设备ID 191*b4eb05a1STTaq stx_rdev_major: u32, 192*b4eb05a1STTaq /// 次设备ID 193*b4eb05a1STTaq stx_rdev_minor: u32, 194*b4eb05a1STTaq /// 主硬件设备ID 195*b4eb05a1STTaq stx_dev_major: u32, 196*b4eb05a1STTaq /// 次硬件设备ID 197*b4eb05a1STTaq stx_dev_minor: u32, 198*b4eb05a1STTaq 199*b4eb05a1STTaq /* 0x90 */ 200*b4eb05a1STTaq stx_mnt_id: u64, 201*b4eb05a1STTaq stx_dio_mem_align: u32, 202*b4eb05a1STTaq stx_dio_offset_align: u32, 203*b4eb05a1STTaq } 204*b4eb05a1STTaq impl PosixStatx { 205*b4eb05a1STTaq fn new() -> Self { 206*b4eb05a1STTaq Self { 207*b4eb05a1STTaq stx_mask: PosixStatxMask::STATX_BASIC_STATS, 208*b4eb05a1STTaq stx_blksize: 0, 209*b4eb05a1STTaq stx_attributes: StxAttributes::STATX_ATTR_APPEND, 210*b4eb05a1STTaq stx_nlink: 0, 211*b4eb05a1STTaq stx_uid: 0, 212*b4eb05a1STTaq stx_gid: 0, 213*b4eb05a1STTaq stx_mode: ModeType { bits: 0 }, 214*b4eb05a1STTaq stx_inode: 0, 215*b4eb05a1STTaq stx_size: 0, 216*b4eb05a1STTaq stx_blocks: 0, 217*b4eb05a1STTaq stx_attributes_mask: StxAttributes::STATX_ATTR_APPEND, 218*b4eb05a1STTaq stx_atime: TimeSpec { 219*b4eb05a1STTaq tv_sec: 0, 220*b4eb05a1STTaq tv_nsec: 0, 221*b4eb05a1STTaq }, 222*b4eb05a1STTaq stx_btime: TimeSpec { 223*b4eb05a1STTaq tv_sec: 0, 224*b4eb05a1STTaq tv_nsec: 0, 225*b4eb05a1STTaq }, 226*b4eb05a1STTaq stx_ctime: TimeSpec { 227*b4eb05a1STTaq tv_sec: 0, 228*b4eb05a1STTaq tv_nsec: 0, 229*b4eb05a1STTaq }, 230*b4eb05a1STTaq stx_mtime: TimeSpec { 231*b4eb05a1STTaq tv_sec: 0, 232*b4eb05a1STTaq tv_nsec: 0, 233*b4eb05a1STTaq }, 234*b4eb05a1STTaq stx_rdev_major: 0, 235*b4eb05a1STTaq stx_rdev_minor: 0, 236*b4eb05a1STTaq stx_dev_major: 0, 237*b4eb05a1STTaq stx_dev_minor: 0, 238*b4eb05a1STTaq stx_mnt_id: 0, 239*b4eb05a1STTaq stx_dio_mem_align: 0, 240*b4eb05a1STTaq stx_dio_offset_align: 0, 241*b4eb05a1STTaq } 242*b4eb05a1STTaq } 243*b4eb05a1STTaq } 244*b4eb05a1STTaq 245*b4eb05a1STTaq bitflags! { 246*b4eb05a1STTaq pub struct PosixStatxMask: u32{ 247*b4eb05a1STTaq /// Want stx_mode & S_IFMT 248*b4eb05a1STTaq const STATX_TYPE = 0x00000001; 249*b4eb05a1STTaq 250*b4eb05a1STTaq /// Want stx_mode & ~S_IFMT 251*b4eb05a1STTaq const STATX_MODE = 0x00000002; 252*b4eb05a1STTaq 253*b4eb05a1STTaq /// Want stx_nlink 254*b4eb05a1STTaq const STATX_NLINK = 0x00000004; 255*b4eb05a1STTaq 256*b4eb05a1STTaq /// Want stx_uid 257*b4eb05a1STTaq const STATX_UID = 0x00000008; 258*b4eb05a1STTaq 259*b4eb05a1STTaq /// Want stx_gid 260*b4eb05a1STTaq const STATX_GID = 0x00000010; 261*b4eb05a1STTaq 262*b4eb05a1STTaq /// Want stx_atime 263*b4eb05a1STTaq const STATX_ATIME = 0x00000020; 264*b4eb05a1STTaq 265*b4eb05a1STTaq /// Want stx_mtime 266*b4eb05a1STTaq const STATX_MTIME = 0x00000040; 267*b4eb05a1STTaq 268*b4eb05a1STTaq /// Want stx_ctime 269*b4eb05a1STTaq const STATX_CTIME = 0x00000080; 270*b4eb05a1STTaq 271*b4eb05a1STTaq /// Want stx_ino 272*b4eb05a1STTaq const STATX_INO = 0x00000100; 273*b4eb05a1STTaq 274*b4eb05a1STTaq /// Want stx_size 275*b4eb05a1STTaq const STATX_SIZE = 0x00000200; 276*b4eb05a1STTaq 277*b4eb05a1STTaq /// Want stx_blocks 278*b4eb05a1STTaq const STATX_BLOCKS = 0x00000400; 279*b4eb05a1STTaq 280*b4eb05a1STTaq /// [All of the above] 281*b4eb05a1STTaq const STATX_BASIC_STATS = 0x000007ff; 282*b4eb05a1STTaq 283*b4eb05a1STTaq /// Want stx_btime 284*b4eb05a1STTaq const STATX_BTIME = 0x00000800; 285*b4eb05a1STTaq 286*b4eb05a1STTaq /// The same as STATX_BASIC_STATS | STATX_BTIME. 287*b4eb05a1STTaq /// It is deprecated and should not be used. 288*b4eb05a1STTaq const STATX_ALL = 0x00000fff; 289*b4eb05a1STTaq 290*b4eb05a1STTaq /// Want stx_mnt_id (since Linux 5.8) 291*b4eb05a1STTaq const STATX_MNT_ID = 0x00001000; 292*b4eb05a1STTaq 293*b4eb05a1STTaq /// Want stx_dio_mem_align and stx_dio_offset_align 294*b4eb05a1STTaq /// (since Linux 6.1; support varies by filesystem) 295*b4eb05a1STTaq const STATX_DIOALIGN = 0x00002000; 296*b4eb05a1STTaq 297*b4eb05a1STTaq /// Reserved for future struct statx expansion 298*b4eb05a1STTaq const STATX_RESERVED = 0x80000000; 299*b4eb05a1STTaq } 300*b4eb05a1STTaq } 301*b4eb05a1STTaq 302*b4eb05a1STTaq bitflags! { 303*b4eb05a1STTaq pub struct StxAttributes: u64 { 304*b4eb05a1STTaq /// 文件被文件系统压缩 305*b4eb05a1STTaq const STATX_ATTR_COMPRESSED = 0x00000004; 306*b4eb05a1STTaq /// 文件被标记为不可修改 307*b4eb05a1STTaq const STATX_ATTR_IMMUTABLE = 0x00000010; 308*b4eb05a1STTaq /// 文件是只追加写入的 309*b4eb05a1STTaq const STATX_ATTR_APPEND = 0x00000020; 310*b4eb05a1STTaq /// 文件不会被备份 311*b4eb05a1STTaq const STATX_ATTR_NODUMP = 0x00000040; 312*b4eb05a1STTaq /// 文件需要密钥才能在文件系统中解密 313*b4eb05a1STTaq const STATX_ATTR_ENCRYPTED = 0x00000800; 314*b4eb05a1STTaq /// 目录是自动挂载触发器 315*b4eb05a1STTaq const STATX_ATTR_AUTOMOUNT = 0x00001000; 316*b4eb05a1STTaq /// 目录是挂载点的根目录 317*b4eb05a1STTaq const STATX_ATTR_MOUNT_ROOT = 0x00002000; 318*b4eb05a1STTaq /// 文件受到 Verity 保护 319*b4eb05a1STTaq const STATX_ATTR_VERITY = 0x00100000; 320*b4eb05a1STTaq /// 文件当前处于 DAX 状态 CPU直接访问 321*b4eb05a1STTaq const STATX_ATTR_DAX = 0x00200000; 322*b4eb05a1STTaq } 323*b4eb05a1STTaq } 324*b4eb05a1STTaq 3250fb515b0SLoGin /// 3260fb515b0SLoGin /// Arguments for how openat2(2) should open the target path. If only @flags and 3270fb515b0SLoGin /// @mode are non-zero, then openat2(2) operates very similarly to openat(2). 3280fb515b0SLoGin /// 3290fb515b0SLoGin /// However, unlike openat(2), unknown or invalid bits in @flags result in 3300fb515b0SLoGin /// -EINVAL rather than being silently ignored. @mode must be zero unless one of 3310fb515b0SLoGin /// {O_CREAT, O_TMPFILE} are set. 3320fb515b0SLoGin /// 3330fb515b0SLoGin /// ## 成员变量 3340fb515b0SLoGin /// 3350fb515b0SLoGin /// - flags: O_* flags. 3360fb515b0SLoGin /// - mode: O_CREAT/O_TMPFILE file mode. 3370fb515b0SLoGin /// - resolve: RESOLVE_* flags. 3380fb515b0SLoGin #[derive(Debug, Clone, Copy)] 3390fb515b0SLoGin #[repr(C)] 3400fb515b0SLoGin pub struct PosixOpenHow { 3410fb515b0SLoGin pub flags: u64, 3420fb515b0SLoGin pub mode: u64, 3430fb515b0SLoGin pub resolve: u64, 3440fb515b0SLoGin } 3450fb515b0SLoGin 3460fb515b0SLoGin impl PosixOpenHow { 3470fb515b0SLoGin #[allow(dead_code)] 3480fb515b0SLoGin pub fn new(flags: u64, mode: u64, resolve: u64) -> Self { 3490fb515b0SLoGin Self { 3500fb515b0SLoGin flags, 3510fb515b0SLoGin mode, 3520fb515b0SLoGin resolve, 3530fb515b0SLoGin } 3540fb515b0SLoGin } 3550fb515b0SLoGin } 3560fb515b0SLoGin 3570fb515b0SLoGin #[derive(Debug, Clone, Copy)] 3580fb515b0SLoGin pub struct OpenHow { 3590fb515b0SLoGin pub o_flags: FileMode, 3600fb515b0SLoGin pub mode: ModeType, 3610fb515b0SLoGin pub resolve: OpenHowResolve, 3620fb515b0SLoGin } 3630fb515b0SLoGin 3640fb515b0SLoGin impl OpenHow { 3650fb515b0SLoGin pub fn new(mut o_flags: FileMode, mut mode: ModeType, resolve: OpenHowResolve) -> Self { 3660fb515b0SLoGin if !o_flags.contains(FileMode::O_CREAT) { 3670fb515b0SLoGin mode = ModeType::empty(); 3680fb515b0SLoGin } 3690fb515b0SLoGin 3700fb515b0SLoGin if o_flags.contains(FileMode::O_PATH) { 3710fb515b0SLoGin o_flags = o_flags.intersection(FileMode::O_PATH_FLAGS); 3720fb515b0SLoGin } 3730fb515b0SLoGin 3740fb515b0SLoGin Self { 3750fb515b0SLoGin o_flags, 3760fb515b0SLoGin mode, 3770fb515b0SLoGin resolve, 3780fb515b0SLoGin } 3790fb515b0SLoGin } 3800fb515b0SLoGin } 3810fb515b0SLoGin 3820fb515b0SLoGin impl From<PosixOpenHow> for OpenHow { 3830fb515b0SLoGin fn from(posix_open_how: PosixOpenHow) -> Self { 3840fb515b0SLoGin let o_flags = FileMode::from_bits_truncate(posix_open_how.flags as u32); 3850fb515b0SLoGin let mode = ModeType::from_bits_truncate(posix_open_how.mode as u32); 3860fb515b0SLoGin let resolve = OpenHowResolve::from_bits_truncate(posix_open_how.resolve as u64); 3870fb515b0SLoGin return Self::new(o_flags, mode, resolve); 3880fb515b0SLoGin } 3890fb515b0SLoGin } 3900fb515b0SLoGin 3910fb515b0SLoGin bitflags! { 3920fb515b0SLoGin pub struct OpenHowResolve: u64{ 3930fb515b0SLoGin /// Block mount-point crossings 3940fb515b0SLoGin /// (including bind-mounts). 3950fb515b0SLoGin const RESOLVE_NO_XDEV = 0x01; 3960fb515b0SLoGin 3970fb515b0SLoGin /// Block traversal through procfs-style 3980fb515b0SLoGin /// "magic-links" 3990fb515b0SLoGin const RESOLVE_NO_MAGICLINKS = 0x02; 4000fb515b0SLoGin 4010fb515b0SLoGin /// Block traversal through all symlinks 4020fb515b0SLoGin /// (implies OEXT_NO_MAGICLINKS) 4030fb515b0SLoGin const RESOLVE_NO_SYMLINKS = 0x04; 4040fb515b0SLoGin /// Block "lexical" trickery like 4050fb515b0SLoGin /// "..", symlinks, and absolute 4060fb515b0SLoGin const RESOLVE_BENEATH = 0x08; 4070fb515b0SLoGin /// Make all jumps to "/" and ".." 4080fb515b0SLoGin /// be scoped inside the dirfd 4090fb515b0SLoGin /// (similar to chroot(2)). 4100fb515b0SLoGin const RESOLVE_IN_ROOT = 0x10; 4110fb515b0SLoGin // Only complete if resolution can be 4120fb515b0SLoGin // completed through cached lookup. May 4130fb515b0SLoGin // return -EAGAIN if that's not 4140fb515b0SLoGin // possible. 4150fb515b0SLoGin const RESOLVE_CACHED = 0x20; 4160fb515b0SLoGin } 4170fb515b0SLoGin } 418ab5c8ca4Slogin impl Syscall { 419ab5c8ca4Slogin /// @brief 为当前进程打开一个文件 420ab5c8ca4Slogin /// 421ab5c8ca4Slogin /// @param path 文件路径 422ab5c8ca4Slogin /// @param o_flags 打开文件的标志位 423ab5c8ca4Slogin /// 424ab5c8ca4Slogin /// @return 文件描述符编号,或者是错误码 4250fb515b0SLoGin pub fn open( 42682df0a13Shmt path: *const u8, 42782df0a13Shmt o_flags: u32, 42882df0a13Shmt mode: u32, 4290fb515b0SLoGin follow_symlink: bool, 4300fb515b0SLoGin ) -> Result<usize, SystemError> { 43182df0a13Shmt let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; 43282df0a13Shmt let open_flags: FileMode = FileMode::from_bits(o_flags).ok_or(SystemError::EINVAL)?; 43382df0a13Shmt let mode = ModeType::from_bits(mode as u32).ok_or(SystemError::EINVAL)?; 43482df0a13Shmt return do_sys_open( 43582df0a13Shmt AtFlags::AT_FDCWD.bits(), 43682df0a13Shmt &path, 43782df0a13Shmt open_flags, 43882df0a13Shmt mode, 43982df0a13Shmt follow_symlink, 44082df0a13Shmt ); 441ab5c8ca4Slogin } 442ab5c8ca4Slogin 4430fb515b0SLoGin pub fn openat( 4440fb515b0SLoGin dirfd: i32, 44582df0a13Shmt path: *const u8, 44682df0a13Shmt o_flags: u32, 44782df0a13Shmt mode: u32, 4480fb515b0SLoGin follow_symlink: bool, 4490fb515b0SLoGin ) -> Result<usize, SystemError> { 45082df0a13Shmt let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; 45182df0a13Shmt let open_flags: FileMode = FileMode::from_bits(o_flags).ok_or(SystemError::EINVAL)?; 45282df0a13Shmt let mode = ModeType::from_bits(mode as u32).ok_or(SystemError::EINVAL)?; 45382df0a13Shmt return do_sys_open(dirfd, &path, open_flags, mode, follow_symlink); 454ab5c8ca4Slogin } 455ab5c8ca4Slogin 456ab5c8ca4Slogin /// @brief 关闭文件 457ab5c8ca4Slogin /// 458ab5c8ca4Slogin /// @param fd 文件描述符编号 459ab5c8ca4Slogin /// 460ab5c8ca4Slogin /// @return 成功返回0,失败返回错误码 461ab5c8ca4Slogin pub fn close(fd: usize) -> Result<usize, SystemError> { 4621496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 4631496ba7bSLoGin let mut fd_table_guard = binding.write(); 4641496ba7bSLoGin 46534e6d6c8Syuyi2439 let res = fd_table_guard.drop_fd(fd as i32).map(|_| 0); 46634e6d6c8Syuyi2439 46734e6d6c8Syuyi2439 return res; 468ab5c8ca4Slogin } 469ab5c8ca4Slogin 47040314b30SXiaoye Zheng /// @brief 发送命令到文件描述符对应的设备, 47140314b30SXiaoye Zheng /// 47240314b30SXiaoye Zheng /// @param fd 文件描述符编号 47340314b30SXiaoye Zheng /// @param cmd 设备相关的请求类型 47440314b30SXiaoye Zheng /// 47540314b30SXiaoye Zheng /// @return Ok(usize) 成功返回0 47640314b30SXiaoye Zheng /// @return Err(SystemError) 读取失败,返回posix错误码 47740314b30SXiaoye Zheng pub fn ioctl(fd: usize, cmd: u32, data: usize) -> Result<usize, SystemError> { 47840314b30SXiaoye Zheng let binding = ProcessManager::current_pcb().fd_table(); 47940314b30SXiaoye Zheng let fd_table_guard = binding.read(); 48040314b30SXiaoye Zheng 48140314b30SXiaoye Zheng let file = fd_table_guard 48240314b30SXiaoye Zheng .get_file_by_fd(fd as i32) 48340314b30SXiaoye Zheng .ok_or(SystemError::EBADF)?; 48440314b30SXiaoye Zheng 48540314b30SXiaoye Zheng // drop guard 以避免无法调度的问题 48640314b30SXiaoye Zheng drop(fd_table_guard); 48752da9a59SGnoCiYeH let file = file.lock_no_preempt(); 48852da9a59SGnoCiYeH let r = file.inode().ioctl(cmd, data, &file.private_data); 48940314b30SXiaoye Zheng return r; 49040314b30SXiaoye Zheng } 49140314b30SXiaoye Zheng 492ab5c8ca4Slogin /// @brief 根据文件描述符,读取文件数据。尝试读取的数据长度与buf的长度相同。 493ab5c8ca4Slogin /// 494ab5c8ca4Slogin /// @param fd 文件描述符编号 49527b967a3S裕依 /// @param buf 输出缓冲区 496ab5c8ca4Slogin /// 497ab5c8ca4Slogin /// @return Ok(usize) 成功读取的数据的字节数 498ab5c8ca4Slogin /// @return Err(SystemError) 读取失败,返回posix错误码 499ab5c8ca4Slogin pub fn read(fd: i32, buf: &mut [u8]) -> Result<usize, SystemError> { 5001496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 5011496ba7bSLoGin let fd_table_guard = binding.read(); 5021496ba7bSLoGin 5031496ba7bSLoGin let file = fd_table_guard.get_file_by_fd(fd); 504ab5c8ca4Slogin if file.is_none() { 505ab5c8ca4Slogin return Err(SystemError::EBADF); 506ab5c8ca4Slogin } 5071496ba7bSLoGin // drop guard 以避免无法调度的问题 5081496ba7bSLoGin drop(fd_table_guard); 5091496ba7bSLoGin let file = file.unwrap(); 510ab5c8ca4Slogin 5111496ba7bSLoGin return file.lock_no_preempt().read(buf.len(), buf); 512ab5c8ca4Slogin } 513ab5c8ca4Slogin 514ab5c8ca4Slogin /// @brief 根据文件描述符,向文件写入数据。尝试写入的数据长度与buf的长度相同。 515ab5c8ca4Slogin /// 516ab5c8ca4Slogin /// @param fd 文件描述符编号 51727b967a3S裕依 /// @param buf 输入缓冲区 518ab5c8ca4Slogin /// 519ab5c8ca4Slogin /// @return Ok(usize) 成功写入的数据的字节数 520ab5c8ca4Slogin /// @return Err(SystemError) 写入失败,返回posix错误码 521ab5c8ca4Slogin pub fn write(fd: i32, buf: &[u8]) -> Result<usize, SystemError> { 5221496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 5231496ba7bSLoGin let fd_table_guard = binding.read(); 524ab5c8ca4Slogin 5251496ba7bSLoGin let file = fd_table_guard 5261496ba7bSLoGin .get_file_by_fd(fd) 5271496ba7bSLoGin .ok_or(SystemError::EBADF)?; 5281496ba7bSLoGin 5291496ba7bSLoGin // drop guard 以避免无法调度的问题 5301496ba7bSLoGin drop(fd_table_guard); 5311496ba7bSLoGin return file.lock_no_preempt().write(buf.len(), buf); 532ab5c8ca4Slogin } 533ab5c8ca4Slogin 534ab5c8ca4Slogin /// @brief 调整文件操作指针的位置 535ab5c8ca4Slogin /// 536ab5c8ca4Slogin /// @param fd 文件描述符编号 537ab5c8ca4Slogin /// @param seek 调整的方式 538ab5c8ca4Slogin /// 539ab5c8ca4Slogin /// @return Ok(usize) 调整后,文件访问指针相对于文件头部的偏移量 540ab5c8ca4Slogin /// @return Err(SystemError) 调整失败,返回posix错误码 54182df0a13Shmt pub fn lseek(fd: i32, offset: i64, seek: u32) -> Result<usize, SystemError> { 54282df0a13Shmt let seek = match seek { 54382df0a13Shmt SEEK_SET => Ok(SeekFrom::SeekSet(offset)), 54482df0a13Shmt SEEK_CUR => Ok(SeekFrom::SeekCurrent(offset)), 54582df0a13Shmt SEEK_END => Ok(SeekFrom::SeekEnd(offset)), 54682df0a13Shmt SEEK_MAX => Ok(SeekFrom::SeekEnd(0)), 54782df0a13Shmt _ => Err(SystemError::EINVAL), 54882df0a13Shmt }?; 54982df0a13Shmt 5501496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 5511496ba7bSLoGin let fd_table_guard = binding.read(); 5521496ba7bSLoGin let file = fd_table_guard 5531496ba7bSLoGin .get_file_by_fd(fd) 5541496ba7bSLoGin .ok_or(SystemError::EBADF)?; 5551496ba7bSLoGin 5561496ba7bSLoGin // drop guard 以避免无法调度的问题 5571496ba7bSLoGin drop(fd_table_guard); 5581496ba7bSLoGin return file.lock_no_preempt().lseek(seek); 559004e86ffSlogin } 560004e86ffSlogin 56127b967a3S裕依 /// # sys_pread64 系统调用的实际执行函数 56227b967a3S裕依 /// 56327b967a3S裕依 /// ## 参数 56427b967a3S裕依 /// - `fd`: 文件描述符 56527b967a3S裕依 /// - `buf`: 读出缓冲区 56627b967a3S裕依 /// - `len`: 要读取的字节数 56727b967a3S裕依 /// - `offset`: 文件偏移量 56827b967a3S裕依 pub fn pread(fd: i32, buf: &mut [u8], len: usize, offset: usize) -> Result<usize, SystemError> { 56927b967a3S裕依 let binding = ProcessManager::current_pcb().fd_table(); 57027b967a3S裕依 let fd_table_guard = binding.read(); 57127b967a3S裕依 57227b967a3S裕依 let file = fd_table_guard.get_file_by_fd(fd); 57327b967a3S裕依 if file.is_none() { 57427b967a3S裕依 return Err(SystemError::EBADF); 57527b967a3S裕依 } 57627b967a3S裕依 // drop guard 以避免无法调度的问题 57727b967a3S裕依 drop(fd_table_guard); 57827b967a3S裕依 let file = file.unwrap(); 57927b967a3S裕依 58027b967a3S裕依 return file.lock_no_preempt().pread(offset, len, buf); 58127b967a3S裕依 } 58227b967a3S裕依 58327b967a3S裕依 /// # sys_pwrite64 系统调用的实际执行函数 58427b967a3S裕依 /// 58527b967a3S裕依 /// ## 参数 58627b967a3S裕依 /// - `fd`: 文件描述符 58727b967a3S裕依 /// - `buf`: 写入缓冲区 58827b967a3S裕依 /// - `len`: 要写入的字节数 58927b967a3S裕依 /// - `offset`: 文件偏移量 59027b967a3S裕依 pub fn pwrite(fd: i32, buf: &[u8], len: usize, offset: usize) -> Result<usize, SystemError> { 59127b967a3S裕依 let binding = ProcessManager::current_pcb().fd_table(); 59227b967a3S裕依 let fd_table_guard = binding.read(); 59327b967a3S裕依 59427b967a3S裕依 let file = fd_table_guard.get_file_by_fd(fd); 59527b967a3S裕依 if file.is_none() { 59627b967a3S裕依 return Err(SystemError::EBADF); 59727b967a3S裕依 } 59827b967a3S裕依 // drop guard 以避免无法调度的问题 59927b967a3S裕依 drop(fd_table_guard); 60027b967a3S裕依 let file = file.unwrap(); 60127b967a3S裕依 60227b967a3S裕依 return file.lock_no_preempt().pwrite(offset, len, buf); 60327b967a3S裕依 } 60427b967a3S裕依 605004e86ffSlogin /// @brief 切换工作目录 606004e86ffSlogin /// 607004e86ffSlogin /// @param dest_path 目标路径 608004e86ffSlogin /// 609004e86ffSlogin /// @return 返回码 描述 610004e86ffSlogin /// 0 | 成功 611004e86ffSlogin /// 612004e86ffSlogin /// EACCESS | 权限不足 613004e86ffSlogin /// 614004e86ffSlogin /// ELOOP | 解析path时遇到路径循环 615004e86ffSlogin /// 616004e86ffSlogin /// ENAMETOOLONG | 路径名过长 617004e86ffSlogin /// 618004e86ffSlogin /// ENOENT | 目标文件或目录不存在 619004e86ffSlogin /// 620004e86ffSlogin /// ENODIR | 检索期间发现非目录项 621004e86ffSlogin /// 622004e86ffSlogin /// ENOMEM | 系统内存不足 623004e86ffSlogin /// 624004e86ffSlogin /// EFAULT | 错误的地址 625004e86ffSlogin /// 626004e86ffSlogin /// ENAMETOOLONG | 路径过长 62782df0a13Shmt pub fn chdir(path: *const u8) -> Result<usize, SystemError> { 62882df0a13Shmt if path.is_null() { 62982df0a13Shmt return Err(SystemError::EFAULT); 63082df0a13Shmt } 63182df0a13Shmt 63282df0a13Shmt let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; 6331496ba7bSLoGin let proc = ProcessManager::current_pcb(); 634ab5c8ca4Slogin // Copy path to kernel space to avoid some security issues 6351496ba7bSLoGin let mut new_path = String::from(""); 6361496ba7bSLoGin if path.len() > 0 { 6371496ba7bSLoGin let cwd = match path.as_bytes()[0] { 6381496ba7bSLoGin b'/' => String::from("/"), 6391496ba7bSLoGin _ => proc.basic().cwd(), 6401496ba7bSLoGin }; 6411496ba7bSLoGin let mut cwd_vec: Vec<_> = cwd.split("/").filter(|&x| x != "").collect(); 6421496ba7bSLoGin let path_split = path.split("/").filter(|&x| x != ""); 6431496ba7bSLoGin for seg in path_split { 6441496ba7bSLoGin if seg == ".." { 6451496ba7bSLoGin cwd_vec.pop(); 6461496ba7bSLoGin } else if seg == "." { 6471496ba7bSLoGin // 当前目录 6481496ba7bSLoGin } else { 6491496ba7bSLoGin cwd_vec.push(seg); 6501496ba7bSLoGin } 6511496ba7bSLoGin } 6521496ba7bSLoGin //proc.basic().set_path(String::from("")); 6531496ba7bSLoGin for seg in cwd_vec { 6541496ba7bSLoGin new_path.push_str("/"); 6551496ba7bSLoGin new_path.push_str(seg); 6561496ba7bSLoGin } 6571496ba7bSLoGin if new_path == "" { 6581496ba7bSLoGin new_path = String::from("/"); 6591496ba7bSLoGin } 6601496ba7bSLoGin } 661a03c4f9dSLoGin let inode = 662a03c4f9dSLoGin match ROOT_INODE().lookup_follow_symlink(&new_path, VFS_MAX_FOLLOW_SYMLINK_TIMES) { 66382df0a13Shmt Err(_) => { 664ab5c8ca4Slogin return Err(SystemError::ENOENT); 665004e86ffSlogin } 666004e86ffSlogin Ok(i) => i, 667004e86ffSlogin }; 6681496ba7bSLoGin let metadata = inode.metadata()?; 6691496ba7bSLoGin if metadata.file_type == FileType::Dir { 6701496ba7bSLoGin proc.basic_mut().set_cwd(String::from(new_path)); 671ab5c8ca4Slogin return Ok(0); 672004e86ffSlogin } else { 673ab5c8ca4Slogin return Err(SystemError::ENOTDIR); 674004e86ffSlogin } 675004e86ffSlogin } 6761496ba7bSLoGin 6771496ba7bSLoGin /// @brief 获取当前进程的工作目录路径 6781496ba7bSLoGin /// 6791496ba7bSLoGin /// @param buf 指向缓冲区的指针 6801496ba7bSLoGin /// @param size 缓冲区的大小 6811496ba7bSLoGin /// 6821496ba7bSLoGin /// @return 成功,返回的指针指向包含工作目录路径的字符串 6831496ba7bSLoGin /// @return 错误,没有足够的空间 6841496ba7bSLoGin pub fn getcwd(buf: &mut [u8]) -> Result<VirtAddr, SystemError> { 6851496ba7bSLoGin let proc = ProcessManager::current_pcb(); 6861496ba7bSLoGin let cwd = proc.basic().cwd(); 6871496ba7bSLoGin 6881496ba7bSLoGin let cwd_bytes = cwd.as_bytes(); 6891496ba7bSLoGin let cwd_len = cwd_bytes.len(); 6901496ba7bSLoGin if cwd_len + 1 > buf.len() { 6911496ba7bSLoGin return Err(SystemError::ENOMEM); 692004e86ffSlogin } 6931496ba7bSLoGin buf[..cwd_len].copy_from_slice(cwd_bytes); 6941496ba7bSLoGin buf[cwd_len] = 0; 6951496ba7bSLoGin 6961496ba7bSLoGin return Ok(VirtAddr::new(buf.as_ptr() as usize)); 697004e86ffSlogin } 698004e86ffSlogin 699004e86ffSlogin /// @brief 获取目录中的数据 700004e86ffSlogin /// 701ab5c8ca4Slogin /// TODO: 这个函数的语义与Linux不一致,需要修改!!! 702ab5c8ca4Slogin /// 703004e86ffSlogin /// @param fd 文件描述符号 704ab5c8ca4Slogin /// @param buf 输出缓冲区 705ab5c8ca4Slogin /// 706ab5c8ca4Slogin /// @return 成功返回读取的字节数,失败返回错误码 707ab5c8ca4Slogin pub fn getdents(fd: i32, buf: &mut [u8]) -> Result<usize, SystemError> { 708ab5c8ca4Slogin let dirent = 709ab5c8ca4Slogin unsafe { (buf.as_mut_ptr() as *mut Dirent).as_mut() }.ok_or(SystemError::EFAULT)?; 710004e86ffSlogin 71146e234aeSLoGin if fd < 0 || fd as usize > FileDescriptorVec::PROCESS_MAX_FD { 712ab5c8ca4Slogin return Err(SystemError::EBADF); 713004e86ffSlogin } 714004e86ffSlogin 715004e86ffSlogin // 获取fd 7161496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 7171496ba7bSLoGin let fd_table_guard = binding.read(); 7181496ba7bSLoGin let file = fd_table_guard 7191496ba7bSLoGin .get_file_by_fd(fd) 7201496ba7bSLoGin .ok_or(SystemError::EBADF)?; 721004e86ffSlogin 7221496ba7bSLoGin // drop guard 以避免无法调度的问题 7231496ba7bSLoGin drop(fd_table_guard); 72434e6d6c8Syuyi2439 72534e6d6c8Syuyi2439 let res = file.lock_no_preempt().readdir(dirent).map(|x| x as usize); 72634e6d6c8Syuyi2439 72734e6d6c8Syuyi2439 return res; 728004e86ffSlogin } 729004e86ffSlogin 730004e86ffSlogin /// @brief 创建文件夹 731004e86ffSlogin /// 732004e86ffSlogin /// @param path(r8) 路径 / mode(r9) 模式 733004e86ffSlogin /// 734004e86ffSlogin /// @return uint64_t 负数错误码 / 0表示成功 73582df0a13Shmt pub fn mkdir(path: *const u8, mode: usize) -> Result<usize, SystemError> { 73682df0a13Shmt let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; 73782df0a13Shmt return do_mkdir(&path, FileMode::from_bits_truncate(mode as u32)).map(|x| x as usize); 738004e86ffSlogin } 739004e86ffSlogin 740ab5c8ca4Slogin /// **删除文件夹、取消文件的链接、删除文件的系统调用** 741004e86ffSlogin /// 742ab5c8ca4Slogin /// ## 参数 743004e86ffSlogin /// 744ab5c8ca4Slogin /// - `dirfd`:文件夹的文件描述符.目前暂未实现 745ab5c8ca4Slogin /// - `pathname`:文件夹的路径 746ab5c8ca4Slogin /// - `flags`:标志位 747004e86ffSlogin /// 748004e86ffSlogin /// 74982df0a13Shmt pub fn unlinkat(dirfd: i32, path: *const u8, flags: u32) -> Result<usize, SystemError> { 750bf4a4899SLoGin let flags = AtFlags::from_bits(flags as i32).ok_or(SystemError::EINVAL)?; 751004e86ffSlogin 75282df0a13Shmt let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; 75382df0a13Shmt 754bf4a4899SLoGin if flags.contains(AtFlags::AT_REMOVEDIR) { 755004e86ffSlogin // kdebug!("rmdir"); 75682df0a13Shmt match do_remove_dir(dirfd, &path) { 757004e86ffSlogin Err(err) => { 758ab5c8ca4Slogin return Err(err); 759004e86ffSlogin } 760004e86ffSlogin Ok(_) => { 761ab5c8ca4Slogin return Ok(0); 762004e86ffSlogin } 763004e86ffSlogin } 764004e86ffSlogin } 765004e86ffSlogin 76682df0a13Shmt match do_unlink_at(dirfd, &path) { 767004e86ffSlogin Err(err) => { 768ab5c8ca4Slogin return Err(err); 769004e86ffSlogin } 770004e86ffSlogin Ok(_) => { 771ab5c8ca4Slogin return Ok(0); 772004e86ffSlogin } 773004e86ffSlogin } 774004e86ffSlogin } 7752b771e32SGou Ngai 77682df0a13Shmt pub fn rmdir(path: *const u8) -> Result<usize, SystemError> { 77782df0a13Shmt let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; 77882df0a13Shmt return do_remove_dir(AtFlags::AT_FDCWD.bits(), &path).map(|v| v as usize); 7795eeefb8cSChenzx } 7805eeefb8cSChenzx 78182df0a13Shmt pub fn unlink(path: *const u8) -> Result<usize, SystemError> { 78282df0a13Shmt let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; 78382df0a13Shmt return do_unlink_at(AtFlags::AT_FDCWD.bits(), &path).map(|v| v as usize); 784bf4a4899SLoGin } 785bf4a4899SLoGin 7869e481b3bSTTaq /// # 修改文件名 7879e481b3bSTTaq /// 7889e481b3bSTTaq /// 7899e481b3bSTTaq /// ## 参数 7909e481b3bSTTaq /// 7919e481b3bSTTaq /// - oldfd: 源文件描述符 7929e481b3bSTTaq /// - filename_from: 源文件路径 7939e481b3bSTTaq /// - newfd: 目标文件描述符 7949e481b3bSTTaq /// - filename_to: 目标文件路径 7959e481b3bSTTaq /// - flags: 标志位 7969e481b3bSTTaq /// 7979e481b3bSTTaq /// 7989e481b3bSTTaq /// ## 返回值 7999e481b3bSTTaq /// - Ok(返回值类型): 返回值的说明 8009e481b3bSTTaq /// - Err(错误值类型): 错误的说明 8019e481b3bSTTaq /// 8029e481b3bSTTaq pub fn do_renameat2( 8039e481b3bSTTaq oldfd: i32, 8049e481b3bSTTaq filename_from: *const u8, 8059e481b3bSTTaq newfd: i32, 8069e481b3bSTTaq filename_to: *const u8, 8079e481b3bSTTaq _flags: u32, 8089e481b3bSTTaq ) -> Result<usize, SystemError> { 8099e481b3bSTTaq let filename_from = check_and_clone_cstr(filename_from, Some(MAX_PATHLEN)).unwrap(); 8109e481b3bSTTaq let filename_to = check_and_clone_cstr(filename_to, Some(MAX_PATHLEN)).unwrap(); 8119e481b3bSTTaq // 文件名过长 8129e481b3bSTTaq if filename_from.len() > MAX_PATHLEN as usize || filename_to.len() > MAX_PATHLEN as usize { 8139e481b3bSTTaq return Err(SystemError::ENAMETOOLONG); 8149e481b3bSTTaq } 8159e481b3bSTTaq 8169e481b3bSTTaq //获取pcb,文件节点 8179e481b3bSTTaq let pcb = ProcessManager::current_pcb(); 8189e481b3bSTTaq let (_old_inode_begin, old_remain_path) = user_path_at(&pcb, oldfd, &filename_from)?; 8199e481b3bSTTaq let (_new_inode_begin, new_remain_path) = user_path_at(&pcb, newfd, &filename_to)?; 8209e481b3bSTTaq //获取父目录 8219e481b3bSTTaq let (old_filename, old_parent_path) = rsplit_path(&old_remain_path); 8229e481b3bSTTaq let old_parent_inode = ROOT_INODE() 8239e481b3bSTTaq .lookup_follow_symlink(old_parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 8249e481b3bSTTaq let (new_filename, new_parent_path) = rsplit_path(&new_remain_path); 8259e481b3bSTTaq let new_parent_inode = ROOT_INODE() 8269e481b3bSTTaq .lookup_follow_symlink(new_parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 8279e481b3bSTTaq old_parent_inode.move_to(old_filename, &new_parent_inode, new_filename)?; 8289e481b3bSTTaq return Ok(0); 8299e481b3bSTTaq } 8309e481b3bSTTaq 831ab5c8ca4Slogin /// @brief 根据提供的文件描述符的fd,复制对应的文件结构体,并返回新复制的文件结构体对应的fd 832ab5c8ca4Slogin pub fn dup(oldfd: i32) -> Result<usize, SystemError> { 8331496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 8341496ba7bSLoGin let mut fd_table_guard = binding.write(); 835ab5c8ca4Slogin 8361496ba7bSLoGin let old_file = fd_table_guard 8371496ba7bSLoGin .get_file_by_fd(oldfd) 8381496ba7bSLoGin .ok_or(SystemError::EBADF)?; 8391496ba7bSLoGin 8401496ba7bSLoGin let new_file = old_file 8411496ba7bSLoGin .lock_no_preempt() 8421496ba7bSLoGin .try_clone() 8431496ba7bSLoGin .ok_or(SystemError::EBADF)?; 8442b771e32SGou Ngai // 申请文件描述符,并把文件对象存入其中 8451496ba7bSLoGin let res = fd_table_guard.alloc_fd(new_file, None).map(|x| x as usize); 8462b771e32SGou Ngai return res; 8472b771e32SGou Ngai } 8482b771e32SGou Ngai 849ab5c8ca4Slogin /// 根据提供的文件描述符的fd,和指定新fd,复制对应的文件结构体, 850ab5c8ca4Slogin /// 并返回新复制的文件结构体对应的fd. 851ab5c8ca4Slogin /// 如果新fd已经打开,则会先关闭新fd. 852ab5c8ca4Slogin /// 853ab5c8ca4Slogin /// ## 参数 854ab5c8ca4Slogin /// 855ab5c8ca4Slogin /// - `oldfd`:旧文件描述符 856ab5c8ca4Slogin /// - `newfd`:新文件描述符 857ab5c8ca4Slogin /// 858ab5c8ca4Slogin /// ## 返回值 859ab5c8ca4Slogin /// 860ab5c8ca4Slogin /// - 成功:新文件描述符 861ab5c8ca4Slogin /// - 失败:错误码 862ab5c8ca4Slogin pub fn dup2(oldfd: i32, newfd: i32) -> Result<usize, SystemError> { 8631496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 8641496ba7bSLoGin let mut fd_table_guard = binding.write(); 8651496ba7bSLoGin return Self::do_dup2(oldfd, newfd, &mut fd_table_guard); 8661496ba7bSLoGin } 8671496ba7bSLoGin 8681496ba7bSLoGin fn do_dup2( 8691496ba7bSLoGin oldfd: i32, 8701496ba7bSLoGin newfd: i32, 8711496ba7bSLoGin fd_table_guard: &mut RwLockWriteGuard<'_, FileDescriptorVec>, 8721496ba7bSLoGin ) -> Result<usize, SystemError> { 8732b771e32SGou Ngai // 确认oldfd, newid是否有效 8741496ba7bSLoGin if !(FileDescriptorVec::validate_fd(oldfd) && FileDescriptorVec::validate_fd(newfd)) { 8751496ba7bSLoGin return Err(SystemError::EBADF); 8761496ba7bSLoGin } 8771496ba7bSLoGin 8782b771e32SGou Ngai if oldfd == newfd { 8792b771e32SGou Ngai // 若oldfd与newfd相等 880ab5c8ca4Slogin return Ok(newfd as usize); 8812b771e32SGou Ngai } 8821496ba7bSLoGin let new_exists = fd_table_guard.get_file_by_fd(newfd).is_some(); 8831496ba7bSLoGin if new_exists { 8842b771e32SGou Ngai // close newfd 8851496ba7bSLoGin if let Err(_) = fd_table_guard.drop_fd(newfd) { 8862b771e32SGou Ngai // An I/O error occurred while attempting to close fildes2. 8872b771e32SGou Ngai return Err(SystemError::EIO); 8882b771e32SGou Ngai } 8892b771e32SGou Ngai } 8902b771e32SGou Ngai 8911496ba7bSLoGin let old_file = fd_table_guard 8921496ba7bSLoGin .get_file_by_fd(oldfd) 8931496ba7bSLoGin .ok_or(SystemError::EBADF)?; 8941496ba7bSLoGin let new_file = old_file 8951496ba7bSLoGin .lock_no_preempt() 8961496ba7bSLoGin .try_clone() 8971496ba7bSLoGin .ok_or(SystemError::EBADF)?; 8982b771e32SGou Ngai // 申请文件描述符,并把文件对象存入其中 8991496ba7bSLoGin let res = fd_table_guard 9001496ba7bSLoGin .alloc_fd(new_file, Some(newfd)) 901ab5c8ca4Slogin .map(|x| x as usize); 9022b771e32SGou Ngai return res; 9032b771e32SGou Ngai } 9046d81180bSLoGin 9056d81180bSLoGin /// # fcntl 9066d81180bSLoGin /// 9076d81180bSLoGin /// ## 参数 9086d81180bSLoGin /// 9096d81180bSLoGin /// - `fd`:文件描述符 9106d81180bSLoGin /// - `cmd`:命令 9116d81180bSLoGin /// - `arg`:参数 9126d81180bSLoGin pub fn fcntl(fd: i32, cmd: FcntlCommand, arg: i32) -> Result<usize, SystemError> { 9136d81180bSLoGin match cmd { 9146d81180bSLoGin FcntlCommand::DupFd => { 9156d81180bSLoGin if arg < 0 || arg as usize >= FileDescriptorVec::PROCESS_MAX_FD { 9166d81180bSLoGin return Err(SystemError::EBADF); 9176d81180bSLoGin } 9186d81180bSLoGin let arg = arg as usize; 9196d81180bSLoGin for i in arg..FileDescriptorVec::PROCESS_MAX_FD { 9201496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 9211496ba7bSLoGin let mut fd_table_guard = binding.write(); 92252da9a59SGnoCiYeH if fd_table_guard.get_file_by_fd(i as i32).is_none() { 9231496ba7bSLoGin return Self::do_dup2(fd, i as i32, &mut fd_table_guard); 9246d81180bSLoGin } 9256d81180bSLoGin } 9266d81180bSLoGin return Err(SystemError::EMFILE); 9276d81180bSLoGin } 9286d81180bSLoGin FcntlCommand::GetFd => { 9296d81180bSLoGin // Get file descriptor flags. 9301496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 9311496ba7bSLoGin let fd_table_guard = binding.read(); 9321496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 9331496ba7bSLoGin // drop guard 以避免无法调度的问题 9341496ba7bSLoGin drop(fd_table_guard); 9356d81180bSLoGin 9361496ba7bSLoGin if file.lock().close_on_exec() { 9376d81180bSLoGin return Ok(FD_CLOEXEC as usize); 9386d81180bSLoGin } 9396d81180bSLoGin } 9406d81180bSLoGin return Err(SystemError::EBADF); 9416d81180bSLoGin } 9426d81180bSLoGin FcntlCommand::SetFd => { 9436d81180bSLoGin // Set file descriptor flags. 9441496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 9451496ba7bSLoGin let fd_table_guard = binding.write(); 9461496ba7bSLoGin 9471496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 9481496ba7bSLoGin // drop guard 以避免无法调度的问题 9491496ba7bSLoGin drop(fd_table_guard); 9506d81180bSLoGin let arg = arg as u32; 9516d81180bSLoGin if arg & FD_CLOEXEC != 0 { 9521496ba7bSLoGin file.lock().set_close_on_exec(true); 9536d81180bSLoGin } else { 9541496ba7bSLoGin file.lock().set_close_on_exec(false); 9556d81180bSLoGin } 9566d81180bSLoGin return Ok(0); 9576d81180bSLoGin } 9586d81180bSLoGin return Err(SystemError::EBADF); 9596d81180bSLoGin } 9606d81180bSLoGin 9616d81180bSLoGin FcntlCommand::GetFlags => { 9626d81180bSLoGin // Get file status flags. 9631496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 9641496ba7bSLoGin let fd_table_guard = binding.read(); 9651496ba7bSLoGin 9661496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 9671496ba7bSLoGin // drop guard 以避免无法调度的问题 9681496ba7bSLoGin drop(fd_table_guard); 9691496ba7bSLoGin return Ok(file.lock_no_preempt().mode().bits() as usize); 9706d81180bSLoGin } 9711496ba7bSLoGin 9726d81180bSLoGin return Err(SystemError::EBADF); 9736d81180bSLoGin } 9746d81180bSLoGin FcntlCommand::SetFlags => { 9756d81180bSLoGin // Set file status flags. 9761496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 9771496ba7bSLoGin let fd_table_guard = binding.write(); 9781496ba7bSLoGin 9791496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 9806d81180bSLoGin let arg = arg as u32; 9816d81180bSLoGin let mode = FileMode::from_bits(arg).ok_or(SystemError::EINVAL)?; 9821496ba7bSLoGin // drop guard 以避免无法调度的问题 9831496ba7bSLoGin drop(fd_table_guard); 9841496ba7bSLoGin file.lock_no_preempt().set_mode(mode)?; 9856d81180bSLoGin return Ok(0); 9866d81180bSLoGin } 9871496ba7bSLoGin 9886d81180bSLoGin return Err(SystemError::EBADF); 9896d81180bSLoGin } 9906d81180bSLoGin _ => { 9916d81180bSLoGin // TODO: unimplemented 9926d81180bSLoGin // 未实现的命令,返回0,不报错。 9936d81180bSLoGin 9946d81180bSLoGin // kwarn!("fcntl: unimplemented command: {:?}, defaults to 0.", cmd); 9956d81180bSLoGin return Ok(0); 9966d81180bSLoGin } 9976d81180bSLoGin } 9986d81180bSLoGin } 9996d81180bSLoGin 10006d81180bSLoGin /// # ftruncate 10016d81180bSLoGin /// 10026d81180bSLoGin /// ## 描述 10036d81180bSLoGin /// 10046d81180bSLoGin /// 改变文件大小. 10056d81180bSLoGin /// 如果文件大小大于原来的大小,那么文件的内容将会被扩展到指定的大小,新的空间将会用0填充. 10066d81180bSLoGin /// 如果文件大小小于原来的大小,那么文件的内容将会被截断到指定的大小. 10076d81180bSLoGin /// 10086d81180bSLoGin /// ## 参数 10096d81180bSLoGin /// 10106d81180bSLoGin /// - `fd`:文件描述符 10116d81180bSLoGin /// - `len`:文件大小 10126d81180bSLoGin /// 10136d81180bSLoGin /// ## 返回值 10146d81180bSLoGin /// 10156d81180bSLoGin /// 如果成功,返回0,否则返回错误码. 10166d81180bSLoGin pub fn ftruncate(fd: i32, len: usize) -> Result<usize, SystemError> { 10171496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 10181496ba7bSLoGin let fd_table_guard = binding.read(); 10191496ba7bSLoGin 10201496ba7bSLoGin if let Some(file) = fd_table_guard.get_file_by_fd(fd) { 10211496ba7bSLoGin // drop guard 以避免无法调度的问题 10221496ba7bSLoGin drop(fd_table_guard); 10231496ba7bSLoGin let r = file.lock_no_preempt().ftruncate(len).map(|_| 0); 10246d81180bSLoGin return r; 10256d81180bSLoGin } 10261496ba7bSLoGin 10276d81180bSLoGin return Err(SystemError::EBADF); 10286d81180bSLoGin } 10291496ba7bSLoGin 103067b48188Shoumkh fn do_fstat(fd: i32) -> Result<PosixKstat, SystemError> { 10311496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 10321496ba7bSLoGin let fd_table_guard = binding.read(); 10331496ba7bSLoGin let file = fd_table_guard 10341496ba7bSLoGin .get_file_by_fd(fd) 10351496ba7bSLoGin .ok_or(SystemError::EBADF)?; 10361496ba7bSLoGin // drop guard 以避免无法调度的问题 10371496ba7bSLoGin drop(fd_table_guard); 10381496ba7bSLoGin 103967b48188Shoumkh let mut kstat = PosixKstat::new(); 104067b48188Shoumkh // 获取文件信息 10411496ba7bSLoGin let metadata = file.lock().metadata()?; 104267b48188Shoumkh kstat.size = metadata.size as i64; 104367b48188Shoumkh kstat.dev_id = metadata.dev_id as u64; 10446b4e7a29SLoGin kstat.inode = metadata.inode_id.into() as u64; 104567b48188Shoumkh kstat.blcok_size = metadata.blk_size as i64; 104667b48188Shoumkh kstat.blocks = metadata.blocks as u64; 104767b48188Shoumkh 104867b48188Shoumkh kstat.atime.tv_sec = metadata.atime.tv_sec; 104967b48188Shoumkh kstat.atime.tv_nsec = metadata.atime.tv_nsec; 105067b48188Shoumkh kstat.mtime.tv_sec = metadata.mtime.tv_sec; 105167b48188Shoumkh kstat.mtime.tv_nsec = metadata.mtime.tv_nsec; 105267b48188Shoumkh kstat.ctime.tv_sec = metadata.ctime.tv_sec; 105367b48188Shoumkh kstat.ctime.tv_nsec = metadata.ctime.tv_nsec; 105467b48188Shoumkh 105567b48188Shoumkh kstat.nlink = metadata.nlinks as u64; 105667b48188Shoumkh kstat.uid = metadata.uid as i32; 105767b48188Shoumkh kstat.gid = metadata.gid as i32; 105802343d0bSLoGin kstat.rdev = metadata.raw_dev.data() as i64; 10596b4e7a29SLoGin kstat.mode = metadata.mode; 10601496ba7bSLoGin match file.lock().file_type() { 10617eda31b2SLoGin FileType::File => kstat.mode.insert(ModeType::S_IFREG), 106267b48188Shoumkh FileType::Dir => kstat.mode.insert(ModeType::S_IFDIR), 106367b48188Shoumkh FileType::BlockDevice => kstat.mode.insert(ModeType::S_IFBLK), 106467b48188Shoumkh FileType::CharDevice => kstat.mode.insert(ModeType::S_IFCHR), 106567b48188Shoumkh FileType::SymLink => kstat.mode.insert(ModeType::S_IFLNK), 106667b48188Shoumkh FileType::Socket => kstat.mode.insert(ModeType::S_IFSOCK), 106767b48188Shoumkh FileType::Pipe => kstat.mode.insert(ModeType::S_IFIFO), 106840314b30SXiaoye Zheng FileType::KvmDevice => kstat.mode.insert(ModeType::S_IFCHR), 106902343d0bSLoGin FileType::FramebufferDevice => kstat.mode.insert(ModeType::S_IFCHR), 107067b48188Shoumkh } 107167b48188Shoumkh 107267b48188Shoumkh return Ok(kstat); 107367b48188Shoumkh } 10741496ba7bSLoGin 107567b48188Shoumkh pub fn fstat(fd: i32, usr_kstat: *mut PosixKstat) -> Result<usize, SystemError> { 107682df0a13Shmt let mut writer = UserBufferWriter::new(usr_kstat, size_of::<PosixKstat>(), true)?; 10771496ba7bSLoGin let kstat = Self::do_fstat(fd)?; 107882df0a13Shmt 107982df0a13Shmt writer.copy_one_to_user(&kstat, 0)?; 108067b48188Shoumkh return Ok(0); 108167b48188Shoumkh } 10822dbef785SGnoCiYeH 108382df0a13Shmt pub fn stat(path: *const u8, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> { 108482df0a13Shmt let fd = Self::open( 108582df0a13Shmt path, 108682df0a13Shmt FileMode::O_RDONLY.bits(), 108782df0a13Shmt ModeType::empty().bits(), 108882df0a13Shmt true, 108982df0a13Shmt )?; 1090bf4a4899SLoGin let r = Self::fstat(fd as i32, user_kstat); 1091971462beSGnoCiYeH Self::close(fd).ok(); 1092bf4a4899SLoGin return r; 1093bf4a4899SLoGin } 1094bf4a4899SLoGin 109582df0a13Shmt pub fn lstat(path: *const u8, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> { 109682df0a13Shmt let fd = Self::open( 109782df0a13Shmt path, 109882df0a13Shmt FileMode::O_RDONLY.bits(), 109982df0a13Shmt ModeType::empty().bits(), 110082df0a13Shmt false, 110182df0a13Shmt )?; 1102bf4a4899SLoGin let r = Self::fstat(fd as i32, user_kstat); 1103bf4a4899SLoGin Self::close(fd).ok(); 1104bf4a4899SLoGin return r; 1105971462beSGnoCiYeH } 1106971462beSGnoCiYeH 1107*b4eb05a1STTaq pub fn do_statx( 1108*b4eb05a1STTaq fd: i32, 1109*b4eb05a1STTaq path: *const u8, 1110*b4eb05a1STTaq flags: u32, 1111*b4eb05a1STTaq mask: u32, 1112*b4eb05a1STTaq usr_kstat: *mut PosixStatx, 1113*b4eb05a1STTaq ) -> Result<usize, SystemError> { 1114*b4eb05a1STTaq if usr_kstat.is_null() { 1115*b4eb05a1STTaq return Err(SystemError::EFAULT); 1116*b4eb05a1STTaq } 1117*b4eb05a1STTaq 1118*b4eb05a1STTaq let mask = PosixStatxMask::from_bits_truncate(mask); 1119*b4eb05a1STTaq 1120*b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_RESERVED) { 1121*b4eb05a1STTaq return Err(SystemError::ENAVAIL); 1122*b4eb05a1STTaq } 1123*b4eb05a1STTaq 1124*b4eb05a1STTaq let flags = FileMode::from_bits_truncate(flags); 1125*b4eb05a1STTaq let ofd = Self::open(path, flags.bits(), ModeType::empty().bits, true)?; 1126*b4eb05a1STTaq 1127*b4eb05a1STTaq let binding = ProcessManager::current_pcb().fd_table(); 1128*b4eb05a1STTaq let fd_table_guard = binding.read(); 1129*b4eb05a1STTaq let file = fd_table_guard 1130*b4eb05a1STTaq .get_file_by_fd(ofd as i32) 1131*b4eb05a1STTaq .ok_or(SystemError::EBADF)?; 1132*b4eb05a1STTaq // drop guard 以避免无法调度的问题 1133*b4eb05a1STTaq drop(fd_table_guard); 1134*b4eb05a1STTaq let mut writer = UserBufferWriter::new(usr_kstat, size_of::<PosixStatx>(), true)?; 1135*b4eb05a1STTaq let mut tmp: PosixStatx = PosixStatx::new(); 1136*b4eb05a1STTaq // 获取文件信息 1137*b4eb05a1STTaq let metadata = file.lock().metadata()?; 1138*b4eb05a1STTaq 1139*b4eb05a1STTaq tmp.stx_mask |= PosixStatxMask::STATX_BASIC_STATS; 1140*b4eb05a1STTaq tmp.stx_blksize = metadata.blk_size as u32; 1141*b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_MODE) || mask.contains(PosixStatxMask::STATX_TYPE) { 1142*b4eb05a1STTaq tmp.stx_mode = metadata.mode; 1143*b4eb05a1STTaq } 1144*b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_NLINK) { 1145*b4eb05a1STTaq tmp.stx_nlink = metadata.nlinks as u32; 1146*b4eb05a1STTaq } 1147*b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_UID) { 1148*b4eb05a1STTaq tmp.stx_uid = metadata.uid as u32; 1149*b4eb05a1STTaq } 1150*b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_GID) { 1151*b4eb05a1STTaq tmp.stx_gid = metadata.gid as u32; 1152*b4eb05a1STTaq } 1153*b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_ATIME) { 1154*b4eb05a1STTaq tmp.stx_atime.tv_sec = metadata.atime.tv_sec; 1155*b4eb05a1STTaq tmp.stx_atime.tv_nsec = metadata.atime.tv_nsec; 1156*b4eb05a1STTaq } 1157*b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_MTIME) { 1158*b4eb05a1STTaq tmp.stx_mtime.tv_sec = metadata.ctime.tv_sec; 1159*b4eb05a1STTaq tmp.stx_mtime.tv_nsec = metadata.ctime.tv_nsec; 1160*b4eb05a1STTaq } 1161*b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_CTIME) { 1162*b4eb05a1STTaq // ctime是文件上次修改状态的时间 1163*b4eb05a1STTaq tmp.stx_ctime.tv_sec = metadata.mtime.tv_sec; 1164*b4eb05a1STTaq tmp.stx_ctime.tv_nsec = metadata.mtime.tv_nsec; 1165*b4eb05a1STTaq } 1166*b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_INO) { 1167*b4eb05a1STTaq tmp.stx_inode = metadata.inode_id.into() as u64; 1168*b4eb05a1STTaq } 1169*b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_SIZE) { 1170*b4eb05a1STTaq tmp.stx_size = metadata.size; 1171*b4eb05a1STTaq } 1172*b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_BLOCKS) { 1173*b4eb05a1STTaq tmp.stx_blocks = metadata.blocks as u64; 1174*b4eb05a1STTaq } 1175*b4eb05a1STTaq 1176*b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_BTIME) { 1177*b4eb05a1STTaq // btime是文件创建时间 1178*b4eb05a1STTaq tmp.stx_btime.tv_sec = metadata.ctime.tv_sec; 1179*b4eb05a1STTaq tmp.stx_btime.tv_nsec = metadata.ctime.tv_nsec; 1180*b4eb05a1STTaq } 1181*b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_ALL) { 1182*b4eb05a1STTaq tmp.stx_attributes = StxAttributes::STATX_ATTR_APPEND; 1183*b4eb05a1STTaq tmp.stx_attributes_mask |= 1184*b4eb05a1STTaq StxAttributes::STATX_ATTR_AUTOMOUNT | StxAttributes::STATX_ATTR_DAX; 1185*b4eb05a1STTaq tmp.stx_dev_major = metadata.dev_id as u32; 1186*b4eb05a1STTaq tmp.stx_dev_minor = metadata.dev_id as u32; // 1187*b4eb05a1STTaq tmp.stx_rdev_major = metadata.raw_dev.data() as u32; 1188*b4eb05a1STTaq tmp.stx_rdev_minor = metadata.raw_dev.data() as u32; 1189*b4eb05a1STTaq } 1190*b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_MNT_ID) { 1191*b4eb05a1STTaq tmp.stx_mnt_id = 0; 1192*b4eb05a1STTaq } 1193*b4eb05a1STTaq if mask.contains(PosixStatxMask::STATX_DIOALIGN) { 1194*b4eb05a1STTaq tmp.stx_dio_mem_align = 0; 1195*b4eb05a1STTaq tmp.stx_dio_offset_align = 0; 1196*b4eb05a1STTaq } 1197*b4eb05a1STTaq 1198*b4eb05a1STTaq match file.lock().file_type() { 1199*b4eb05a1STTaq FileType::File => tmp.stx_mode.insert(ModeType::S_IFREG), 1200*b4eb05a1STTaq FileType::Dir => tmp.stx_mode.insert(ModeType::S_IFDIR), 1201*b4eb05a1STTaq FileType::BlockDevice => tmp.stx_mode.insert(ModeType::S_IFBLK), 1202*b4eb05a1STTaq FileType::CharDevice => tmp.stx_mode.insert(ModeType::S_IFCHR), 1203*b4eb05a1STTaq FileType::SymLink => tmp.stx_mode.insert(ModeType::S_IFLNK), 1204*b4eb05a1STTaq FileType::Socket => tmp.stx_mode.insert(ModeType::S_IFSOCK), 1205*b4eb05a1STTaq FileType::Pipe => tmp.stx_mode.insert(ModeType::S_IFIFO), 1206*b4eb05a1STTaq FileType::KvmDevice => tmp.stx_mode.insert(ModeType::S_IFCHR), 1207*b4eb05a1STTaq FileType::FramebufferDevice => tmp.stx_mode.insert(ModeType::S_IFCHR), 1208*b4eb05a1STTaq } 1209*b4eb05a1STTaq 1210*b4eb05a1STTaq writer.copy_one_to_user(&tmp, 0)?; 1211*b4eb05a1STTaq Self::close(fd as usize).ok(); 1212*b4eb05a1STTaq return Ok(0); 1213*b4eb05a1STTaq } 1214*b4eb05a1STTaq 12152dbef785SGnoCiYeH pub fn mknod( 121682df0a13Shmt path: *const u8, 12172dbef785SGnoCiYeH mode: ModeType, 12182dbef785SGnoCiYeH dev_t: DeviceNumber, 12192dbef785SGnoCiYeH ) -> Result<usize, SystemError> { 122082df0a13Shmt let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; 122182df0a13Shmt let path = path.as_str().trim(); 12222dbef785SGnoCiYeH 1223a03c4f9dSLoGin let inode: Result<Arc<dyn IndexNode>, SystemError> = 1224a03c4f9dSLoGin ROOT_INODE().lookup_follow_symlink(path, VFS_MAX_FOLLOW_SYMLINK_TIMES); 12252dbef785SGnoCiYeH 12262dbef785SGnoCiYeH if inode.is_ok() { 12272dbef785SGnoCiYeH return Err(SystemError::EEXIST); 12282dbef785SGnoCiYeH } 12292dbef785SGnoCiYeH 12302dbef785SGnoCiYeH let (filename, parent_path) = rsplit_path(path); 12312dbef785SGnoCiYeH 12322dbef785SGnoCiYeH // 查找父目录 1233a03c4f9dSLoGin let parent_inode: Arc<dyn IndexNode> = ROOT_INODE() 1234a03c4f9dSLoGin .lookup_follow_symlink(parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 12352dbef785SGnoCiYeH // 创建nod 12362dbef785SGnoCiYeH parent_inode.mknod(filename, mode, dev_t)?; 12372dbef785SGnoCiYeH 12382dbef785SGnoCiYeH return Ok(0); 12392dbef785SGnoCiYeH } 1240971462beSGnoCiYeH 1241971462beSGnoCiYeH pub fn writev(fd: i32, iov: usize, count: usize) -> Result<usize, SystemError> { 1242971462beSGnoCiYeH // IoVecs会进行用户态检验 1243971462beSGnoCiYeH let iovecs = unsafe { IoVecs::from_user(iov as *const IoVec, count, false) }?; 1244971462beSGnoCiYeH 1245971462beSGnoCiYeH let data = iovecs.gather(); 1246971462beSGnoCiYeH 1247971462beSGnoCiYeH Self::write(fd, &data) 1248971462beSGnoCiYeH } 1249709498caSLoGin 1250bf4a4899SLoGin pub fn readv(fd: i32, iov: usize, count: usize) -> Result<usize, SystemError> { 1251bf4a4899SLoGin // IoVecs会进行用户态检验 1252bf4a4899SLoGin let mut iovecs = unsafe { IoVecs::from_user(iov as *const IoVec, count, true) }?; 1253bf4a4899SLoGin 1254bf4a4899SLoGin let mut data = Vec::new(); 1255bf4a4899SLoGin data.resize(iovecs.0.iter().map(|x| x.len()).sum(), 0); 1256bf4a4899SLoGin 1257bf4a4899SLoGin let len = Self::read(fd, &mut data)?; 1258bf4a4899SLoGin 1259bf4a4899SLoGin iovecs.scatter(&data[..len]); 1260bf4a4899SLoGin 1261bf4a4899SLoGin return Ok(len); 1262bf4a4899SLoGin } 1263bf4a4899SLoGin 1264709498caSLoGin pub fn readlink_at( 1265709498caSLoGin dirfd: i32, 1266709498caSLoGin path: *const u8, 1267709498caSLoGin user_buf: *mut u8, 1268709498caSLoGin buf_size: usize, 1269709498caSLoGin ) -> Result<usize, SystemError> { 12709b0abe6dSLoGin let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; 127182df0a13Shmt let path = path.as_str().trim(); 1272709498caSLoGin let mut user_buf = UserBufferWriter::new(user_buf, buf_size, true)?; 1273709498caSLoGin 12740fb515b0SLoGin let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, &path)?; 1275709498caSLoGin 1276709498caSLoGin let inode = inode.lookup(path.as_str())?; 1277709498caSLoGin if inode.metadata()?.file_type != FileType::SymLink { 1278709498caSLoGin return Err(SystemError::EINVAL); 1279709498caSLoGin } 1280709498caSLoGin 1281709498caSLoGin let ubuf = user_buf.buffer::<u8>(0).unwrap(); 1282709498caSLoGin 1283709498caSLoGin let mut file = File::new(inode, FileMode::O_RDONLY)?; 1284709498caSLoGin 1285709498caSLoGin let len = file.read(buf_size, ubuf)?; 1286709498caSLoGin 1287709498caSLoGin return Ok(len); 1288709498caSLoGin } 1289709498caSLoGin 1290709498caSLoGin pub fn readlink( 1291709498caSLoGin path: *const u8, 1292709498caSLoGin user_buf: *mut u8, 1293709498caSLoGin buf_size: usize, 1294709498caSLoGin ) -> Result<usize, SystemError> { 12959b0abe6dSLoGin return Self::readlink_at(AtFlags::AT_FDCWD.bits(), path, user_buf, buf_size); 12969b0abe6dSLoGin } 12979b0abe6dSLoGin 12989b0abe6dSLoGin pub fn access(pathname: *const u8, mode: u32) -> Result<usize, SystemError> { 12999b0abe6dSLoGin return do_faccessat( 13009b0abe6dSLoGin AtFlags::AT_FDCWD.bits(), 13019b0abe6dSLoGin pathname, 1302bf4a4899SLoGin ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?, 13039b0abe6dSLoGin 0, 13049b0abe6dSLoGin ); 13059b0abe6dSLoGin } 13069b0abe6dSLoGin 13079b0abe6dSLoGin pub fn faccessat2( 13089b0abe6dSLoGin dirfd: i32, 13099b0abe6dSLoGin pathname: *const u8, 13109b0abe6dSLoGin mode: u32, 13119b0abe6dSLoGin flags: u32, 13129b0abe6dSLoGin ) -> Result<usize, SystemError> { 1313bf4a4899SLoGin return do_faccessat( 1314bf4a4899SLoGin dirfd, 1315bf4a4899SLoGin pathname, 1316bf4a4899SLoGin ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?, 1317bf4a4899SLoGin flags, 1318bf4a4899SLoGin ); 1319bf4a4899SLoGin } 1320bf4a4899SLoGin 1321bf4a4899SLoGin pub fn chmod(pathname: *const u8, mode: u32) -> Result<usize, SystemError> { 1322bf4a4899SLoGin return do_fchmodat( 1323bf4a4899SLoGin AtFlags::AT_FDCWD.bits(), 1324bf4a4899SLoGin pathname, 1325bf4a4899SLoGin ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?, 1326bf4a4899SLoGin ); 1327bf4a4899SLoGin } 1328bf4a4899SLoGin 1329bf4a4899SLoGin pub fn fchmodat(dirfd: i32, pathname: *const u8, mode: u32) -> Result<usize, SystemError> { 1330bf4a4899SLoGin return do_fchmodat( 1331bf4a4899SLoGin dirfd, 1332bf4a4899SLoGin pathname, 1333bf4a4899SLoGin ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?, 1334bf4a4899SLoGin ); 1335bf4a4899SLoGin } 1336bf4a4899SLoGin 1337bf4a4899SLoGin pub fn fchmod(fd: i32, mode: u32) -> Result<usize, SystemError> { 1338bf4a4899SLoGin let _mode = ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?; 1339bf4a4899SLoGin let binding = ProcessManager::current_pcb().fd_table(); 1340bf4a4899SLoGin let fd_table_guard = binding.read(); 1341bf4a4899SLoGin let _file = fd_table_guard 1342bf4a4899SLoGin .get_file_by_fd(fd) 1343bf4a4899SLoGin .ok_or(SystemError::EBADF)?; 1344bf4a4899SLoGin 1345bf4a4899SLoGin // fchmod没完全实现,因此不修改文件的权限 1346bf4a4899SLoGin // todo: 实现fchmod 1347bf4a4899SLoGin kwarn!("fchmod not fully implemented"); 1348bf4a4899SLoGin return Ok(0); 1349709498caSLoGin } 13501d37ca6dSDonkey Kane /// #挂载文件系统 13511d37ca6dSDonkey Kane /// 13521d37ca6dSDonkey Kane /// 用于挂载文件系统,目前仅支持ramfs挂载 13531d37ca6dSDonkey Kane /// 13541d37ca6dSDonkey Kane /// ## 参数: 13551d37ca6dSDonkey Kane /// 13561d37ca6dSDonkey Kane /// - source 挂载设备(暂时不支持) 13571d37ca6dSDonkey Kane /// - target 挂载目录 13581d37ca6dSDonkey Kane /// - filesystemtype 文件系统 13591d37ca6dSDonkey Kane /// - mountflags 挂载选项(暂未实现) 13601d37ca6dSDonkey Kane /// - data 带数据挂载 13611d37ca6dSDonkey Kane /// 13621d37ca6dSDonkey Kane /// ## 返回值 13631d37ca6dSDonkey Kane /// - Ok(0): 挂载成功 13641d37ca6dSDonkey Kane /// - Err(SystemError) :挂载过程中出错 13651d37ca6dSDonkey Kane pub fn mount( 13661d37ca6dSDonkey Kane _source: *const u8, 13671d37ca6dSDonkey Kane target: *const u8, 13681d37ca6dSDonkey Kane filesystemtype: *const u8, 13691d37ca6dSDonkey Kane _mountflags: usize, 13701d37ca6dSDonkey Kane _data: *const c_void, 13711d37ca6dSDonkey Kane ) -> Result<usize, SystemError> { 13721d37ca6dSDonkey Kane let target = user_access::check_and_clone_cstr(target, Some(MAX_PATHLEN))?; 13731d37ca6dSDonkey Kane 13741d37ca6dSDonkey Kane let filesystemtype = user_access::check_and_clone_cstr(filesystemtype, Some(MAX_PATHLEN))?; 13751d37ca6dSDonkey Kane 13761d37ca6dSDonkey Kane let filesystemtype = producefs!(FSMAKER, filesystemtype)?; 13771d37ca6dSDonkey Kane 13781d37ca6dSDonkey Kane return Vcore::do_mount(filesystemtype, (format!("{target}")).as_str()); 13791d37ca6dSDonkey Kane } 13801d37ca6dSDonkey Kane 13811d37ca6dSDonkey Kane // 想法:可以在VFS中实现一个文件系统分发器,流程如下: 13821d37ca6dSDonkey Kane // 1. 接受从上方传来的文件类型字符串 13831d37ca6dSDonkey Kane // 2. 将传入值与启动时准备好的字符串数组逐个比较(probe) 13841d37ca6dSDonkey Kane // 3. 直接在函数内调用构造方法并直接返回文件系统对象 1385709498caSLoGin } 1386709498caSLoGin 1387cde5492fSlogin #[repr(C)] 1388cde5492fSlogin #[derive(Debug, Clone, Copy)] 1389cde5492fSlogin pub struct IoVec { 1390cde5492fSlogin /// 缓冲区的起始地址 1391cde5492fSlogin pub iov_base: *mut u8, 1392cde5492fSlogin /// 缓冲区的长度 1393cde5492fSlogin pub iov_len: usize, 1394cde5492fSlogin } 1395cde5492fSlogin 1396cde5492fSlogin /// 用于存储多个来自用户空间的IoVec 1397cde5492fSlogin /// 1398cde5492fSlogin /// 由于目前内核中的文件系统还不支持分散读写,所以暂时只支持将用户空间的IoVec聚合成一个缓冲区,然后进行操作。 1399cde5492fSlogin /// TODO:支持分散读写 1400cde5492fSlogin #[derive(Debug)] 1401cde5492fSlogin pub struct IoVecs(Vec<&'static mut [u8]>); 1402cde5492fSlogin 1403cde5492fSlogin impl IoVecs { 1404cde5492fSlogin /// 从用户空间的IoVec中构造IoVecs 1405cde5492fSlogin /// 1406cde5492fSlogin /// @param iov 用户空间的IoVec 1407cde5492fSlogin /// @param iovcnt 用户空间的IoVec的数量 1408cde5492fSlogin /// @param readv 是否为readv系统调用 1409cde5492fSlogin /// 1410cde5492fSlogin /// @return 构造成功返回IoVecs,否则返回错误码 1411cde5492fSlogin pub unsafe fn from_user( 1412cde5492fSlogin iov: *const IoVec, 1413cde5492fSlogin iovcnt: usize, 1414cde5492fSlogin _readv: bool, 1415cde5492fSlogin ) -> Result<Self, SystemError> { 1416cde5492fSlogin // 检查iov指针所在空间是否合法 14174fda81ceSLoGin verify_area( 14184fda81ceSLoGin VirtAddr::new(iov as usize), 14194fda81ceSLoGin iovcnt * core::mem::size_of::<IoVec>(), 14204fda81ceSLoGin ) 14214fda81ceSLoGin .map_err(|_| SystemError::EFAULT)?; 1422cde5492fSlogin 1423cde5492fSlogin // 将用户空间的IoVec转换为引用(注意:这里的引用是静态的,因为用户空间的IoVec不会被释放) 1424cde5492fSlogin let iovs: &[IoVec] = core::slice::from_raw_parts(iov, iovcnt); 1425cde5492fSlogin 1426cde5492fSlogin let mut slices: Vec<&mut [u8]> = vec![]; 1427cde5492fSlogin slices.reserve(iovs.len()); 1428cde5492fSlogin 1429cde5492fSlogin for iov in iovs.iter() { 1430cde5492fSlogin if iov.iov_len == 0 { 1431cde5492fSlogin continue; 1432cde5492fSlogin } 1433cde5492fSlogin 14344fda81ceSLoGin verify_area( 14354fda81ceSLoGin VirtAddr::new(iov.iov_base as usize), 14364fda81ceSLoGin iovcnt * core::mem::size_of::<IoVec>(), 14374fda81ceSLoGin ) 14384fda81ceSLoGin .map_err(|_| SystemError::EFAULT)?; 1439cde5492fSlogin 1440cde5492fSlogin slices.push(core::slice::from_raw_parts_mut(iov.iov_base, iov.iov_len)); 1441cde5492fSlogin } 1442cde5492fSlogin 1443cde5492fSlogin return Ok(Self(slices)); 1444cde5492fSlogin } 1445cde5492fSlogin 1446cde5492fSlogin /// @brief 将IoVecs中的数据聚合到一个缓冲区中 1447cde5492fSlogin /// 1448cde5492fSlogin /// @return 返回聚合后的缓冲区 1449cde5492fSlogin pub fn gather(&self) -> Vec<u8> { 1450cde5492fSlogin let mut buf = Vec::new(); 1451cde5492fSlogin for slice in self.0.iter() { 1452cde5492fSlogin buf.extend_from_slice(slice); 1453cde5492fSlogin } 1454cde5492fSlogin return buf; 1455cde5492fSlogin } 1456cde5492fSlogin 1457cde5492fSlogin /// @brief 将给定的数据分散写入到IoVecs中 1458cde5492fSlogin pub fn scatter(&mut self, data: &[u8]) { 1459cde5492fSlogin let mut data: &[u8] = data; 1460cde5492fSlogin for slice in self.0.iter_mut() { 1461cde5492fSlogin let len = core::cmp::min(slice.len(), data.len()); 1462cde5492fSlogin if len == 0 { 1463cde5492fSlogin continue; 1464cde5492fSlogin } 1465cde5492fSlogin 1466cde5492fSlogin slice[..len].copy_from_slice(&data[..len]); 1467cde5492fSlogin data = &data[len..]; 1468cde5492fSlogin } 1469cde5492fSlogin } 1470cde5492fSlogin 1471cde5492fSlogin /// @brief 创建与IoVecs等长的缓冲区 1472cde5492fSlogin /// 1473cde5492fSlogin /// @param set_len 是否设置返回的Vec的len。 1474cde5492fSlogin /// 如果为true,则返回的Vec的len为所有IoVec的长度之和; 1475cde5492fSlogin /// 否则返回的Vec的len为0,capacity为所有IoVec的长度之和. 1476cde5492fSlogin /// 1477cde5492fSlogin /// @return 返回创建的缓冲区 1478cde5492fSlogin pub fn new_buf(&self, set_len: bool) -> Vec<u8> { 1479cde5492fSlogin let total_len: usize = self.0.iter().map(|slice| slice.len()).sum(); 1480cde5492fSlogin let mut buf: Vec<u8> = Vec::with_capacity(total_len); 1481cde5492fSlogin 1482cde5492fSlogin if set_len { 14837ae679ddSLoGin buf.resize(total_len, 0); 1484cde5492fSlogin } 1485cde5492fSlogin return buf; 1486cde5492fSlogin } 1487cde5492fSlogin } 1488