소스 검색

perf: replace the annoyed ext4 crate with a new choice (called another ext4 crate

Heinz 6 달 전
부모
커밋
f6c26c956c
3개의 변경된 파일78개의 추가작업 그리고 59개의 파일을 삭제
  1. 20 21
      Cargo.lock
  2. 1 1
      Cargo.toml
  3. 57 37
      src/fs/ext4.rs

+ 20 - 21
Cargo.lock

@@ -19,15 +19,24 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c1c330e503236d0b06386ae6cc42a513ef1ccc23c52b603c1b52f018564faf44"
 
+[[package]]
+name = "another_ext4"
+version = "0.1.0"
+source = "git+https://github.com/SMS-Derfflinger/another_ext4?branch=main#ed6d91718db721eb4a744483c289cc44a6f34bf4"
+dependencies = [
+ "bitflags",
+ "log",
+]
+
 [[package]]
 name = "atomic_unique_refcell"
 version = "0.1.0"
 
 [[package]]
 name = "autocfg"
-version = "1.4.0"
+version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
+checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
 
 [[package]]
 name = "bit_field"
@@ -51,9 +60,9 @@ dependencies = [
 
 [[package]]
 name = "cfg-if"
-version = "1.0.0"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
 
 [[package]]
 name = "critical-section"
@@ -133,6 +142,7 @@ version = "0.1.0"
 dependencies = [
  "acpi",
  "align_ext",
+ "another_ext4",
  "atomic_unique_refcell",
  "bitflags",
  "buddy_allocator",
@@ -144,7 +154,6 @@ dependencies = [
  "eonix_preempt",
  "eonix_runtime",
  "eonix_sync",
- "ext4_rs",
  "intrusive-collections",
  "intrusive_list",
  "itertools",
@@ -247,16 +256,6 @@ dependencies = [
  "intrusive-collections",
 ]
 
-[[package]]
-name = "ext4_rs"
-version = "1.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a1a97344bde15b0ace15e265dab27228d4bdc37a0bfa8548c5645d7cfa6a144"
-dependencies = [
- "bitflags",
- "log",
-]
-
 [[package]]
 name = "fdt"
 version = "0.1.5"
@@ -392,9 +391,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.101"
+version = "2.0.104"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
+checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -459,18 +458,18 @@ checksum = "2fe21bcc34ca7fe6dd56cc2cb1261ea59d6b93620215aefb5ea6032265527784"
 
 [[package]]
 name = "zerocopy"
-version = "0.8.25"
+version = "0.8.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb"
+checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f"
 dependencies = [
  "zerocopy-derive",
 ]
 
 [[package]]
 name = "zerocopy-derive"
-version = "0.8.25"
+version = "0.8.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef"
+checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181"
 dependencies = [
  "proc-macro2",
  "quote",

+ 1 - 1
Cargo.toml

@@ -30,7 +30,7 @@ itertools = { version = "0.13.0", default-features = false }
 acpi = "5.2.0"
 align_ext = "0.1.0"
 xmas-elf = "0.10.0"
-ext4_rs = "1.3.2"
+another_ext4 = { git = "https://github.com/SMS-Derfflinger/another_ext4", branch = "main" }
 
 [target.'cfg(target_arch = "riscv64")'.dependencies]
 virtio-drivers = { version = "0.11.0" }

+ 57 - 37
src/fs/ext4.rs

@@ -22,10 +22,11 @@ use alloc::{
     collections::btree_map::{BTreeMap, Entry},
     sync::Arc,
 };
+use another_ext4::{
+    Block, BlockDevice as Ext4BlockDeviceTrait, Ext4, FileType, InodeMode, PBlockId,
+};
 use eonix_runtime::task::Task;
 use eonix_sync::RwLock;
-use ext4_rs::{BlockDevice as Ext4BlockDeviceTrait, Ext4Error};
-use ext4_rs::{Errno, Ext4};
 
 pub struct Ext4BlockDevice {
     device: Arc<BlockDevice>,
@@ -38,19 +39,22 @@ impl Ext4BlockDevice {
 }
 
 impl Ext4BlockDeviceTrait for Ext4BlockDevice {
-    fn read_offset(&self, offset: usize) -> Vec<u8> {
-        let mut buffer = vec![0u8; 4096];
+    fn read_block(&self, block_id: PBlockId) -> Block {
+        let mut buffer = [0u8; 4096];
         let mut byte_buffer = ByteBuffer::new(buffer.as_mut_slice());
 
         let _ = self
             .device
-            .read_some(offset, &mut byte_buffer)
+            .read_some((block_id as usize) * 4096, &mut byte_buffer)
             .expect("Failed to read from block device");
 
-        buffer
+        Block {
+            id: block_id,
+            data: buffer,
+        }
     }
 
-    fn write_offset(&self, _offset: usize, _data: &[u8]) {
+    fn write_block(&self, block: &another_ext4::Block) {
         todo!()
     }
 }
@@ -115,7 +119,7 @@ impl Ext4Fs {
 impl Ext4Fs {
     pub fn create(device: Arc<BlockDevice>) -> KResult<(Arc<Self>, Arc<dyn Inode>)> {
         let ext4_device = Ext4BlockDevice::new(device.clone());
-        let ext4 = Ext4::open(Arc::new(ext4_device));
+        let ext4 = Ext4::load(Arc::new(ext4_device)).unwrap();
 
         let ext4fs = Arc::new(Self {
             inner: ext4,
@@ -125,28 +129,28 @@ impl Ext4Fs {
 
         let root_inode = {
             let mut icache = Task::block_on(ext4fs.icache.write());
-            let root_inode = ext4fs.inner.get_inode_ref(2);
+            let root_inode = ext4fs.inner.read_root_inode();
 
             ext4fs.get_or_insert(
                 &mut icache,
                 InodeData {
-                    ino: root_inode.inode_num as Ino,
+                    ino: root_inode.id as Ino,
                     size: AtomicU64::new(root_inode.inode.size()),
-                    nlink: AtomicNlink::new(root_inode.inode.links_count() as _),
-                    uid: AtomicU32::new(root_inode.inode.uid() as _),
-                    gid: AtomicU32::new(root_inode.inode.gid() as _),
-                    mode: AtomicU32::new(root_inode.inode.mode() as _),
+                    nlink: AtomicNlink::new(root_inode.inode.link_count() as u64),
+                    uid: AtomicU32::new(root_inode.inode.uid()),
+                    gid: AtomicU32::new(root_inode.inode.gid()),
+                    mode: AtomicU32::new(root_inode.inode.mode().bits() as u32),
                     atime: Spin::new(Instant::new(
                         root_inode.inode.atime() as _,
-                        root_inode.inode.i_atime_extra() as _,
+                        root_inode.inode.atime_extra() as _,
                     )),
                     ctime: Spin::new(Instant::new(
                         root_inode.inode.ctime() as _,
-                        root_inode.inode.i_ctime_extra() as _,
+                        root_inode.inode.ctime_extra() as _,
                     )),
                     mtime: Spin::new(Instant::new(
                         root_inode.inode.mtime() as _,
-                        root_inode.inode.i_mtime_extra() as _,
+                        root_inode.inode.mtime_extra() as _,
                     )),
                     rwsem: RwLock::new(()),
                     vfs: Arc::downgrade(&ext4fs) as _,
@@ -187,12 +191,12 @@ impl Inode for FileInode {
         let ext4fs = vfs.as_any().downcast_ref::<Ext4Fs>().unwrap();
 
         let mut temp_buf = vec![0u8; buffer.total()];
-        match ext4fs.inner.read_at(self.ino as u32, offset, &mut temp_buf) {
+        match ext4fs.inner.read(self.ino as u32, offset, &mut temp_buf) {
             Ok(bytes_read) => {
                 let _ = buffer.fill(&temp_buf[..bytes_read])?;
                 Ok(buffer.wrote())
             }
-            Err(e) => Err(e.error() as u32),
+            Err(e) => Err(e.code() as u32),
         }
     }
 }
@@ -204,13 +208,14 @@ impl Inode for DirInode {
 
         let name = dentry.get_name();
         let name = String::from_utf8_lossy(&name);
-        let lookup_result = ext4fs.inner.fuse_lookup(self.ino, &name);
+        let lookup_result = ext4fs.inner.lookup(self.ino as u32, &name);
 
-        const EXT4_ERROR_ENOENT: Ext4Error = Ext4Error::new(Errno::ENOENT);
+        // TODO: wtf
+        //const EXT4_ERROR_ENOENT: Ext4Error_ = Ext4Error_::new(ErrCode::ENOENT);
         let attr = match lookup_result {
-            Ok(attr) => attr,
-            Err(EXT4_ERROR_ENOENT) => return Ok(None),
-            Err(error) => return Err(error.error() as u32),
+            Ok(inode_id) => ext4fs.inner.getattr(inode_id).unwrap(),
+            //Err(EXT4_ERROR_ENOENT) => return Ok(None),
+            Err(error) => return Err(error.code() as u32),
         };
 
         // Fast path: if the inode is already in the cache, return it.
@@ -219,9 +224,19 @@ impl Inode for DirInode {
             return Ok(Some(inode));
         }
 
-        let extra_perm = attr.perm.bits() as u32 & 0o7000;
-        let perm = attr.perm.bits() as u32 & 0o0700;
-        let real_perm = extra_perm | perm | perm >> 3 | perm >> 6;
+        let file_type_bits = match attr.ftype {
+            FileType::RegularFile => InodeMode::FILE.bits(),
+            FileType::Directory => InodeMode::DIRECTORY.bits(),
+            FileType::CharacterDev => InodeMode::CHARDEV.bits(),
+            FileType::BlockDev => InodeMode::BLOCKDEV.bits(),
+            FileType::Fifo => InodeMode::FIFO.bits(),
+            FileType::Socket => InodeMode::SOCKET.bits(),
+            FileType::SymLink => InodeMode::SOFTLINK.bits(),
+            FileType::Unknown => 0,
+        };
+
+        let perm_bits = attr.perm.bits() & InodeMode::PERM_MASK.bits();
+        let mode = file_type_bits | perm_bits;
 
         // Create a new inode based on the attributes.
         let mut icache = Task::block_on(ext4fs.icache.write());
@@ -230,10 +245,10 @@ impl Inode for DirInode {
             InodeData {
                 ino: attr.ino as Ino,
                 size: AtomicU64::new(attr.size),
-                nlink: AtomicNlink::new(attr.nlink as _),
+                nlink: AtomicNlink::new(attr.links as _),
                 uid: AtomicU32::new(attr.uid),
                 gid: AtomicU32::new(attr.gid),
-                mode: AtomicU32::new(attr.kind.bits() as u32 | real_perm),
+                mode: AtomicU32::new(mode as u32),
                 atime: Spin::new(Instant::new(attr.atime as _, 0)),
                 ctime: Spin::new(Instant::new(attr.ctime as _, 0)),
                 mtime: Spin::new(Instant::new(attr.mtime as _, 0)),
@@ -255,18 +270,23 @@ impl Inode for DirInode {
 
         let entries = ext4fs
             .inner
-            .fuse_readdir(self.ino as u64, 0, offset as i64)
-            .map_err(|err| err.error() as u32)?;
-        let mut current_offset = 0;
+            .listdir(self.ino as u32)
+            .map_err(|err| err.code() as u32)?;
 
-        for entry in entries {
-            let name_len = entry.name_len as usize;
-            let name = &entry.name[..name_len];
+        let entries_to_process = if offset < entries.len() {
+            &entries[offset..]
+        } else {
+            &entries[0..0]
+        };
+        let mut current_offset = 0;
+        for entry in entries_to_process {
+            let name_string = entry.name();
+            let name = name_string.as_bytes();
+            let inode = entry.inode() as Ino;
 
-            if callback(name, entry.inode as Ino)?.is_break() {
+            if callback(name, inode)?.is_break() {
                 break;
             }
-
             current_offset += 1;
         }
         Ok(current_offset)