11//! File and filesystem-related syscalls
22use crate :: fs:: { open_file, OpenFlags , Stat } ;
3- use crate :: mm:: { translated_byte_buffer, translated_str, UserBuffer } ;
3+ use crate :: mm:: { translated_byte_buffer, translated_str, UserBuffer , translated_refmut } ;
44use crate :: task:: { current_task, current_user_token} ;
5-
5+ use crate :: fs:: inode:: ROOT_INODE ;
6+ use crate :: fs:: OSInode ;
67
78pub fn sys_write ( fd : usize , buf : * const u8 , len : usize ) -> isize {
89 trace ! ( "kernel:pid[{}] sys_write" , current_task( ) . unwrap( ) . pid. 0 ) ;
@@ -51,6 +52,7 @@ pub fn sys_open(path: *const u8, flags: u32) -> isize {
5152 trace ! ( "kernel:pid[{}] sys_open" , current_task( ) . unwrap( ) . pid. 0 ) ;
5253 let task = current_task ( ) . unwrap ( ) ;
5354 let token = current_user_token ( ) ;
55+ // 通过页表将另一个地址空间中的C风格字符串(以\0结尾的字节数组)转换为Rust的String
5456 let path = translated_str ( token, path) ;
5557 if let Some ( inode) = open_file ( path. as_str ( ) , OpenFlags :: from_bits ( flags) . unwrap ( ) ) {
5658 let mut inner = task. inner_exclusive_access ( ) ;
@@ -77,28 +79,85 @@ pub fn sys_close(fd: usize) -> isize {
7779}
7880
7981/// YOUR JOB: Implement fstat.
80- pub fn sys_fstat ( _fd : usize , _st : * mut Stat ) -> isize {
82+ pub fn sys_fstat ( fd : usize , st : * mut Stat ) -> isize {
8183 trace ! (
8284 "kernel:pid[{}] sys_fstat NOT IMPLEMENTED" ,
8385 current_task( ) . unwrap( ) . pid. 0
8486 ) ;
87+ let task = current_task ( ) . unwrap ( ) ;
88+ let token = current_user_token ( ) ;
89+
90+ if let Some ( file) = task. get_file ( fd) {
91+ // 只处理 OSInode(普通文件)
92+ if let Some ( os_inode) = file. as_any ( ) . downcast_ref :: < OSInode > ( ) {
93+ let stat = os_inode. get_stat ( ) ;
94+ let st_buf = translated_refmut ( token, st) ;
95+ * st_buf = stat;
96+ return 0 ;
97+ }
98+ // 对于其他类型的文件(Stdin/Stdout),暂时返回错误
99+ // 等普通文件工作后再扩展
100+ else {
101+ return -1 ;
102+ }
103+ }
104+
85105 -1
86106}
87107
88108/// YOUR JOB: Implement linkat.
89- pub fn sys_linkat ( _old_name : * const u8 , _new_name : * const u8 ) -> isize {
109+ pub fn sys_linkat ( old_name : * const u8 , new_name : * const u8 ) -> isize {
90110 trace ! (
91111 "kernel:pid[{}] sys_linkat NOT IMPLEMENTED" ,
92112 current_task( ) . unwrap( ) . pid. 0
93113 ) ;
94- -1
114+
115+ let token = current_user_token ( ) ;
116+ let old_path = translated_str ( token, old_name) ;
117+ let new_path = translated_str ( token, new_name) ;
118+
119+ // 检查路径是否相同
120+ if old_path == new_path {
121+ return -1 ;
122+ }
123+
124+ // 查找原文件
125+ let old_inode = match ROOT_INODE . find ( & old_path) {
126+ Some ( inode) => inode,
127+ None => return -1 , // 原文件不存在
128+ } ;
129+
130+ // 检查新文件是否已存在
131+ if ROOT_INODE . find ( & new_path) . is_some ( ) {
132+ return -1 ; // 新文件已存在
133+ }
134+ // 创建硬链接
135+ match ROOT_INODE . create_hardlink ( & new_path, & old_inode) {
136+ Some ( _) => {
137+ 0
138+ } ,
139+ None => {
140+ -1
141+ }
142+ }
95143}
96144
97145/// YOUR JOB: Implement unlinkat.
98- pub fn sys_unlinkat ( _name : * const u8 ) -> isize {
146+ pub fn sys_unlinkat ( name : * const u8 ) -> isize {
99147 trace ! (
100148 "kernel:pid[{}] sys_unlinkat NOT IMPLEMENTED" ,
101149 current_task( ) . unwrap( ) . pid. 0
102150 ) ;
103- -1
151+
152+
153+ let token = current_user_token ( ) ;
154+ let path = translated_str ( token, name) ;
155+
156+ // 检查路径是否为空
157+ if path. is_empty ( ) {
158+ return -1 ;
159+ }
160+
161+ // 直接调用 ROOT_INODE 的 unlink 方法
162+ ROOT_INODE . unlink ( & path)
104163}
0 commit comments