Parcourir la source

修复readdir以及读磁盘时buf传错问题 (#422)

* 修复readdir以及读磁盘时buf传错问题

* fix potential memory problem

---------

Co-authored-by: longjin <longjin@DragonOS.org>
GnoCiYeH il y a 1 an
Parent
commit
1effcfe519

+ 2 - 1
kernel/src/driver/base/block/block_device.rs

@@ -292,9 +292,10 @@ pub trait BlockDevice: Device {
             let count: usize = (range.lba_end - range.lba_start).try_into().unwrap();
             let full = multi && range.is_multi() || !multi && range.is_full();
 
+            // 读取整个block作为有效数据
             if full {
                 // 调用 BlockDevice::read_at() 直接把引用传进去,不是把整个数组move进去
-                self.read_at(range.lba_start, count, buf)?;
+                self.read_at(range.lba_start, count, buf_slice)?;
             } else {
                 // 判断块的长度不能超过最大值
                 if self.blk_size_log2() > BLK_SIZE_LOG2_LIMIT {

+ 2 - 0
kernel/src/filesystem/fat/fs.rs

@@ -1716,6 +1716,8 @@ impl IndexNode for LockedFATInode {
         } else if mode.contains(ModeType::S_IFCHR) {
             nod.0.lock().metadata.file_type = FileType::CharDevice;
             unimplemented!()
+        } else {
+            return Err(SystemError::EINVAL);
         }
 
         inode

+ 13 - 7
kernel/src/filesystem/vfs/file.rs

@@ -269,15 +269,18 @@ impl File {
 
         // 如果偏移量为0
         if self.offset == 0 {
+            // 通过list更新readdir_subdirs_name
             self.readdir_subdirs_name = inode.list()?;
             self.readdir_subdirs_name.sort();
         }
         // kdebug!("sub_entries={sub_entries:?}");
-        if self.readdir_subdirs_name.is_empty() {
+
+        // 已经读到末尾
+        if self.offset == self.readdir_subdirs_name.len() {
             self.offset = 0;
             return Ok(0);
         }
-        let name: String = self.readdir_subdirs_name.remove(0);
+        let name = &self.readdir_subdirs_name[self.offset];
         let sub_inode: Arc<dyn IndexNode> = match inode.find(&name) {
             Ok(i) => i,
             Err(e) => {
@@ -290,17 +293,20 @@ impl File {
 
         let name_bytes: &[u8] = name.as_bytes();
 
-        self.offset += 1;
-        dirent.d_ino = sub_inode.metadata().unwrap().inode_id.into() as u64;
-        dirent.d_type = sub_inode.metadata().unwrap().file_type.get_file_type_num() as u8;
         // 根据posix的规定,dirent中的d_name是一个不定长的数组,因此需要unsafe来拷贝数据
         unsafe {
             let ptr = &mut dirent.d_name as *mut u8;
+
             let buf: &mut [u8] =
-                ::core::slice::from_raw_parts_mut::<'static, u8>(ptr, name_bytes.len());
-            buf.copy_from_slice(name_bytes);
+                ::core::slice::from_raw_parts_mut::<'static, u8>(ptr, name_bytes.len() + 1);
+            buf[0..name_bytes.len()].copy_from_slice(name_bytes);
+            buf[name_bytes.len()] = 0;
         }
 
+        self.offset += 1;
+        dirent.d_ino = sub_inode.metadata().unwrap().inode_id.into() as u64;
+        dirent.d_type = sub_inode.metadata().unwrap().file_type.get_file_type_num() as u8;
+
         // 计算dirent结构体的大小
         let size = (name_bytes.len() + ::core::mem::size_of::<Dirent>()
             - ::core::mem::size_of_val(&dirent.d_name)) as u64;

+ 1 - 1
user/dadk/config/dragon_reach-0.1.0.dadk

@@ -6,7 +6,7 @@
     "BuildFromSource": {
       "Git": {
         "url" : "https://git.mirrors.dragonos.org/DragonOS-Community/DragonReach.git",
-        "revision": "67e3e34cb5"
+        "revision": "d70ac4ed6b"
       }
     }
   },

+ 1 - 2
user/libs/libc/src/Makefile

@@ -35,5 +35,4 @@ clean:
 libc: $(libc_objs) $(libc_sub_dirs) libc_rust
 
 libc_rust:
-	rustup default nightly
-	cargo +nightly build --release --target ./arch/x86_64/x86_64-unknown-none.json
+	cargo +nightly-2023-01-21 build --release --target ./arch/x86_64/x86_64-unknown-none.json