xref: /DragonOS/kernel/src/filesystem/vfs/syscall.rs (revision 55e6f0b65f91b32638fd56581f711a816eccdcd1)
1 use core::ffi::c_void;
2 use core::mem::size_of;
3 
4 use alloc::{string::String, sync::Arc, vec::Vec};
5 use log::warn;
6 use system_error::SystemError;
7 
8 use crate::producefs;
9 use crate::syscall::user_access::UserBufferReader;
10 use crate::{
11     driver::base::{block::SeekFrom, device::device_number::DeviceNumber},
12     filesystem::vfs::{core as Vcore, file::FileDescriptorVec},
13     libs::rwlock::RwLockWriteGuard,
14     mm::{verify_area, VirtAddr},
15     process::ProcessManager,
16     syscall::{
17         user_access::{self, check_and_clone_cstr, UserBufferWriter},
18         Syscall,
19     },
20     time::{syscall::PosixTimeval, PosixTimeSpec},
21 };
22 
23 use super::core::do_symlinkat;
24 use super::{
25     core::{do_mkdir_at, do_remove_dir, do_unlink_at},
26     fcntl::{AtFlags, FcntlCommand, FD_CLOEXEC},
27     file::{File, FileMode},
28     open::{
29         do_faccessat, do_fchmodat, do_fchownat, do_sys_open, do_utimensat, do_utimes, ksys_fchown,
30     },
31     utils::{rsplit_path, user_path_at},
32     Dirent, FileType, IndexNode, SuperBlock, FSMAKER, MAX_PATHLEN, ROOT_INODE,
33     VFS_MAX_FOLLOW_SYMLINK_TIMES,
34 };
35 
36 pub const SEEK_SET: u32 = 0;
37 pub const SEEK_CUR: u32 = 1;
38 pub const SEEK_END: u32 = 2;
39 pub const SEEK_MAX: u32 = 3;
40 
41 bitflags! {
42     /// 文件类型和权限
43     #[repr(C)]
44     pub struct ModeType: u32 {
45         /// 掩码
46         const S_IFMT = 0o0_170_000;
47         /// 文件类型
48         const S_IFSOCK = 0o140000;
49         const S_IFLNK = 0o120000;
50         const S_IFREG = 0o100000;
51         const S_IFBLK = 0o060000;
52         const S_IFDIR = 0o040000;
53         const S_IFCHR = 0o020000;
54         const S_IFIFO = 0o010000;
55 
56         const S_ISUID = 0o004000;
57         const S_ISGID = 0o002000;
58         const S_ISVTX = 0o001000;
59         /// 文件用户权限
60         const S_IRWXU = 0o0700;
61         const S_IRUSR = 0o0400;
62         const S_IWUSR = 0o0200;
63         const S_IXUSR = 0o0100;
64         /// 文件组权限
65         const S_IRWXG = 0o0070;
66         const S_IRGRP = 0o0040;
67         const S_IWGRP = 0o0020;
68         const S_IXGRP = 0o0010;
69         /// 文件其他用户权限
70         const S_IRWXO = 0o0007;
71         const S_IROTH = 0o0004;
72         const S_IWOTH = 0o0002;
73         const S_IXOTH = 0o0001;
74 
75         /// 0o777
76         const S_IRWXUGO = Self::S_IRWXU.bits | Self::S_IRWXG.bits | Self::S_IRWXO.bits;
77         /// 0o7777
78         const S_IALLUGO = Self::S_ISUID.bits | Self::S_ISGID.bits | Self::S_ISVTX.bits| Self::S_IRWXUGO.bits;
79         /// 0o444
80         const S_IRUGO = Self::S_IRUSR.bits | Self::S_IRGRP.bits | Self::S_IROTH.bits;
81         /// 0o222
82         const S_IWUGO = Self::S_IWUSR.bits | Self::S_IWGRP.bits | Self::S_IWOTH.bits;
83         /// 0o111
84         const S_IXUGO = Self::S_IXUSR.bits | Self::S_IXGRP.bits | Self::S_IXOTH.bits;
85 
86 
87     }
88 }
89 
90 #[repr(C)]
91 #[derive(Clone, Copy)]
92 /// # 文件信息结构体
93 pub struct PosixKstat {
94     /// 硬件设备ID
95     dev_id: u64,
96     /// inode号
97     inode: u64,
98     /// 硬链接数
99     nlink: u64,
100     /// 文件权限
101     mode: ModeType,
102     /// 所有者用户ID
103     uid: i32,
104     /// 所有者组ID
105     gid: i32,
106     /// 设备ID
107     rdev: i64,
108     /// 文件大小
109     size: i64,
110     /// 文件系统块大小
111     blcok_size: i64,
112     /// 分配的512B块数
113     blocks: u64,
114     /// 最后访问时间
115     atime: PosixTimeSpec,
116     /// 最后修改时间
117     mtime: PosixTimeSpec,
118     /// 最后状态变化时间
119     ctime: PosixTimeSpec,
120     /// 用于填充结构体大小的空白数据
121     pub _pad: [i8; 24],
122 }
123 impl PosixKstat {
124     fn new() -> Self {
125         Self {
126             inode: 0,
127             dev_id: 0,
128             mode: ModeType { bits: 0 },
129             nlink: 0,
130             uid: 0,
131             gid: 0,
132             rdev: 0,
133             size: 0,
134             atime: PosixTimeSpec {
135                 tv_sec: 0,
136                 tv_nsec: 0,
137             },
138             mtime: PosixTimeSpec {
139                 tv_sec: 0,
140                 tv_nsec: 0,
141             },
142             ctime: PosixTimeSpec {
143                 tv_sec: 0,
144                 tv_nsec: 0,
145             },
146             blcok_size: 0,
147             blocks: 0,
148             _pad: Default::default(),
149         }
150     }
151 }
152 
153 #[repr(C)]
154 #[derive(Clone, Copy)]
155 /// # 文件信息结构体X
156 pub struct PosixStatx {
157     /* 0x00 */
158     stx_mask: PosixStatxMask,
159     /// 文件系统块大小
160     stx_blksize: u32,
161     /// Flags conveying information about the file [uncond]
162     stx_attributes: StxAttributes,
163     /* 0x10 */
164     /// 硬链接数
165     stx_nlink: u32,
166     /// 所有者用户ID
167     stx_uid: u32,
168     /// 所有者组ID
169     stx_gid: u32,
170     /// 文件权限
171     stx_mode: ModeType,
172 
173     /* 0x20 */
174     /// inode号
175     stx_inode: u64,
176     /// 文件大小
177     stx_size: i64,
178     /// 分配的512B块数
179     stx_blocks: u64,
180     /// Mask to show what's supported in stx_attributes
181     stx_attributes_mask: StxAttributes,
182 
183     /* 0x40 */
184     /// 最后访问时间
185     stx_atime: PosixTimeSpec,
186     /// 文件创建时间
187     stx_btime: PosixTimeSpec,
188     /// 最后状态变化时间
189     stx_ctime: PosixTimeSpec,
190     /// 最后修改时间
191     stx_mtime: PosixTimeSpec,
192 
193     /* 0x80 */
194     /// 主设备ID
195     stx_rdev_major: u32,
196     /// 次设备ID
197     stx_rdev_minor: u32,
198     /// 主硬件设备ID
199     stx_dev_major: u32,
200     /// 次硬件设备ID
201     stx_dev_minor: u32,
202 
203     /* 0x90 */
204     stx_mnt_id: u64,
205     stx_dio_mem_align: u32,
206     stx_dio_offset_align: u32,
207 }
208 impl PosixStatx {
209     fn new() -> Self {
210         Self {
211             stx_mask: PosixStatxMask::STATX_BASIC_STATS,
212             stx_blksize: 0,
213             stx_attributes: StxAttributes::STATX_ATTR_APPEND,
214             stx_nlink: 0,
215             stx_uid: 0,
216             stx_gid: 0,
217             stx_mode: ModeType { bits: 0 },
218             stx_inode: 0,
219             stx_size: 0,
220             stx_blocks: 0,
221             stx_attributes_mask: StxAttributes::STATX_ATTR_APPEND,
222             stx_atime: PosixTimeSpec {
223                 tv_sec: 0,
224                 tv_nsec: 0,
225             },
226             stx_btime: PosixTimeSpec {
227                 tv_sec: 0,
228                 tv_nsec: 0,
229             },
230             stx_ctime: PosixTimeSpec {
231                 tv_sec: 0,
232                 tv_nsec: 0,
233             },
234             stx_mtime: PosixTimeSpec {
235                 tv_sec: 0,
236                 tv_nsec: 0,
237             },
238             stx_rdev_major: 0,
239             stx_rdev_minor: 0,
240             stx_dev_major: 0,
241             stx_dev_minor: 0,
242             stx_mnt_id: 0,
243             stx_dio_mem_align: 0,
244             stx_dio_offset_align: 0,
245         }
246     }
247 }
248 
249 bitflags! {
250     pub struct PosixStatxMask: u32{
251         ///  Want stx_mode & S_IFMT
252         const STATX_TYPE = 0x00000001;
253 
254         /// Want stx_mode & ~S_IFMT
255         const STATX_MODE = 0x00000002;
256 
257         /// Want stx_nlink
258         const STATX_NLINK = 0x00000004;
259 
260         /// Want stx_uid
261         const STATX_UID = 0x00000008;
262 
263         /// Want stx_gid
264         const STATX_GID = 0x00000010;
265 
266         /// Want stx_atime
267         const STATX_ATIME = 0x00000020;
268 
269         /// Want stx_mtime
270         const STATX_MTIME = 0x00000040;
271 
272         /// Want stx_ctime
273         const STATX_CTIME = 0x00000080;
274 
275         /// Want stx_ino
276         const STATX_INO = 0x00000100;
277 
278         /// Want stx_size
279         const STATX_SIZE = 0x00000200;
280 
281         /// Want stx_blocks
282         const STATX_BLOCKS = 0x00000400;
283 
284         /// [All of the above]
285         const STATX_BASIC_STATS = 0x000007ff;
286 
287         /// Want stx_btime
288         const STATX_BTIME = 0x00000800;
289 
290         /// The same as STATX_BASIC_STATS | STATX_BTIME.
291         /// It is deprecated and should not be used.
292         const STATX_ALL = 0x00000fff;
293 
294         /// Want stx_mnt_id (since Linux 5.8)
295         const STATX_MNT_ID = 0x00001000;
296 
297         /// Want stx_dio_mem_align and stx_dio_offset_align
298         /// (since Linux 6.1; support varies by filesystem)
299         const STATX_DIOALIGN = 0x00002000;
300 
301         /// Reserved for future struct statx expansion
302         const STATX_RESERVED = 0x80000000;
303     }
304 }
305 
306 bitflags! {
307     pub struct StxAttributes: u64 {
308         /// 文件被文件系统压缩
309         const STATX_ATTR_COMPRESSED = 0x00000004;
310         /// 文件被标记为不可修改
311         const STATX_ATTR_IMMUTABLE = 0x00000010;
312         /// 文件是只追加写入的
313         const STATX_ATTR_APPEND = 0x00000020;
314         /// 文件不会被备份
315         const STATX_ATTR_NODUMP = 0x00000040;
316         /// 文件需要密钥才能在文件系统中解密
317         const STATX_ATTR_ENCRYPTED = 0x00000800;
318         /// 目录是自动挂载触发器
319         const STATX_ATTR_AUTOMOUNT = 0x00001000;
320         /// 目录是挂载点的根目录
321         const STATX_ATTR_MOUNT_ROOT = 0x00002000;
322         /// 文件受到 Verity 保护
323         const STATX_ATTR_VERITY = 0x00100000;
324         /// 文件当前处于 DAX 状态 CPU直接访问
325         const STATX_ATTR_DAX = 0x00200000;
326     }
327 }
328 
329 bitflags! {
330     pub struct UtimensFlags: u32 {
331         /// 不需要解释符号链接
332         const AT_SYMLINK_NOFOLLOW = 0x100;
333     }
334 }
335 
336 #[repr(C)]
337 #[derive(Debug, Clone, Copy)]
338 pub struct PosixStatfs {
339     f_type: u64,
340     f_bsize: u64,
341     f_blocks: u64,
342     f_bfree: u64,
343     f_bavail: u64,
344     f_files: u64,
345     f_ffree: u64,
346     f_fsid: u64,
347     f_namelen: u64,
348     f_frsize: u64,
349     f_flags: u64,
350     f_spare: [u64; 4],
351 }
352 
353 impl From<SuperBlock> for PosixStatfs {
354     fn from(super_block: SuperBlock) -> Self {
355         Self {
356             f_type: super_block.magic.bits,
357             f_bsize: super_block.bsize,
358             f_blocks: super_block.blocks,
359             f_bfree: super_block.bfree,
360             f_bavail: super_block.bavail,
361             f_files: super_block.files,
362             f_ffree: super_block.ffree,
363             f_fsid: super_block.fsid,
364             f_namelen: super_block.namelen,
365             f_frsize: super_block.frsize,
366             f_flags: super_block.flags,
367             f_spare: [0u64; 4],
368         }
369     }
370 }
371 ///
372 ///  Arguments for how openat2(2) should open the target path. If only @flags and
373 ///  @mode are non-zero, then openat2(2) operates very similarly to openat(2).
374 ///
375 ///  However, unlike openat(2), unknown or invalid bits in @flags result in
376 ///  -EINVAL rather than being silently ignored. @mode must be zero unless one of
377 ///  {O_CREAT, O_TMPFILE} are set.
378 ///
379 /// ## 成员变量
380 ///
381 /// - flags: O_* flags.
382 /// - mode: O_CREAT/O_TMPFILE file mode.
383 /// - resolve: RESOLVE_* flags.
384 #[derive(Debug, Clone, Copy)]
385 #[repr(C)]
386 pub struct PosixOpenHow {
387     pub flags: u64,
388     pub mode: u64,
389     pub resolve: u64,
390 }
391 
392 impl PosixOpenHow {
393     #[allow(dead_code)]
394     pub fn new(flags: u64, mode: u64, resolve: u64) -> Self {
395         Self {
396             flags,
397             mode,
398             resolve,
399         }
400     }
401 }
402 
403 #[allow(dead_code)]
404 #[derive(Debug, Clone, Copy)]
405 pub struct OpenHow {
406     pub o_flags: FileMode,
407     pub mode: ModeType,
408     pub resolve: OpenHowResolve,
409 }
410 
411 impl OpenHow {
412     pub fn new(mut o_flags: FileMode, mut mode: ModeType, resolve: OpenHowResolve) -> Self {
413         if !o_flags.contains(FileMode::O_CREAT) {
414             mode = ModeType::empty();
415         }
416 
417         if o_flags.contains(FileMode::O_PATH) {
418             o_flags = o_flags.intersection(FileMode::O_PATH_FLAGS);
419         }
420 
421         Self {
422             o_flags,
423             mode,
424             resolve,
425         }
426     }
427 }
428 
429 impl From<PosixOpenHow> for OpenHow {
430     fn from(posix_open_how: PosixOpenHow) -> Self {
431         let o_flags = FileMode::from_bits_truncate(posix_open_how.flags as u32);
432         let mode = ModeType::from_bits_truncate(posix_open_how.mode as u32);
433         let resolve = OpenHowResolve::from_bits_truncate(posix_open_how.resolve);
434         return Self::new(o_flags, mode, resolve);
435     }
436 }
437 
438 bitflags! {
439     pub struct OpenHowResolve: u64{
440         /// Block mount-point crossings
441         ///     (including bind-mounts).
442         const RESOLVE_NO_XDEV = 0x01;
443 
444         /// Block traversal through procfs-style
445         ///     "magic-links"
446         const RESOLVE_NO_MAGICLINKS = 0x02;
447 
448         /// Block traversal through all symlinks
449         ///     (implies OEXT_NO_MAGICLINKS)
450         const RESOLVE_NO_SYMLINKS = 0x04;
451         /// Block "lexical" trickery like
452         ///     "..", symlinks, and absolute
453         const RESOLVE_BENEATH = 0x08;
454         /// Make all jumps to "/" and ".."
455         ///     be scoped inside the dirfd
456         ///     (similar to chroot(2)).
457         const RESOLVE_IN_ROOT = 0x10;
458         // Only complete if resolution can be
459         // 			completed through cached lookup. May
460         // 			return -EAGAIN if that's not
461         // 			possible.
462         const RESOLVE_CACHED = 0x20;
463     }
464 }
465 
466 bitflags! {
467     pub struct UmountFlag: i32 {
468         const DEFAULT = 0;          /* Default call to umount. */
469         const MNT_FORCE = 1;        /* Force unmounting.  */
470         const MNT_DETACH = 2;       /* Just detach from the tree.  */
471         const MNT_EXPIRE = 4;       /* Mark for expiry.  */
472         const UMOUNT_NOFOLLOW = 8;  /* Don't follow symlink on umount.  */
473     }
474 }
475 
476 impl Syscall {
477     /// @brief 为当前进程打开一个文件
478     ///
479     /// @param path 文件路径
480     /// @param o_flags 打开文件的标志位
481     ///
482     /// @return 文件描述符编号,或者是错误码
483     pub fn open(
484         path: *const u8,
485         o_flags: u32,
486         mode: u32,
487         follow_symlink: bool,
488     ) -> Result<usize, SystemError> {
489         let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
490             .into_string()
491             .map_err(|_| SystemError::EINVAL)?;
492 
493         let open_flags: FileMode = FileMode::from_bits(o_flags).ok_or(SystemError::EINVAL)?;
494         let mode = ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?;
495         return do_sys_open(
496             AtFlags::AT_FDCWD.bits(),
497             &path,
498             open_flags,
499             mode,
500             follow_symlink,
501         );
502     }
503 
504     pub fn openat(
505         dirfd: i32,
506         path: *const u8,
507         o_flags: u32,
508         mode: u32,
509         follow_symlink: bool,
510     ) -> Result<usize, SystemError> {
511         let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
512             .into_string()
513             .map_err(|_| SystemError::EINVAL)?;
514 
515         let open_flags: FileMode = FileMode::from_bits(o_flags).ok_or(SystemError::EINVAL)?;
516         let mode = ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?;
517         return do_sys_open(dirfd, &path, open_flags, mode, follow_symlink);
518     }
519 
520     /// @brief 关闭文件
521     ///
522     /// @param fd 文件描述符编号
523     ///
524     /// @return 成功返回0,失败返回错误码
525     pub fn close(fd: usize) -> Result<usize, SystemError> {
526         let binding = ProcessManager::current_pcb().fd_table();
527         let mut fd_table_guard = binding.write();
528         let _file = fd_table_guard.drop_fd(fd as i32)?;
529         drop(fd_table_guard);
530         Ok(0)
531     }
532 
533     /// @brief 发送命令到文件描述符对应的设备,
534     ///
535     /// @param fd 文件描述符编号
536     /// @param cmd 设备相关的请求类型
537     ///
538     /// @return Ok(usize) 成功返回0
539     /// @return Err(SystemError) 读取失败,返回posix错误码
540     pub fn ioctl(fd: usize, cmd: u32, data: usize) -> Result<usize, SystemError> {
541         let binding = ProcessManager::current_pcb().fd_table();
542         let fd_table_guard = binding.read();
543 
544         let file = fd_table_guard
545             .get_file_by_fd(fd as i32)
546             .ok_or(SystemError::EBADF)?;
547 
548         // drop guard 以避免无法调度的问题
549         drop(fd_table_guard);
550         let r = file.inode().ioctl(cmd, data, &file.private_data.lock());
551         return r;
552     }
553 
554     /// @brief 根据文件描述符,读取文件数据。尝试读取的数据长度与buf的长度相同。
555     ///
556     /// @param fd 文件描述符编号
557     /// @param buf 输出缓冲区
558     ///
559     /// @return Ok(usize) 成功读取的数据的字节数
560     /// @return Err(SystemError) 读取失败,返回posix错误码
561     pub fn read(fd: i32, buf: &mut [u8]) -> Result<usize, SystemError> {
562         let binding = ProcessManager::current_pcb().fd_table();
563         let fd_table_guard = binding.read();
564 
565         let file = fd_table_guard.get_file_by_fd(fd);
566         if file.is_none() {
567             return Err(SystemError::EBADF);
568         }
569         // drop guard 以避免无法调度的问题
570         drop(fd_table_guard);
571         let file = file.unwrap();
572 
573         return file.read(buf.len(), buf);
574     }
575 
576     /// @brief 根据文件描述符,向文件写入数据。尝试写入的数据长度与buf的长度相同。
577     ///
578     /// @param fd 文件描述符编号
579     /// @param buf 输入缓冲区
580     ///
581     /// @return Ok(usize) 成功写入的数据的字节数
582     /// @return Err(SystemError) 写入失败,返回posix错误码
583     pub fn write(fd: i32, buf: &[u8]) -> Result<usize, SystemError> {
584         let binding = ProcessManager::current_pcb().fd_table();
585         let fd_table_guard = binding.read();
586 
587         let file = fd_table_guard
588             .get_file_by_fd(fd)
589             .ok_or(SystemError::EBADF)?;
590 
591         // drop guard 以避免无法调度的问题
592         drop(fd_table_guard);
593         return file.write(buf.len(), buf);
594     }
595 
596     /// @brief 调整文件操作指针的位置
597     ///
598     /// @param fd 文件描述符编号
599     /// @param seek 调整的方式
600     ///
601     /// @return Ok(usize) 调整后,文件访问指针相对于文件头部的偏移量
602     /// @return Err(SystemError) 调整失败,返回posix错误码
603     pub fn lseek(fd: i32, offset: i64, seek: u32) -> Result<usize, SystemError> {
604         let seek = match seek {
605             SEEK_SET => Ok(SeekFrom::SeekSet(offset)),
606             SEEK_CUR => Ok(SeekFrom::SeekCurrent(offset)),
607             SEEK_END => Ok(SeekFrom::SeekEnd(offset)),
608             SEEK_MAX => Ok(SeekFrom::SeekEnd(0)),
609             _ => Err(SystemError::EINVAL),
610         }?;
611 
612         let binding = ProcessManager::current_pcb().fd_table();
613         let fd_table_guard = binding.read();
614         let file = fd_table_guard
615             .get_file_by_fd(fd)
616             .ok_or(SystemError::EBADF)?;
617 
618         // drop guard 以避免无法调度的问题
619         drop(fd_table_guard);
620         return file.lseek(seek);
621     }
622 
623     /// # sys_pread64 系统调用的实际执行函数
624     ///
625     /// ## 参数
626     /// - `fd`: 文件描述符
627     /// - `buf`: 读出缓冲区
628     /// - `len`: 要读取的字节数
629     /// - `offset`: 文件偏移量
630     pub fn pread(fd: i32, buf: &mut [u8], len: usize, offset: usize) -> Result<usize, SystemError> {
631         let binding = ProcessManager::current_pcb().fd_table();
632         let fd_table_guard = binding.read();
633 
634         let file = fd_table_guard.get_file_by_fd(fd);
635         if file.is_none() {
636             return Err(SystemError::EBADF);
637         }
638         // drop guard 以避免无法调度的问题
639         drop(fd_table_guard);
640         let file = file.unwrap();
641 
642         return file.pread(offset, len, buf);
643     }
644 
645     /// # sys_pwrite64 系统调用的实际执行函数
646     ///
647     /// ## 参数
648     /// - `fd`: 文件描述符
649     /// - `buf`: 写入缓冲区
650     /// - `len`: 要写入的字节数
651     /// - `offset`: 文件偏移量
652     pub fn pwrite(fd: i32, buf: &[u8], len: usize, offset: usize) -> Result<usize, SystemError> {
653         let binding = ProcessManager::current_pcb().fd_table();
654         let fd_table_guard = binding.read();
655 
656         let file = fd_table_guard.get_file_by_fd(fd);
657         if file.is_none() {
658             return Err(SystemError::EBADF);
659         }
660         // drop guard 以避免无法调度的问题
661         drop(fd_table_guard);
662         let file = file.unwrap();
663 
664         return file.pwrite(offset, len, buf);
665     }
666 
667     /// @brief 切换工作目录
668     ///
669     /// @param dest_path 目标路径
670     ///
671     /// @return   返回码  描述
672     ///      0       |          成功
673     ///
674     ///   EACCESS    |        权限不足
675     ///
676     ///    ELOOP     | 解析path时遇到路径循环
677     ///
678     /// ENAMETOOLONG |       路径名过长
679     ///
680     ///    ENOENT    |  目标文件或目录不存在
681     ///
682     ///    ENODIR    |  检索期间发现非目录项
683     ///
684     ///    ENOMEM    |      系统内存不足
685     ///
686     ///    EFAULT    |       错误的地址
687     ///
688     /// ENAMETOOLONG |        路径过长
689     pub fn chdir(path: *const u8) -> Result<usize, SystemError> {
690         if path.is_null() {
691             return Err(SystemError::EFAULT);
692         }
693 
694         let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
695             .into_string()
696             .map_err(|_| SystemError::EINVAL)?;
697 
698         let proc = ProcessManager::current_pcb();
699         // Copy path to kernel space to avoid some security issues
700         let mut new_path = String::from("");
701         if !path.is_empty() {
702             let cwd = match path.as_bytes()[0] {
703                 b'/' => String::from("/"),
704                 _ => proc.basic().cwd(),
705             };
706             let mut cwd_vec: Vec<_> = cwd.split('/').filter(|&x| !x.is_empty()).collect();
707             let path_split = path.split('/').filter(|&x| !x.is_empty());
708             for seg in path_split {
709                 if seg == ".." {
710                     cwd_vec.pop();
711                 } else if seg == "." {
712                     // 当前目录
713                 } else {
714                     cwd_vec.push(seg);
715                 }
716             }
717             //proc.basic().set_path(String::from(""));
718             for seg in cwd_vec {
719                 new_path.push('/');
720                 new_path.push_str(seg);
721             }
722             if new_path.is_empty() {
723                 new_path = String::from("/");
724             }
725         }
726         let inode =
727             match ROOT_INODE().lookup_follow_symlink(&new_path, VFS_MAX_FOLLOW_SYMLINK_TIMES) {
728                 Err(_) => {
729                     return Err(SystemError::ENOENT);
730                 }
731                 Ok(i) => i,
732             };
733         let metadata = inode.metadata()?;
734         if metadata.file_type == FileType::Dir {
735             proc.basic_mut().set_cwd(new_path);
736             return Ok(0);
737         } else {
738             return Err(SystemError::ENOTDIR);
739         }
740     }
741 
742     /// @brief 获取当前进程的工作目录路径
743     ///
744     /// @param buf 指向缓冲区的指针
745     /// @param size 缓冲区的大小
746     ///
747     /// @return 成功,返回的指针指向包含工作目录路径的字符串
748     /// @return 错误,没有足够的空间
749     pub fn getcwd(buf: &mut [u8]) -> Result<VirtAddr, SystemError> {
750         let proc = ProcessManager::current_pcb();
751         let cwd = proc.basic().cwd();
752 
753         let cwd_bytes = cwd.as_bytes();
754         let cwd_len = cwd_bytes.len();
755         if cwd_len + 1 > buf.len() {
756             return Err(SystemError::ENOMEM);
757         }
758         buf[..cwd_len].copy_from_slice(cwd_bytes);
759         buf[cwd_len] = 0;
760 
761         return Ok(VirtAddr::new(buf.as_ptr() as usize));
762     }
763 
764     /// @brief 获取目录中的数据
765     ///
766     /// TODO: 这个函数的语义与Linux不一致,需要修改!!!
767     ///
768     /// @param fd 文件描述符号
769     /// @param buf 输出缓冲区
770     ///
771     /// @return 成功返回读取的字节数,失败返回错误码
772     pub fn getdents(fd: i32, buf: &mut [u8]) -> Result<usize, SystemError> {
773         let dirent =
774             unsafe { (buf.as_mut_ptr() as *mut Dirent).as_mut() }.ok_or(SystemError::EFAULT)?;
775 
776         if fd < 0 || fd as usize > FileDescriptorVec::PROCESS_MAX_FD {
777             return Err(SystemError::EBADF);
778         }
779 
780         // 获取fd
781         let binding = ProcessManager::current_pcb().fd_table();
782         let fd_table_guard = binding.read();
783         let file = fd_table_guard
784             .get_file_by_fd(fd)
785             .ok_or(SystemError::EBADF)?;
786 
787         // drop guard 以避免无法调度的问题
788         drop(fd_table_guard);
789 
790         let res = file.readdir(dirent).map(|x| x as usize);
791 
792         return res;
793     }
794 
795     /// @brief 创建文件夹
796     ///
797     /// @param path(r8) 路径 / mode(r9) 模式
798     ///
799     /// @return uint64_t 负数错误码 / 0表示成功
800     pub fn mkdir(path: *const u8, mode: usize) -> Result<usize, SystemError> {
801         let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
802             .into_string()
803             .map_err(|_| SystemError::EINVAL)?;
804 
805         do_mkdir_at(
806             AtFlags::AT_FDCWD.bits(),
807             &path,
808             FileMode::from_bits_truncate(mode as u32),
809         )?;
810         return Ok(0);
811     }
812 
813     pub fn mkdir_at(dirfd: i32, path: *const u8, mode: usize) -> Result<usize, SystemError> {
814         let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
815             .into_string()
816             .map_err(|_| SystemError::EINVAL)?;
817         do_mkdir_at(dirfd, &path, FileMode::from_bits_truncate(mode as u32))?;
818         return Ok(0);
819     }
820 
821     /// **创建硬连接的系统调用**
822     ///
823     /// ## 参数
824     ///
825     /// - 'oldfd': 用于解析源文件路径的文件描述符
826     /// - 'old': 源文件路径
827     /// - 'newfd': 用于解析新文件路径的文件描述符
828     /// - 'new': 新文件将创建的路径
829     /// - 'flags': 标志位,仅以位或方式包含AT_EMPTY_PATH和AT_SYMLINK_FOLLOW
830     ///
831     ///
832     pub fn do_linkat(
833         oldfd: i32,
834         old: &str,
835         newfd: i32,
836         new: &str,
837         flags: AtFlags,
838     ) -> Result<usize, SystemError> {
839         // flag包含其他未规定值时返回EINVAL
840         if !(AtFlags::AT_EMPTY_PATH | AtFlags::AT_SYMLINK_FOLLOW).contains(flags) {
841             return Err(SystemError::EINVAL);
842         }
843         // TODO AT_EMPTY_PATH标志启用时,进行调用者CAP_DAC_READ_SEARCH或相似的检查
844         let symlink_times = if flags.contains(AtFlags::AT_SYMLINK_FOLLOW) {
845             0_usize
846         } else {
847             VFS_MAX_FOLLOW_SYMLINK_TIMES
848         };
849         let pcb = ProcessManager::current_pcb();
850 
851         // 得到源路径的inode
852         let old_inode: Arc<dyn IndexNode> = if old.is_empty() {
853             if flags.contains(AtFlags::AT_EMPTY_PATH) {
854                 // 在AT_EMPTY_PATH启用时,old可以为空,old_inode实际为oldfd所指文件,但该文件不能为目录。
855                 let binding = pcb.fd_table();
856                 let fd_table_guard = binding.read();
857                 let file = fd_table_guard
858                     .get_file_by_fd(oldfd)
859                     .ok_or(SystemError::EBADF)?;
860                 let old_inode = file.inode();
861                 old_inode
862             } else {
863                 return Err(SystemError::ENONET);
864             }
865         } else {
866             let (old_begin_inode, old_remain_path) = user_path_at(&pcb, oldfd, old)?;
867             old_begin_inode.lookup_follow_symlink(&old_remain_path, symlink_times)?
868         };
869 
870         // old_inode为目录时返回EPERM
871         if old_inode.metadata().unwrap().file_type == FileType::Dir {
872             return Err(SystemError::EPERM);
873         }
874 
875         // 得到新创建节点的父节点
876         let (new_begin_inode, new_remain_path) = user_path_at(&pcb, newfd, new)?;
877         let (new_name, new_parent_path) = rsplit_path(&new_remain_path);
878         let new_parent =
879             new_begin_inode.lookup_follow_symlink(new_parent_path.unwrap_or("/"), symlink_times)?;
880 
881         // 被调用者利用downcast_ref判断两inode是否为同一文件系统
882         return new_parent.link(new_name, &old_inode).map(|_| 0);
883     }
884 
885     pub fn link(old: *const u8, new: *const u8) -> Result<usize, SystemError> {
886         let get_path = |cstr: *const u8| -> Result<String, SystemError> {
887             let res = check_and_clone_cstr(cstr, Some(MAX_PATHLEN))?
888                 .into_string()
889                 .map_err(|_| SystemError::EINVAL)?;
890 
891             if res.len() >= MAX_PATHLEN {
892                 return Err(SystemError::ENAMETOOLONG);
893             }
894             if res.is_empty() {
895                 return Err(SystemError::ENOENT);
896             }
897             Ok(res)
898         };
899         let old = get_path(old)?;
900         let new = get_path(new)?;
901         return Self::do_linkat(
902             AtFlags::AT_FDCWD.bits(),
903             &old,
904             AtFlags::AT_FDCWD.bits(),
905             &new,
906             AtFlags::empty(),
907         );
908     }
909 
910     pub fn linkat(
911         oldfd: i32,
912         old: *const u8,
913         newfd: i32,
914         new: *const u8,
915         flags: i32,
916     ) -> Result<usize, SystemError> {
917         let old = check_and_clone_cstr(old, Some(MAX_PATHLEN))?
918             .into_string()
919             .map_err(|_| SystemError::EINVAL)?;
920         let new = check_and_clone_cstr(new, Some(MAX_PATHLEN))?
921             .into_string()
922             .map_err(|_| SystemError::EINVAL)?;
923         if old.len() >= MAX_PATHLEN || new.len() >= MAX_PATHLEN {
924             return Err(SystemError::ENAMETOOLONG);
925         }
926         // old 根据flags & AtFlags::AT_EMPTY_PATH判空
927         if new.is_empty() {
928             return Err(SystemError::ENOENT);
929         }
930         let flags = AtFlags::from_bits(flags).ok_or(SystemError::EINVAL)?;
931         Self::do_linkat(oldfd, &old, newfd, &new, flags)
932     }
933 
934     /// **删除文件夹、取消文件的链接、删除文件的系统调用**
935     ///
936     /// ## 参数
937     ///
938     /// - `dirfd`:文件夹的文件描述符.目前暂未实现
939     /// - `pathname`:文件夹的路径
940     /// - `flags`:标志位
941     ///
942     ///
943     pub fn unlinkat(dirfd: i32, path: *const u8, flags: u32) -> Result<usize, SystemError> {
944         let flags = AtFlags::from_bits(flags as i32).ok_or(SystemError::EINVAL)?;
945 
946         let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
947             .into_string()
948             .map_err(|_| SystemError::EINVAL)?;
949 
950         if flags.contains(AtFlags::AT_REMOVEDIR) {
951             // debug!("rmdir");
952             match do_remove_dir(dirfd, &path) {
953                 Err(err) => {
954                     return Err(err);
955                 }
956                 Ok(_) => {
957                     return Ok(0);
958                 }
959             }
960         }
961 
962         match do_unlink_at(dirfd, &path) {
963             Err(err) => {
964                 return Err(err);
965             }
966             Ok(_) => {
967                 return Ok(0);
968             }
969         }
970     }
971 
972     pub fn rmdir(path: *const u8) -> Result<usize, SystemError> {
973         let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
974             .into_string()
975             .map_err(|_| SystemError::EINVAL)?;
976         return do_remove_dir(AtFlags::AT_FDCWD.bits(), &path).map(|v| v as usize);
977     }
978 
979     pub fn unlink(path: *const u8) -> Result<usize, SystemError> {
980         let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
981             .into_string()
982             .map_err(|_| SystemError::EINVAL)?;
983         return do_unlink_at(AtFlags::AT_FDCWD.bits(), &path).map(|v| v as usize);
984     }
985 
986     pub fn symlink(oldname: *const u8, newname: *const u8) -> Result<usize, SystemError> {
987         return do_symlinkat(oldname, AtFlags::AT_FDCWD.bits(), newname);
988     }
989 
990     pub fn symlinkat(
991         oldname: *const u8,
992         newdfd: i32,
993         newname: *const u8,
994     ) -> Result<usize, SystemError> {
995         return do_symlinkat(oldname, newdfd, newname);
996     }
997 
998     /// # 修改文件名
999     ///
1000     ///
1001     /// ## 参数
1002     ///
1003     /// - oldfd: 源文件夹文件描述符
1004     /// - filename_from: 源文件路径
1005     /// - newfd: 目标文件夹文件描述符
1006     /// - filename_to: 目标文件路径
1007     /// - flags: 标志位
1008     ///
1009     ///
1010     /// ## 返回值
1011     /// - Ok(返回值类型): 返回值的说明
1012     /// - Err(错误值类型): 错误的说明
1013     ///
1014     pub fn do_renameat2(
1015         oldfd: i32,
1016         filename_from: *const u8,
1017         newfd: i32,
1018         filename_to: *const u8,
1019         _flags: u32,
1020     ) -> Result<usize, SystemError> {
1021         let filename_from = check_and_clone_cstr(filename_from, Some(MAX_PATHLEN))
1022             .unwrap()
1023             .into_string()
1024             .map_err(|_| SystemError::EINVAL)?;
1025         let filename_to = check_and_clone_cstr(filename_to, Some(MAX_PATHLEN))
1026             .unwrap()
1027             .into_string()
1028             .map_err(|_| SystemError::EINVAL)?;
1029         // 文件名过长
1030         if filename_from.len() > MAX_PATHLEN || filename_to.len() > MAX_PATHLEN {
1031             return Err(SystemError::ENAMETOOLONG);
1032         }
1033 
1034         //获取pcb,文件节点
1035         let pcb = ProcessManager::current_pcb();
1036         let (_old_inode_begin, old_remain_path) = user_path_at(&pcb, oldfd, &filename_from)?;
1037         let (_new_inode_begin, new_remain_path) = user_path_at(&pcb, newfd, &filename_to)?;
1038         //获取父目录
1039         let (old_filename, old_parent_path) = rsplit_path(&old_remain_path);
1040         let old_parent_inode = ROOT_INODE()
1041             .lookup_follow_symlink(old_parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
1042         let (new_filename, new_parent_path) = rsplit_path(&new_remain_path);
1043         let new_parent_inode = ROOT_INODE()
1044             .lookup_follow_symlink(new_parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
1045         old_parent_inode.move_to(old_filename, &new_parent_inode, new_filename)?;
1046         return Ok(0);
1047     }
1048 
1049     /// @brief 根据提供的文件描述符的fd,复制对应的文件结构体,并返回新复制的文件结构体对应的fd
1050     pub fn dup(oldfd: i32) -> Result<usize, SystemError> {
1051         let binding = ProcessManager::current_pcb().fd_table();
1052         let mut fd_table_guard = binding.write();
1053 
1054         let old_file = fd_table_guard
1055             .get_file_by_fd(oldfd)
1056             .ok_or(SystemError::EBADF)?;
1057 
1058         let new_file = old_file.try_clone().ok_or(SystemError::EBADF)?;
1059         // dup默认非cloexec
1060         new_file.set_close_on_exec(false);
1061         // 申请文件描述符,并把文件对象存入其中
1062         let res = fd_table_guard.alloc_fd(new_file, None).map(|x| x as usize);
1063         return res;
1064     }
1065 
1066     /// 根据提供的文件描述符的fd,和指定新fd,复制对应的文件结构体,
1067     /// 并返回新复制的文件结构体对应的fd.
1068     /// 如果新fd已经打开,则会先关闭新fd.
1069     ///
1070     /// ## 参数
1071     ///
1072     /// - `oldfd`:旧文件描述符
1073     /// - `newfd`:新文件描述符
1074     ///
1075     /// ## 返回值
1076     ///
1077     /// - 成功:新文件描述符
1078     /// - 失败:错误码
1079     pub fn dup2(oldfd: i32, newfd: i32) -> Result<usize, SystemError> {
1080         let binding = ProcessManager::current_pcb().fd_table();
1081         let mut fd_table_guard = binding.write();
1082         return Self::do_dup2(oldfd, newfd, &mut fd_table_guard);
1083     }
1084 
1085     pub fn dup3(oldfd: i32, newfd: i32, flags: u32) -> Result<usize, SystemError> {
1086         let flags = FileMode::from_bits_truncate(flags);
1087         if (flags.bits() & !FileMode::O_CLOEXEC.bits()) != 0 {
1088             return Err(SystemError::EINVAL);
1089         }
1090 
1091         if oldfd == newfd {
1092             return Err(SystemError::EINVAL);
1093         }
1094 
1095         let binding = ProcessManager::current_pcb().fd_table();
1096         let mut fd_table_guard = binding.write();
1097         return Self::do_dup3(oldfd, newfd, flags, &mut fd_table_guard);
1098     }
1099 
1100     fn do_dup2(
1101         oldfd: i32,
1102         newfd: i32,
1103         fd_table_guard: &mut RwLockWriteGuard<'_, FileDescriptorVec>,
1104     ) -> Result<usize, SystemError> {
1105         Self::do_dup3(oldfd, newfd, FileMode::empty(), fd_table_guard)
1106     }
1107 
1108     fn do_dup3(
1109         oldfd: i32,
1110         newfd: i32,
1111         flags: FileMode,
1112         fd_table_guard: &mut RwLockWriteGuard<'_, FileDescriptorVec>,
1113     ) -> Result<usize, SystemError> {
1114         // 确认oldfd, newid是否有效
1115         if !(FileDescriptorVec::validate_fd(oldfd) && FileDescriptorVec::validate_fd(newfd)) {
1116             return Err(SystemError::EBADF);
1117         }
1118 
1119         if oldfd == newfd {
1120             // 若oldfd与newfd相等
1121             return Ok(newfd as usize);
1122         }
1123         let new_exists = fd_table_guard.get_file_by_fd(newfd).is_some();
1124         if new_exists {
1125             // close newfd
1126             if fd_table_guard.drop_fd(newfd).is_err() {
1127                 // An I/O error occurred while attempting to close fildes2.
1128                 return Err(SystemError::EIO);
1129             }
1130         }
1131 
1132         let old_file = fd_table_guard
1133             .get_file_by_fd(oldfd)
1134             .ok_or(SystemError::EBADF)?;
1135         let new_file = old_file.try_clone().ok_or(SystemError::EBADF)?;
1136 
1137         if flags.contains(FileMode::O_CLOEXEC) {
1138             new_file.set_close_on_exec(true);
1139         } else {
1140             new_file.set_close_on_exec(false);
1141         }
1142         // 申请文件描述符,并把文件对象存入其中
1143         let res = fd_table_guard
1144             .alloc_fd(new_file, Some(newfd))
1145             .map(|x| x as usize);
1146         return res;
1147     }
1148 
1149     /// # fcntl
1150     ///
1151     /// ## 参数
1152     ///
1153     /// - `fd`:文件描述符
1154     /// - `cmd`:命令
1155     /// - `arg`:参数
1156     pub fn fcntl(fd: i32, cmd: FcntlCommand, arg: i32) -> Result<usize, SystemError> {
1157         // debug!("fcntl ({cmd:?}) fd: {fd}, arg={arg}");
1158         match cmd {
1159             FcntlCommand::DupFd | FcntlCommand::DupFdCloexec => {
1160                 if arg < 0 || arg as usize >= FileDescriptorVec::PROCESS_MAX_FD {
1161                     return Err(SystemError::EBADF);
1162                 }
1163                 let arg = arg as usize;
1164                 for i in arg..FileDescriptorVec::PROCESS_MAX_FD {
1165                     let binding = ProcessManager::current_pcb().fd_table();
1166                     let mut fd_table_guard = binding.write();
1167                     if fd_table_guard.get_file_by_fd(i as i32).is_none() {
1168                         if cmd == FcntlCommand::DupFd {
1169                             return Self::do_dup2(fd, i as i32, &mut fd_table_guard);
1170                         } else {
1171                             return Self::do_dup3(
1172                                 fd,
1173                                 i as i32,
1174                                 FileMode::O_CLOEXEC,
1175                                 &mut fd_table_guard,
1176                             );
1177                         }
1178                     }
1179                 }
1180                 return Err(SystemError::EMFILE);
1181             }
1182             FcntlCommand::GetFd => {
1183                 // Get file descriptor flags.
1184                 let binding = ProcessManager::current_pcb().fd_table();
1185                 let fd_table_guard = binding.read();
1186 
1187                 if let Some(file) = fd_table_guard.get_file_by_fd(fd) {
1188                     // drop guard 以避免无法调度的问题
1189                     drop(fd_table_guard);
1190 
1191                     if file.close_on_exec() {
1192                         return Ok(FD_CLOEXEC as usize);
1193                     } else {
1194                         return Ok(0);
1195                     }
1196                 }
1197                 return Err(SystemError::EBADF);
1198             }
1199             FcntlCommand::SetFd => {
1200                 // Set file descriptor flags.
1201                 let binding = ProcessManager::current_pcb().fd_table();
1202                 let fd_table_guard = binding.write();
1203 
1204                 if let Some(file) = fd_table_guard.get_file_by_fd(fd) {
1205                     // drop guard 以避免无法调度的问题
1206                     drop(fd_table_guard);
1207                     let arg = arg as u32;
1208                     if arg & FD_CLOEXEC != 0 {
1209                         file.set_close_on_exec(true);
1210                     } else {
1211                         file.set_close_on_exec(false);
1212                     }
1213                     return Ok(0);
1214                 }
1215                 return Err(SystemError::EBADF);
1216             }
1217 
1218             FcntlCommand::GetFlags => {
1219                 // Get file status flags.
1220                 let binding = ProcessManager::current_pcb().fd_table();
1221                 let fd_table_guard = binding.read();
1222 
1223                 if let Some(file) = fd_table_guard.get_file_by_fd(fd) {
1224                     // drop guard 以避免无法调度的问题
1225                     drop(fd_table_guard);
1226                     return Ok(file.mode().bits() as usize);
1227                 }
1228 
1229                 return Err(SystemError::EBADF);
1230             }
1231             FcntlCommand::SetFlags => {
1232                 // Set file status flags.
1233                 let binding = ProcessManager::current_pcb().fd_table();
1234                 let fd_table_guard = binding.write();
1235 
1236                 if let Some(file) = fd_table_guard.get_file_by_fd(fd) {
1237                     let arg = arg as u32;
1238                     let mode = FileMode::from_bits(arg).ok_or(SystemError::EINVAL)?;
1239                     // drop guard 以避免无法调度的问题
1240                     drop(fd_table_guard);
1241                     file.set_mode(mode)?;
1242                     return Ok(0);
1243                 }
1244 
1245                 return Err(SystemError::EBADF);
1246             }
1247             _ => {
1248                 // TODO: unimplemented
1249                 // 未实现的命令,返回0,不报错。
1250 
1251                 warn!("fcntl: unimplemented command: {:?}, defaults to 0.", cmd);
1252                 return Err(SystemError::ENOSYS);
1253             }
1254         }
1255     }
1256 
1257     /// # ftruncate
1258     ///
1259     /// ## 描述
1260     ///
1261     /// 改变文件大小.
1262     /// 如果文件大小大于原来的大小,那么文件的内容将会被扩展到指定的大小,新的空间将会用0填充.
1263     /// 如果文件大小小于原来的大小,那么文件的内容将会被截断到指定的大小.
1264     ///
1265     /// ## 参数
1266     ///
1267     /// - `fd`:文件描述符
1268     /// - `len`:文件大小
1269     ///
1270     /// ## 返回值
1271     ///
1272     /// 如果成功,返回0,否则返回错误码.
1273     pub fn ftruncate(fd: i32, len: usize) -> Result<usize, SystemError> {
1274         let binding = ProcessManager::current_pcb().fd_table();
1275         let fd_table_guard = binding.read();
1276 
1277         if let Some(file) = fd_table_guard.get_file_by_fd(fd) {
1278             // drop guard 以避免无法调度的问题
1279             drop(fd_table_guard);
1280             let r = file.ftruncate(len).map(|_| 0);
1281             return r;
1282         }
1283 
1284         return Err(SystemError::EBADF);
1285     }
1286 
1287     fn do_fstat(fd: i32) -> Result<PosixKstat, SystemError> {
1288         let binding = ProcessManager::current_pcb().fd_table();
1289         let fd_table_guard = binding.read();
1290         let file = fd_table_guard
1291             .get_file_by_fd(fd)
1292             .ok_or(SystemError::EBADF)?;
1293         // drop guard 以避免无法调度的问题
1294         drop(fd_table_guard);
1295 
1296         let mut kstat = PosixKstat::new();
1297         // 获取文件信息
1298         let metadata = file.metadata()?;
1299         kstat.size = metadata.size;
1300         kstat.dev_id = metadata.dev_id as u64;
1301         kstat.inode = metadata.inode_id.into() as u64;
1302         kstat.blcok_size = metadata.blk_size as i64;
1303         kstat.blocks = metadata.blocks as u64;
1304 
1305         kstat.atime.tv_sec = metadata.atime.tv_sec;
1306         kstat.atime.tv_nsec = metadata.atime.tv_nsec;
1307         kstat.mtime.tv_sec = metadata.mtime.tv_sec;
1308         kstat.mtime.tv_nsec = metadata.mtime.tv_nsec;
1309         kstat.ctime.tv_sec = metadata.ctime.tv_sec;
1310         kstat.ctime.tv_nsec = metadata.ctime.tv_nsec;
1311 
1312         kstat.nlink = metadata.nlinks as u64;
1313         kstat.uid = metadata.uid as i32;
1314         kstat.gid = metadata.gid as i32;
1315         kstat.rdev = metadata.raw_dev.data() as i64;
1316         kstat.mode = metadata.mode;
1317         match file.file_type() {
1318             FileType::File => kstat.mode.insert(ModeType::S_IFREG),
1319             FileType::Dir => kstat.mode.insert(ModeType::S_IFDIR),
1320             FileType::BlockDevice => kstat.mode.insert(ModeType::S_IFBLK),
1321             FileType::CharDevice => kstat.mode.insert(ModeType::S_IFCHR),
1322             FileType::SymLink => kstat.mode.insert(ModeType::S_IFLNK),
1323             FileType::Socket => kstat.mode.insert(ModeType::S_IFSOCK),
1324             FileType::Pipe => kstat.mode.insert(ModeType::S_IFIFO),
1325             FileType::KvmDevice => kstat.mode.insert(ModeType::S_IFCHR),
1326             FileType::FramebufferDevice => kstat.mode.insert(ModeType::S_IFCHR),
1327         }
1328 
1329         return Ok(kstat);
1330     }
1331 
1332     pub fn fstat(fd: i32, usr_kstat: *mut PosixKstat) -> Result<usize, SystemError> {
1333         let mut writer = UserBufferWriter::new(usr_kstat, size_of::<PosixKstat>(), true)?;
1334         let kstat = Self::do_fstat(fd)?;
1335 
1336         writer.copy_one_to_user(&kstat, 0)?;
1337         return Ok(0);
1338     }
1339 
1340     pub fn stat(path: *const u8, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> {
1341         let fd = Self::open(
1342             path,
1343             FileMode::O_RDONLY.bits(),
1344             ModeType::empty().bits(),
1345             true,
1346         )?;
1347         let r = Self::fstat(fd as i32, user_kstat);
1348         Self::close(fd).ok();
1349         return r;
1350     }
1351 
1352     pub fn lstat(path: *const u8, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> {
1353         let fd = Self::open(
1354             path,
1355             FileMode::O_RDONLY.bits(),
1356             ModeType::empty().bits(),
1357             false,
1358         )?;
1359         let r = Self::fstat(fd as i32, user_kstat);
1360         Self::close(fd).ok();
1361         return r;
1362     }
1363 
1364     pub fn statfs(path: *const u8, user_statfs: *mut PosixStatfs) -> Result<usize, SystemError> {
1365         let mut writer = UserBufferWriter::new(user_statfs, size_of::<PosixStatfs>(), true)?;
1366         let fd = Self::open(
1367             path,
1368             FileMode::O_RDONLY.bits(),
1369             ModeType::empty().bits(),
1370             true,
1371         )?;
1372         let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))
1373             .unwrap()
1374             .into_string()
1375             .map_err(|_| SystemError::EINVAL)?;
1376         let pcb = ProcessManager::current_pcb();
1377         let (_inode_begin, remain_path) = user_path_at(&pcb, fd as i32, &path)?;
1378         let inode = ROOT_INODE().lookup_follow_symlink(&remain_path, MAX_PATHLEN)?;
1379         let statfs = PosixStatfs::from(inode.fs().super_block());
1380         writer.copy_one_to_user(&statfs, 0)?;
1381         return Ok(0);
1382     }
1383 
1384     pub fn fstatfs(fd: i32, user_statfs: *mut PosixStatfs) -> Result<usize, SystemError> {
1385         let mut writer = UserBufferWriter::new(user_statfs, size_of::<PosixStatfs>(), true)?;
1386         let binding = ProcessManager::current_pcb().fd_table();
1387         let fd_table_guard = binding.read();
1388         let file = fd_table_guard
1389             .get_file_by_fd(fd)
1390             .ok_or(SystemError::EBADF)?;
1391         drop(fd_table_guard);
1392         let statfs = PosixStatfs::from(file.inode().fs().super_block());
1393         writer.copy_one_to_user(&statfs, 0)?;
1394         return Ok(0);
1395     }
1396 
1397     pub fn do_statx(
1398         fd: i32,
1399         path: *const u8,
1400         flags: u32,
1401         mask: u32,
1402         usr_kstat: *mut PosixStatx,
1403     ) -> Result<usize, SystemError> {
1404         if usr_kstat.is_null() {
1405             return Err(SystemError::EFAULT);
1406         }
1407 
1408         let mask = PosixStatxMask::from_bits_truncate(mask);
1409 
1410         if mask.contains(PosixStatxMask::STATX_RESERVED) {
1411             return Err(SystemError::ENAVAIL);
1412         }
1413 
1414         let flags = FileMode::from_bits_truncate(flags);
1415         let ofd = Self::open(path, flags.bits(), ModeType::empty().bits, true)?;
1416 
1417         let binding = ProcessManager::current_pcb().fd_table();
1418         let fd_table_guard = binding.read();
1419         let file = fd_table_guard
1420             .get_file_by_fd(ofd as i32)
1421             .ok_or(SystemError::EBADF)?;
1422         // drop guard 以避免无法调度的问题
1423         drop(fd_table_guard);
1424         let mut writer = UserBufferWriter::new(usr_kstat, size_of::<PosixStatx>(), true)?;
1425         let mut tmp: PosixStatx = PosixStatx::new();
1426         // 获取文件信息
1427         let metadata = file.metadata()?;
1428 
1429         tmp.stx_mask |= PosixStatxMask::STATX_BASIC_STATS;
1430         tmp.stx_blksize = metadata.blk_size as u32;
1431         if mask.contains(PosixStatxMask::STATX_MODE) || mask.contains(PosixStatxMask::STATX_TYPE) {
1432             tmp.stx_mode = metadata.mode;
1433         }
1434         if mask.contains(PosixStatxMask::STATX_NLINK) {
1435             tmp.stx_nlink = metadata.nlinks as u32;
1436         }
1437         if mask.contains(PosixStatxMask::STATX_UID) {
1438             tmp.stx_uid = metadata.uid as u32;
1439         }
1440         if mask.contains(PosixStatxMask::STATX_GID) {
1441             tmp.stx_gid = metadata.gid as u32;
1442         }
1443         if mask.contains(PosixStatxMask::STATX_ATIME) {
1444             tmp.stx_atime.tv_sec = metadata.atime.tv_sec;
1445             tmp.stx_atime.tv_nsec = metadata.atime.tv_nsec;
1446         }
1447         if mask.contains(PosixStatxMask::STATX_MTIME) {
1448             tmp.stx_mtime.tv_sec = metadata.ctime.tv_sec;
1449             tmp.stx_mtime.tv_nsec = metadata.ctime.tv_nsec;
1450         }
1451         if mask.contains(PosixStatxMask::STATX_CTIME) {
1452             // ctime是文件上次修改状态的时间
1453             tmp.stx_ctime.tv_sec = metadata.mtime.tv_sec;
1454             tmp.stx_ctime.tv_nsec = metadata.mtime.tv_nsec;
1455         }
1456         if mask.contains(PosixStatxMask::STATX_INO) {
1457             tmp.stx_inode = metadata.inode_id.into() as u64;
1458         }
1459         if mask.contains(PosixStatxMask::STATX_SIZE) {
1460             tmp.stx_size = metadata.size;
1461         }
1462         if mask.contains(PosixStatxMask::STATX_BLOCKS) {
1463             tmp.stx_blocks = metadata.blocks as u64;
1464         }
1465 
1466         if mask.contains(PosixStatxMask::STATX_BTIME) {
1467             // btime是文件创建时间
1468             tmp.stx_btime.tv_sec = metadata.ctime.tv_sec;
1469             tmp.stx_btime.tv_nsec = metadata.ctime.tv_nsec;
1470         }
1471         if mask.contains(PosixStatxMask::STATX_ALL) {
1472             tmp.stx_attributes = StxAttributes::STATX_ATTR_APPEND;
1473             tmp.stx_attributes_mask |=
1474                 StxAttributes::STATX_ATTR_AUTOMOUNT | StxAttributes::STATX_ATTR_DAX;
1475             tmp.stx_dev_major = metadata.dev_id as u32;
1476             tmp.stx_dev_minor = metadata.dev_id as u32; //
1477             tmp.stx_rdev_major = metadata.raw_dev.data();
1478             tmp.stx_rdev_minor = metadata.raw_dev.data();
1479         }
1480         if mask.contains(PosixStatxMask::STATX_MNT_ID) {
1481             tmp.stx_mnt_id = 0;
1482         }
1483         if mask.contains(PosixStatxMask::STATX_DIOALIGN) {
1484             tmp.stx_dio_mem_align = 0;
1485             tmp.stx_dio_offset_align = 0;
1486         }
1487 
1488         match file.file_type() {
1489             FileType::File => tmp.stx_mode.insert(ModeType::S_IFREG),
1490             FileType::Dir => tmp.stx_mode.insert(ModeType::S_IFDIR),
1491             FileType::BlockDevice => tmp.stx_mode.insert(ModeType::S_IFBLK),
1492             FileType::CharDevice => tmp.stx_mode.insert(ModeType::S_IFCHR),
1493             FileType::SymLink => tmp.stx_mode.insert(ModeType::S_IFLNK),
1494             FileType::Socket => tmp.stx_mode.insert(ModeType::S_IFSOCK),
1495             FileType::Pipe => tmp.stx_mode.insert(ModeType::S_IFIFO),
1496             FileType::KvmDevice => tmp.stx_mode.insert(ModeType::S_IFCHR),
1497             FileType::FramebufferDevice => tmp.stx_mode.insert(ModeType::S_IFCHR),
1498         }
1499 
1500         writer.copy_one_to_user(&tmp, 0)?;
1501         Self::close(fd as usize).ok();
1502         return Ok(0);
1503     }
1504 
1505     pub fn mknod(
1506         path: *const u8,
1507         mode: ModeType,
1508         dev_t: DeviceNumber,
1509     ) -> Result<usize, SystemError> {
1510         let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
1511             .into_string()
1512             .map_err(|_| SystemError::EINVAL)?;
1513         let path = path.as_str().trim();
1514 
1515         let inode: Result<Arc<dyn IndexNode>, SystemError> =
1516             ROOT_INODE().lookup_follow_symlink(path, VFS_MAX_FOLLOW_SYMLINK_TIMES);
1517 
1518         if inode.is_ok() {
1519             return Err(SystemError::EEXIST);
1520         }
1521 
1522         let (filename, parent_path) = rsplit_path(path);
1523 
1524         // 查找父目录
1525         let parent_inode: Arc<dyn IndexNode> = ROOT_INODE()
1526             .lookup_follow_symlink(parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
1527         // 创建nod
1528         parent_inode.mknod(filename, mode, dev_t)?;
1529 
1530         return Ok(0);
1531     }
1532 
1533     pub fn writev(fd: i32, iov: usize, count: usize) -> Result<usize, SystemError> {
1534         // IoVecs会进行用户态检验
1535         let iovecs = unsafe { IoVecs::from_user(iov as *const IoVec, count, false) }?;
1536 
1537         let data = iovecs.gather();
1538 
1539         Self::write(fd, &data)
1540     }
1541 
1542     pub fn readv(fd: i32, iov: usize, count: usize) -> Result<usize, SystemError> {
1543         // IoVecs会进行用户态检验
1544         let mut iovecs = unsafe { IoVecs::from_user(iov as *const IoVec, count, true) }?;
1545 
1546         let mut data = vec![0; iovecs.0.iter().map(|x| x.len()).sum()];
1547 
1548         let len = Self::read(fd, &mut data)?;
1549 
1550         iovecs.scatter(&data[..len]);
1551 
1552         return Ok(len);
1553     }
1554 
1555     pub fn readlink_at(
1556         dirfd: i32,
1557         path: *const u8,
1558         user_buf: *mut u8,
1559         buf_size: usize,
1560     ) -> Result<usize, SystemError> {
1561         let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
1562             .into_string()
1563             .map_err(|_| SystemError::EINVAL)?;
1564         let path = path.as_str().trim();
1565         let mut user_buf = UserBufferWriter::new(user_buf, buf_size, true)?;
1566 
1567         let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, path)?;
1568 
1569         let inode = inode.lookup(path.as_str())?;
1570         if inode.metadata()?.file_type != FileType::SymLink {
1571             return Err(SystemError::EINVAL);
1572         }
1573 
1574         let ubuf = user_buf.buffer::<u8>(0).unwrap();
1575 
1576         let file = File::new(inode, FileMode::O_RDONLY)?;
1577 
1578         let len = file.read(buf_size, ubuf)?;
1579 
1580         return Ok(len);
1581     }
1582 
1583     pub fn readlink(
1584         path: *const u8,
1585         user_buf: *mut u8,
1586         buf_size: usize,
1587     ) -> Result<usize, SystemError> {
1588         return Self::readlink_at(AtFlags::AT_FDCWD.bits(), path, user_buf, buf_size);
1589     }
1590 
1591     pub fn access(pathname: *const u8, mode: u32) -> Result<usize, SystemError> {
1592         return do_faccessat(
1593             AtFlags::AT_FDCWD.bits(),
1594             pathname,
1595             ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?,
1596             0,
1597         );
1598     }
1599 
1600     pub fn faccessat2(
1601         dirfd: i32,
1602         pathname: *const u8,
1603         mode: u32,
1604         flags: u32,
1605     ) -> Result<usize, SystemError> {
1606         return do_faccessat(
1607             dirfd,
1608             pathname,
1609             ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?,
1610             flags,
1611         );
1612     }
1613 
1614     pub fn chmod(pathname: *const u8, mode: u32) -> Result<usize, SystemError> {
1615         return do_fchmodat(
1616             AtFlags::AT_FDCWD.bits(),
1617             pathname,
1618             ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?,
1619         );
1620     }
1621 
1622     pub fn fchmodat(dirfd: i32, pathname: *const u8, mode: u32) -> Result<usize, SystemError> {
1623         return do_fchmodat(
1624             dirfd,
1625             pathname,
1626             ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?,
1627         );
1628     }
1629 
1630     pub fn fchmod(fd: i32, mode: u32) -> Result<usize, SystemError> {
1631         let _mode = ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?;
1632         let binding = ProcessManager::current_pcb().fd_table();
1633         let fd_table_guard = binding.read();
1634         let _file = fd_table_guard
1635             .get_file_by_fd(fd)
1636             .ok_or(SystemError::EBADF)?;
1637 
1638         // fchmod没完全实现,因此不修改文件的权限
1639         // todo: 实现fchmod
1640         warn!("fchmod not fully implemented");
1641         return Ok(0);
1642     }
1643 
1644     pub fn chown(pathname: *const u8, uid: usize, gid: usize) -> Result<usize, SystemError> {
1645         let pathname = user_access::check_and_clone_cstr(pathname, Some(MAX_PATHLEN))?
1646             .into_string()
1647             .map_err(|_| SystemError::EINVAL)?;
1648         return do_fchownat(
1649             AtFlags::AT_FDCWD.bits(),
1650             &pathname,
1651             uid,
1652             gid,
1653             AtFlags::AT_STATX_SYNC_AS_STAT,
1654         );
1655     }
1656 
1657     pub fn lchown(pathname: *const u8, uid: usize, gid: usize) -> Result<usize, SystemError> {
1658         let pathname = user_access::check_and_clone_cstr(pathname, Some(MAX_PATHLEN))?
1659             .into_string()
1660             .map_err(|_| SystemError::EINVAL)?;
1661         return do_fchownat(
1662             AtFlags::AT_FDCWD.bits(),
1663             &pathname,
1664             uid,
1665             gid,
1666             AtFlags::AT_SYMLINK_NOFOLLOW,
1667         );
1668     }
1669 
1670     pub fn fchownat(
1671         dirfd: i32,
1672         pathname: *const u8,
1673         uid: usize,
1674         gid: usize,
1675         flags: i32,
1676     ) -> Result<usize, SystemError> {
1677         let pathname = user_access::check_and_clone_cstr(pathname, Some(MAX_PATHLEN))?
1678             .into_string()
1679             .map_err(|_| SystemError::EINVAL)?;
1680         let pathname = pathname.as_str().trim();
1681         let flags = AtFlags::from_bits_truncate(flags);
1682         return do_fchownat(dirfd, pathname, uid, gid, flags);
1683     }
1684 
1685     pub fn fchown(fd: i32, uid: usize, gid: usize) -> Result<usize, SystemError> {
1686         return ksys_fchown(fd, uid, gid);
1687     }
1688 
1689     /// #挂载文件系统
1690     ///
1691     /// 用于挂载文件系统,目前仅支持ramfs挂载
1692     ///
1693     /// ## 参数:
1694     ///
1695     /// - source       挂载设备(暂时不支持)
1696     /// - target       挂载目录
1697     /// - filesystemtype   文件系统
1698     /// - mountflags     挂载选项(暂未实现)
1699     /// - data        带数据挂载
1700     ///
1701     /// ## 返回值
1702     /// - Ok(0): 挂载成功
1703     /// - Err(SystemError) :挂载过程中出错
1704     pub fn mount(
1705         _source: *const u8,
1706         target: *const u8,
1707         filesystemtype: *const u8,
1708         _mountflags: usize,
1709         _data: *const c_void,
1710     ) -> Result<usize, SystemError> {
1711         let target = user_access::check_and_clone_cstr(target, Some(MAX_PATHLEN))?
1712             .into_string()
1713             .map_err(|_| SystemError::EINVAL)?;
1714 
1715         let fstype_str = user_access::check_and_clone_cstr(filesystemtype, Some(MAX_PATHLEN))?;
1716         let fstype_str = fstype_str.to_str().map_err(|_| SystemError::EINVAL)?;
1717 
1718         let fstype = producefs!(FSMAKER, fstype_str)?;
1719 
1720         Vcore::do_mount(fstype, &target)?;
1721 
1722         return Ok(0);
1723     }
1724 
1725     // 想法:可以在VFS中实现一个文件系统分发器,流程如下:
1726     // 1. 接受从上方传来的文件类型字符串
1727     // 2. 将传入值与启动时准备好的字符串数组逐个比较(probe)
1728     // 3. 直接在函数内调用构造方法并直接返回文件系统对象
1729 
1730     /// src/linux/mount.c `umount` & `umount2`
1731     ///
1732     /// [umount(2) — Linux manual page](https://www.man7.org/linux/man-pages/man2/umount.2.html)
1733     pub fn umount2(target: *const u8, flags: i32) -> Result<(), SystemError> {
1734         let target = user_access::check_and_clone_cstr(target, Some(MAX_PATHLEN))?
1735             .into_string()
1736             .map_err(|_| SystemError::EINVAL)?;
1737         Vcore::do_umount2(
1738             AtFlags::AT_FDCWD.bits(),
1739             &target,
1740             UmountFlag::from_bits(flags).ok_or(SystemError::EINVAL)?,
1741         )?;
1742         return Ok(());
1743     }
1744 
1745     pub fn sys_utimensat(
1746         dirfd: i32,
1747         pathname: *const u8,
1748         times: *const PosixTimeSpec,
1749         flags: u32,
1750     ) -> Result<usize, SystemError> {
1751         let pathname = if pathname.is_null() {
1752             None
1753         } else {
1754             let pathname = check_and_clone_cstr(pathname, Some(MAX_PATHLEN))?
1755                 .into_string()
1756                 .map_err(|_| SystemError::EINVAL)?;
1757             Some(pathname)
1758         };
1759         let flags = UtimensFlags::from_bits(flags).ok_or(SystemError::EINVAL)?;
1760         let times = if times.is_null() {
1761             None
1762         } else {
1763             let times_reader = UserBufferReader::new(times, size_of::<PosixTimeSpec>() * 2, true)?;
1764             let times = times_reader.read_from_user::<PosixTimeSpec>(0)?;
1765             Some([times[0], times[1]])
1766         };
1767         do_utimensat(dirfd, pathname, times, flags)
1768     }
1769 
1770     pub fn sys_utimes(
1771         pathname: *const u8,
1772         times: *const PosixTimeval,
1773     ) -> Result<usize, SystemError> {
1774         let pathname = check_and_clone_cstr(pathname, Some(MAX_PATHLEN))?
1775             .into_string()
1776             .map_err(|_| SystemError::EINVAL)?;
1777         let times = if times.is_null() {
1778             None
1779         } else {
1780             let times_reader = UserBufferReader::new(times, size_of::<PosixTimeval>() * 2, true)?;
1781             let times = times_reader.read_from_user::<PosixTimeval>(0)?;
1782             Some([times[0], times[1]])
1783         };
1784         do_utimes(&pathname, times)
1785     }
1786 }
1787 
1788 #[repr(C)]
1789 #[derive(Debug, Clone, Copy)]
1790 pub struct IoVec {
1791     /// 缓冲区的起始地址
1792     pub iov_base: *mut u8,
1793     /// 缓冲区的长度
1794     pub iov_len: usize,
1795 }
1796 
1797 /// 用于存储多个来自用户空间的IoVec
1798 ///
1799 /// 由于目前内核中的文件系统还不支持分散读写,所以暂时只支持将用户空间的IoVec聚合成一个缓冲区,然后进行操作。
1800 /// TODO:支持分散读写
1801 #[derive(Debug)]
1802 pub struct IoVecs(Vec<&'static mut [u8]>);
1803 
1804 impl IoVecs {
1805     /// 从用户空间的IoVec中构造IoVecs
1806     ///
1807     /// @param iov 用户空间的IoVec
1808     /// @param iovcnt 用户空间的IoVec的数量
1809     /// @param readv 是否为readv系统调用
1810     ///
1811     /// @return 构造成功返回IoVecs,否则返回错误码
1812     pub unsafe fn from_user(
1813         iov: *const IoVec,
1814         iovcnt: usize,
1815         _readv: bool,
1816     ) -> Result<Self, SystemError> {
1817         // 检查iov指针所在空间是否合法
1818         verify_area(
1819             VirtAddr::new(iov as usize),
1820             iovcnt * core::mem::size_of::<IoVec>(),
1821         )
1822         .map_err(|_| SystemError::EFAULT)?;
1823 
1824         // 将用户空间的IoVec转换为引用(注意:这里的引用是静态的,因为用户空间的IoVec不会被释放)
1825         let iovs: &[IoVec] = core::slice::from_raw_parts(iov, iovcnt);
1826 
1827         let mut slices: Vec<&mut [u8]> = Vec::with_capacity(iovs.len());
1828 
1829         for iov in iovs.iter() {
1830             if iov.iov_len == 0 {
1831                 continue;
1832             }
1833 
1834             verify_area(
1835                 VirtAddr::new(iov.iov_base as usize),
1836                 iovcnt * core::mem::size_of::<IoVec>(),
1837             )
1838             .map_err(|_| SystemError::EFAULT)?;
1839 
1840             slices.push(core::slice::from_raw_parts_mut(iov.iov_base, iov.iov_len));
1841         }
1842 
1843         return Ok(Self(slices));
1844     }
1845 
1846     /// @brief 将IoVecs中的数据聚合到一个缓冲区中
1847     ///
1848     /// @return 返回聚合后的缓冲区
1849     pub fn gather(&self) -> Vec<u8> {
1850         let mut buf = Vec::new();
1851         for slice in self.0.iter() {
1852             buf.extend_from_slice(slice);
1853         }
1854         return buf;
1855     }
1856 
1857     /// @brief 将给定的数据分散写入到IoVecs中
1858     pub fn scatter(&mut self, data: &[u8]) {
1859         let mut data: &[u8] = data;
1860         for slice in self.0.iter_mut() {
1861             let len = core::cmp::min(slice.len(), data.len());
1862             if len == 0 {
1863                 continue;
1864             }
1865 
1866             slice[..len].copy_from_slice(&data[..len]);
1867             data = &data[len..];
1868         }
1869     }
1870 
1871     /// @brief 创建与IoVecs等长的缓冲区
1872     ///
1873     /// @param set_len 是否设置返回的Vec的len。
1874     /// 如果为true,则返回的Vec的len为所有IoVec的长度之和;
1875     /// 否则返回的Vec的len为0,capacity为所有IoVec的长度之和.
1876     ///
1877     /// @return 返回创建的缓冲区
1878     pub fn new_buf(&self, set_len: bool) -> Vec<u8> {
1879         let total_len: usize = self.0.iter().map(|slice| slice.len()).sum();
1880         let mut buf: Vec<u8> = Vec::with_capacity(total_len);
1881 
1882         if set_len {
1883             buf.resize(total_len, 0);
1884         }
1885         return buf;
1886     }
1887 }
1888