Răsfoiți Sursa

refactor: inode read and write

liujingx 1 an în urmă
părinte
comite
bac242ad43
6 a modificat fișierele cu 76 adăugiri și 51 ștergeri
  1. 2 2
      src/ext4/alloc.rs
  2. 5 5
      src/ext4/file.rs
  3. 9 0
      src/ext4/journal.rs
  4. 10 33
      src/ext4/mod.rs
  5. 1 1
      src/ext4/utils.rs
  6. 49 10
      src/ext4_defs/inode.rs

+ 2 - 2
src/ext4/alloc.rs

@@ -139,7 +139,7 @@ impl Ext4 {
         inode_ref
             .inode
             .set_blocks_count(inode_blocks as u32);
-        self.write_back_inode(inode_ref);
+        self.write_back_inode_with_csum(inode_ref);
 
         /* Update block group free blocks count */
         let mut fb_cnt = bg.get_free_blocks_count();
@@ -169,7 +169,7 @@ impl Ext4 {
             .inode
             .set_size(inode_size + BLOCK_SIZE as u64);
     
-        self.write_back_inode(inode_ref);
+        self.write_back_inode_with_csum(inode_ref);
     
         // let mut inode_ref = Ext4InodeRef::get_inode_ref(inode_ref.fs().self_ref.clone(), inode_ref.inode_num);
     

+ 5 - 5
src/ext4/file.rs

@@ -90,9 +90,9 @@ impl Ext4 {
                     return_errno_with_message!(Errnum::ELINKFIAL, "link fail");
                 }
 
-                self.write_back_inode(&mut search_parent);
-                self.write_back_inode(&mut child_inode_ref);
-                self.write_back_inode(parent_inode);
+                self.write_back_inode_with_csum(&mut search_parent);
+                self.write_back_inode_with_csum(&mut child_inode_ref);
+                self.write_back_inode_with_csum(parent_inode);
 
                 continue;
             }
@@ -219,10 +219,10 @@ impl Ext4 {
                 .write_offset(offset, &data[idx..(idx + BLOCK_SIZE as usize)]);
         }
         // inode_ref.inner.inode.size = fblock_count as u32 * BLOCK_SIZE as u32;
-        self.write_back_inode(&mut inode_ref);
+        self.write_back_inode_with_csum(&mut inode_ref);
         // let mut inode_ref = Ext4InodeRef::get_inode_ref(self.self_ref.clone(), ext4_file.inode);
         let mut root_inode_ref = self.get_root_inode_ref();
-        self.write_back_inode(&mut root_inode_ref);
+        self.write_back_inode_with_csum(&mut root_inode_ref);
     }
 
     pub fn ext4_file_remove(&self, _path: &str) -> Result<usize> {

+ 9 - 0
src/ext4/journal.rs

@@ -0,0 +1,9 @@
+use super::Ext4;
+
+impl Ext4 {
+    // start transaction
+    pub fn ext4_trans_start(&self) {}
+
+    // stop transaction
+    pub fn ext4_trans_abort(&self) {}
+}

+ 10 - 33
src/ext4/mod.rs

@@ -6,6 +6,7 @@ mod alloc;
 mod dir;
 mod extent;
 mod file;
+mod journal;
 mod link;
 mod utils;
 
@@ -60,52 +61,28 @@ impl Ext4 {
         }
     }
 
-    // start transaction
-    pub fn ext4_trans_start(&self) {}
-
-    // stop transaction
-    pub fn ext4_trans_abort(&self) {}
-
+    /// Read an inode from block device, return an`Ext4InodeRef` that combines
+    /// the inode and its id.
     fn get_inode_ref(&self, inode_id: u32) -> Ext4InodeRef {
-        let super_block = self.super_block;
-
-        let inodes_per_group = super_block.inodes_per_group();
-        let inode_size = super_block.inode_size() as u64;
-        let group = (inode_id - 1) / inodes_per_group;
-        let index = (inode_id - 1) % inodes_per_group;
-        let group = self.block_groups[group as usize];
-        let inode_table_blk_num = group.inode_table_blk_num();
-        let offset =
-            inode_table_blk_num as usize * BLOCK_SIZE + index as usize * inode_size as usize;
-
-        let data = self.block_device.read_offset(offset);
-        let inode_data = &data[..core::mem::size_of::<Ext4Inode>()];
-        let inode = Ext4Inode::try_from(inode_data).unwrap();
-
-        Ext4InodeRef::new(inode_id, inode)
+        Ext4InodeRef::read_from_disk(self.block_device.clone(), &self.super_block, inode_id)
     }
 
+    /// Read the root inode from block device
     fn get_root_inode_ref(&self) -> Ext4InodeRef {
         self.get_inode_ref(EXT4_ROOT_INO)
     }
 
-    fn write_back_inode(&self, inode_ref: &mut Ext4InodeRef) {
-        let block_device = self.block_device.clone();
-        let super_block = self.super_block.clone();
-        let inode_id = inode_ref.inode_id;
+    /// Write back an inode to block device with checksum
+    fn write_back_inode_with_csum(&self, inode_ref: &mut Ext4InodeRef) {
         inode_ref
-            .inode
-            .sync_to_disk_with_csum(block_device, &super_block, inode_id)
+            .sync_to_disk_with_csum(self.block_device.clone(), &self.super_block)
             .unwrap()
     }
 
+    /// Write back an inode to block device without checksum
     fn write_back_inode_without_csum(&self, inode_ref: &mut Ext4InodeRef) {
-        let block_device = self.block_device.clone();
-        let super_block = self.super_block.clone();
-        let inode_id = inode_ref.inode_id;
         inode_ref
-            .inode
-            .sync_to_disk(block_device, &super_block, inode_id)
+            .sync_to_disk_without_csum(self.block_device.clone(), &self.super_block)
             .unwrap()
     }
 }

+ 1 - 1
src/ext4/utils.rs

@@ -22,7 +22,7 @@ pub fn ext4_bmap_bit_set(bmap: &mut [u8], bit: u32) {
     bmap[(bit >> 3) as usize] |= 1 << (bit & 7);
 }
 
-// 查找位图中第一个为0的位
+/// 查找位图中第一个为0的位
 pub fn ext4_bmap_bit_find_clr(bmap: &[u8], sbit: u32, ebit: u32, bit_id: &mut u32) -> bool {
     let mut i: u32;
     let mut bcnt = ebit - sbit;

+ 49 - 10
src/ext4_defs/inode.rs

@@ -180,7 +180,7 @@ impl Ext4Inode {
 
     /// Find the position of an inode in the block device.
     ///
-    /// Each block group contains sb->s_inodes_per_group inodes.
+    /// Each block group contains `sb.inodes_per_group` inodes.
     /// Because inode 0 is defined not to exist, this formula can
     /// be used to find the block group that an inode lives in:
     /// `bg = (inode_id - 1) / sb.inodes_per_group`.
@@ -189,8 +189,7 @@ impl Ext4Inode {
     /// inode table at `index = (inode_id - 1) % sb.inodes_per_group`.
     /// To get the byte address within the inode table, use
     /// `offset = index * sb.inode_size`.
-    pub fn get_inode_disk_pos(
-        &self,
+    fn inode_disk_pos(
         super_block: &Ext4Superblock,
         block_device: Arc<dyn BlockDevice>,
         inode_id: u32,
@@ -204,6 +203,17 @@ impl Ext4Inode {
         bg.inode_table_blk_num() as usize * BLOCK_SIZE + (index * inode_size as u32) as usize
     }
 
+    fn read_from_disk(
+        super_block: &Ext4Superblock,
+        block_device: Arc<dyn BlockDevice>,
+        inode_id: u32,
+    ) -> Self {
+        let pos = Ext4Inode::inode_disk_pos(super_block, block_device.clone(), inode_id);
+        let data = block_device.read_offset(pos);
+        let inode_data = &data[..core::mem::size_of::<Ext4Inode>()];
+        Ext4Inode::try_from(inode_data).unwrap()
+    }
+
     fn copy_to_byte_slice(&self, slice: &mut [u8]) {
         unsafe {
             let inode_ptr = self as *const Ext4Inode as *const u8;
@@ -212,7 +222,7 @@ impl Ext4Inode {
         }
     }
 
-    pub fn calc_checksum(&mut self, inode_id: u32, super_block: &Ext4Superblock) -> u32 {
+    fn calc_checksum(&mut self, inode_id: u32, super_block: &Ext4Superblock) -> u32 {
         let inode_size = super_block.inode_size();
 
         let ino_index = inode_id as u32;
@@ -245,7 +255,7 @@ impl Ext4Inode {
         checksum
     }
 
-    pub fn set_checksum(&mut self, super_block: &Ext4Superblock, inode_id: u32) {
+    fn set_checksum(&mut self, super_block: &Ext4Superblock, inode_id: u32) {
         let inode_size = super_block.inode_size();
         let checksum = self.calc_checksum(inode_id, super_block);
 
@@ -255,13 +265,13 @@ impl Ext4Inode {
         }
     }
 
-    pub fn sync_to_disk(
+    fn sync_to_disk_without_csum(
         &self,
         block_device: Arc<dyn BlockDevice>,
         super_block: &Ext4Superblock,
         inode_id: u32,
     ) -> Result<()> {
-        let disk_pos = self.get_inode_disk_pos(super_block, block_device.clone(), inode_id);
+        let disk_pos = Self::inode_disk_pos(super_block, block_device.clone(), inode_id);
         let data = unsafe {
             core::slice::from_raw_parts(self as *const _ as *const u8, size_of::<Ext4Inode>())
         };
@@ -270,18 +280,18 @@ impl Ext4Inode {
         Ok(())
     }
 
-    pub fn sync_to_disk_with_csum(
+    fn sync_to_disk_with_csum(
         &mut self,
         block_device: Arc<dyn BlockDevice>,
         super_block: &Ext4Superblock,
         inode_id: u32,
     ) -> Result<()> {
         self.set_checksum(super_block, inode_id);
-        self.sync_to_disk(block_device, super_block, inode_id)
+        self.sync_to_disk_without_csum(block_device, super_block, inode_id)
     }
 }
 
-/// A reference to an inode in the ext4 filesystem.
+/// A combination of an `Ext4Inode` and its id
 #[derive(Default)]
 pub struct Ext4InodeRef {
     pub inode_id: u32,
@@ -292,4 +302,33 @@ impl Ext4InodeRef {
     pub fn new(inode_id: u32, inode: Ext4Inode) -> Self {
         Self { inode_id, inode }
     }
+
+    pub fn read_from_disk(
+        block_device: Arc<dyn BlockDevice>,
+        super_block: &Ext4Superblock,
+        inode_id: u32,
+    ) -> Self {
+        Self::new(
+            inode_id,
+            Ext4Inode::read_from_disk(super_block, block_device, inode_id),
+        )
+    }
+
+    pub fn sync_to_disk_without_csum(
+        &self,
+        block_device: Arc<dyn BlockDevice>,
+        super_block: &Ext4Superblock,
+    ) -> Result<()> {
+        self.inode
+            .sync_to_disk_without_csum(block_device, super_block, self.inode_id)
+    }
+
+    pub fn sync_to_disk_with_csum(
+        &mut self,
+        block_device: Arc<dyn BlockDevice>,
+        super_block: &Ext4Superblock,
+    ) -> Result<()> {
+        self.inode
+            .sync_to_disk_with_csum(block_device, super_block, self.inode_id)
+    }
 }