Bläddra i källkod

refactor: read write block

liujingx 11 månader sedan
förälder
incheckning
d187fb27e2

+ 0 - 1
src/constants.rs

@@ -1,7 +1,6 @@
 #![allow(unused)]
 
 use crate::prelude::*;
-use bitflags::bitflags;
 
 pub const EXT4_INODE_FLAG_EXTENTS: u32 = 0x00080000; /* Inode uses extents */
 pub const EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE: u16 = 32;

+ 13 - 13
src/ext4/alloc.rs

@@ -62,7 +62,7 @@ impl Ext4 {
             // Deallocate the block
             self.dealloc_block(&mut inode, pblock)?;
             // Clear the block content
-            Block::new(pblock, [0; BLOCK_SIZE]).sync_to_disk(self.block_device.clone());
+            self.write_block(&Block::new(pblock, [0; BLOCK_SIZE]));
         }
         // Deallocate the inode
         self.dealloc_inode(&inode)?;
@@ -103,7 +103,7 @@ impl Ext4 {
 
         // Load block bitmap
         let bitmap_block_id = bg.desc.block_bitmap_block(&self.super_block);
-        let mut bitmap_block = self.block_device.read_block(bitmap_block_id);
+        let mut bitmap_block = self.read_block(bitmap_block_id);
         let mut bitmap = Bitmap::new(&mut bitmap_block.data);
 
         // Find the first free block
@@ -114,12 +114,12 @@ impl Ext4 {
 
         // Set block group checksum
         bg.desc.set_block_bitmap_csum(&self.super_block, &bitmap);
-        self.block_device.write_block(&bitmap_block);
+        self.write_block(&bitmap_block);
 
         // Update superblock free blocks count
         let free_blocks = self.super_block.free_blocks_count() - 1;
         self.super_block.set_free_blocks_count(free_blocks);
-        self.super_block.sync_to_disk(self.block_device.clone());
+        self.write_super_block();
 
         // Update inode blocks (different block size!) count
         let inode_blocks = inode_ref.inode.blocks_count() + (BLOCK_SIZE / INODE_BLOCK_SIZE) as u64;
@@ -151,7 +151,7 @@ impl Ext4 {
 
         // Load block bitmap
         let bitmap_block_id = bg.desc.block_bitmap_block(&self.super_block);
-        let mut bitmap_block = self.block_device.read_block(bitmap_block_id);
+        let mut bitmap_block = self.read_block(bitmap_block_id);
         let mut bitmap = Bitmap::new(&mut bitmap_block.data);
 
         // Free the block
@@ -165,12 +165,12 @@ impl Ext4 {
 
         // Set block group checksum
         bg.desc.set_block_bitmap_csum(&self.super_block, &bitmap);
-        self.block_device.write_block(&bitmap_block);
+        self.write_block(&bitmap_block);
 
         // Update superblock free blocks count
         let free_blocks = self.super_block.free_blocks_count() + 1;
         self.super_block.set_free_blocks_count(free_blocks);
-        self.super_block.sync_to_disk(self.block_device.clone());
+        self.write_super_block();
 
         // Update inode blocks (different block size!) count
         let inode_blocks = inode_ref.inode.blocks_count() - (BLOCK_SIZE / INODE_BLOCK_SIZE) as u64;
@@ -203,7 +203,7 @@ impl Ext4 {
 
             // Load inode bitmap
             let bitmap_block_id = bg.desc.inode_bitmap_block(&self.super_block);
-            let mut bitmap_block = self.block_device.read_block(bitmap_block_id);
+            let mut bitmap_block = self.read_block(bitmap_block_id);
             let inode_count = self.super_block.inode_count_in_group(bgid) as usize;
             let mut bitmap = Bitmap::new(&mut bitmap_block.data[..inode_count / 8]);
 
@@ -215,7 +215,7 @@ impl Ext4 {
 
             // Update bitmap in disk
             bg.desc.set_inode_bitmap_csum(&self.super_block, &bitmap);
-            self.block_device.write_block(&bitmap_block);
+            self.write_block(&bitmap_block);
 
             // Modify filesystem counters
             let free_inodes = bg.desc.free_inodes_count() - 1;
@@ -240,7 +240,7 @@ impl Ext4 {
 
             // Update superblock
             self.super_block.decrease_free_inodes_count();
-            self.super_block.sync_to_disk(self.block_device.clone());
+            self.write_super_block();
 
             // Compute the absolute i-node number
             let inodes_per_group = self.super_block.inodes_per_group();
@@ -264,7 +264,7 @@ impl Ext4 {
 
         // Load inode bitmap
         let bitmap_block_id = bg.desc.inode_bitmap_block(&self.super_block);
-        let mut bitmap_block = self.block_device.read_block(bitmap_block_id);
+        let mut bitmap_block = self.read_block(bitmap_block_id);
         let inode_count = self.super_block.inode_count_in_group(bgid) as usize;
         let mut bitmap = Bitmap::new(&mut bitmap_block.data[..inode_count / 8]);
 
@@ -279,7 +279,7 @@ impl Ext4 {
 
         // Update bitmap in disk
         bg.desc.set_inode_bitmap_csum(&self.super_block, &bitmap);
-        self.block_device.write_block(&bitmap_block);
+        self.write_block(&bitmap_block);
 
         // Modify filesystem counters
         let free_inodes = bg.desc.free_inodes_count() + 1;
@@ -300,7 +300,7 @@ impl Ext4 {
 
         // Update superblock
         self.super_block.decrease_free_inodes_count();
-        self.super_block.sync_to_disk(self.block_device.clone());
+        self.write_super_block();
 
         Ok(())
     }

+ 6 - 6
src/ext4/dir.rs

@@ -15,7 +15,7 @@ impl Ext4 {
             // Get the fs block id
             let fblock = self.extent_get_pblock(parent, iblock)?;
             // Load block from disk
-            let block = self.block_device.read_block(fblock);
+            let block = self.read_block(fblock);
             // Find the entry in block
             let res = Self::find_entry_in_block(&block, name);
             if let Ok(r) = res {
@@ -46,7 +46,7 @@ impl Ext4 {
             // Get the parent physical block id
             let fblock = self.extent_get_pblock(parent, iblock)?;
             // Load the parent block from disk
-            let mut block = self.block_device.read_block(fblock);
+            let mut block = self.read_block(fblock);
             // Try inserting the entry to parent block
             if self.insert_entry_to_old_block(&mut block, child, name) {
                 return Ok(());
@@ -59,7 +59,7 @@ impl Ext4 {
         // Append a new data block
         let (_, fblock) = self.inode_append_block(parent)?;
         // Load new block
-        let mut new_block = self.block_device.read_block(fblock);
+        let mut new_block = self.read_block(fblock);
         // Write the entry to block
         self.insert_entry_to_new_block(&mut new_block, child, name);
 
@@ -83,7 +83,7 @@ impl Ext4 {
             // Get the parent physical block id
             let fblock = self.extent_get_pblock(parent, iblock)?;
             // Load the block from disk
-            let mut block = self.block_device.read_block(fblock);
+            let mut block = self.read_block(fblock);
             // Try removing the entry
             if let Ok(inode) = self.remove_entry_from_block(&mut block, name) {
                 return Ok(inode);
@@ -151,7 +151,7 @@ impl Ext4 {
         dst_blk.write_offset_as(tail_offset, &tail);
 
         // Sync block to disk
-        dst_blk.sync_to_disk(self.block_device.clone());
+        self.write_block(&dst_blk);
     }
 
     /// Try insert a directory entry of child inode into a parent block.
@@ -197,7 +197,7 @@ impl Ext4 {
             dst_blk.write_offset_as(tail_offset, &tail);
 
             // Sync to disk
-            dst_blk.sync_to_disk(self.block_device.clone());
+            self.write_block(&dst_blk);
             return true;
         }
         false

+ 14 - 14
src/ext4/extent.rs

@@ -37,7 +37,7 @@ impl Ext4 {
             let block_data: Block;
             let ex_node = if leaf.pblock != 0 {
                 // Load the extent node
-                block_data = self.block_device.read_block(leaf.pblock);
+                block_data = self.read_block(leaf.pblock);
                 // Load the next extent header
                 ExtentNode::from_bytes(&block_data.data)
             } else {
@@ -65,7 +65,7 @@ impl Ext4 {
         // Note: block data must be defined here to keep it alive
         let mut block_data: Block;
         let ex_node = if leaf.pblock != 0 {
-            block_data = self.block_device.read_block(leaf.pblock);
+            block_data = self.read_block(leaf.pblock);
             ExtentNodeMut::from_bytes(&mut block_data.data)
         } else {
             // Root node
@@ -116,7 +116,7 @@ impl Ext4 {
             for i in 0..ex_node.header().entries_count() as usize {
                 let ex_idx = ex_node.extent_index_at(i);
                 pblocks.push(ex_idx.leaf());
-                let child_block = self.block_device.read_block(ex_idx.leaf());
+                let child_block = self.read_block(ex_idx.leaf());
                 let child_node = ExtentNode::from_bytes(&child_block.data);
                 self.get_all_pblocks_recursive(&child_node, pblocks);
             }
@@ -143,7 +143,7 @@ impl Ext4 {
             // Load the next extent node
             let next = ex_idx.leaf();
             // Note: block data cannot be released until the next assigment
-            block_data = self.block_device.read_block(next);
+            block_data = self.read_block(next);
             // Load the next extent header
             ex_node = ExtentNode::from_bytes(&block_data.data);
             pblock = next;
@@ -177,11 +177,11 @@ impl Ext4 {
             };
         }
         // 2. Leaf is not root, load the leaf node
-        let mut leaf_block = self.block_device.read_block(leaf.pblock);
+        let mut leaf_block = self.read_block(leaf.pblock);
         let mut leaf_node = ExtentNodeMut::from_bytes(&mut leaf_block.data);
         // Insert the extent
         let res = leaf_node.insert_extent(new_ext, leaf.index.unwrap_err());
-        leaf_block.sync_to_disk(self.block_device.clone());
+        self.write_block(&leaf_block);
         // Handle split
         if let Err(mut split) = res {
             // Handle split until root
@@ -219,7 +219,7 @@ impl Ext4 {
         split: &[FakeExtent],
     ) -> core::result::Result<(), Vec<FakeExtent>> {
         let right_bid = self.alloc_block(inode_ref).unwrap();
-        let mut right_block = self.block_device.read_block(right_bid);
+        let mut right_block = self.read_block(right_bid);
         let mut right_node = ExtentNodeMut::from_bytes(&mut right_block.data);
 
         // Insert the split half to right node
@@ -244,16 +244,16 @@ impl Ext4 {
             self.write_inode_without_csum(inode_ref);
         } else {
             // Parent is not root
-            let mut parent_block = self.block_device.read_block(parent_pblock);
+            let mut parent_block = self.read_block(parent_pblock);
             let mut parent_node = ExtentNodeMut::from_bytes(&mut parent_block.data);
             parent_depth = parent_node.header().depth();
             res = parent_node.insert_extent_index(&extent_index, child_pos + 1);
-            parent_block.sync_to_disk(self.block_device.clone());
+            self.write_block(&parent_block);
         }
 
         // Right node is the child of parent, so its depth is 1 less than parent
         right_node.header_mut().set_depth(parent_depth - 1);
-        right_block.sync_to_disk(self.block_device.clone());
+        self.write_block(&right_block);
 
         res
     }
@@ -268,8 +268,8 @@ impl Ext4 {
         // Create left and right blocks
         let l_bid = self.alloc_block(inode_ref)?;
         let r_bid = self.alloc_block(inode_ref)?;
-        let mut l_block = self.block_device.read_block(l_bid);
-        let mut r_block = self.block_device.read_block(r_bid);
+        let mut l_block = self.read_block(l_bid);
+        let mut r_block = self.read_block(r_bid);
 
         // Load root, left, right nodes
         let mut root = inode_ref.inode.extent_node_mut();
@@ -299,8 +299,8 @@ impl Ext4 {
         *root.extent_index_mut_at(1) = ExtentIndex::new(right.extent_at(0).start_lblock(), r_bid);
 
         // Sync to disk
-        l_block.sync_to_disk(self.block_device.clone());
-        r_block.sync_to_disk(self.block_device.clone());
+        self.write_block(&l_block);
+        self.write_block(&r_block);
         self.write_inode_without_csum(inode_ref);
 
         Ok(())

+ 4 - 4
src/ext4/file.rs

@@ -123,7 +123,7 @@ impl Ext4 {
         if misaligned > 0 {
             let read_len = min(BLOCK_SIZE - misaligned, size_to_read);
             let fblock = self.extent_get_pblock(&mut inode_ref, start_iblock)?;
-            let block = self.block_device.read_block(fblock);
+            let block = self.read_block(fblock);
             // Copy data from block to the user buffer
             read_buf[cursor..cursor + read_len]
                 .copy_from_slice(block.read_offset(misaligned, read_len));
@@ -135,7 +135,7 @@ impl Ext4 {
         while cursor < size_to_read {
             let read_len = min(BLOCK_SIZE, size_to_read - cursor);
             let fblock = self.extent_get_pblock(&mut inode_ref, iblock)?;
-            let block = self.block_device.read_block(fblock);
+            let block = self.read_block(fblock);
             // Copy data from block to the user buffer
             read_buf[cursor..cursor + read_len].copy_from_slice(block.read_offset(0, read_len));
             cursor += read_len;
@@ -169,9 +169,9 @@ impl Ext4 {
         while cursor < size {
             let write_len = min(BLOCK_SIZE, size - cursor);
             let fblock = self.extent_get_pblock(&mut inode_ref, iblock)?;
-            let mut block = self.block_device.read_block(fblock);
+            let mut block = self.read_block(fblock);
             block.write_offset(file.fpos % BLOCK_SIZE, &data[cursor..cursor + write_len]);
-            block.sync_to_disk(self.block_device.clone());
+            self.write_block(&block);
 
             cursor += write_len;
             file.fpos += write_len;

+ 3 - 40
src/ext4/mod.rs

@@ -8,11 +8,12 @@ mod extent;
 mod file;
 mod journal;
 mod link;
+mod rw;
 
 #[derive(Debug)]
 pub struct Ext4 {
     pub block_device: Arc<dyn BlockDevice>,
-    pub super_block: Superblock,
+    pub super_block: SuperBlock,
     pub mount_point: MountPoint,
 }
 
@@ -25,7 +26,7 @@ impl Ext4 {
         // Load the superblock
         // TODO: if the main superblock is corrupted, should we load the backup?
         let block = block_device.read_block(0);
-        let super_block = block.read_offset_as::<Superblock>(BASE_OFFSET);
+        let super_block = block.read_offset_as::<SuperBlock>(BASE_OFFSET);
         // Root mount point
         let mount_point = MountPoint::new("/");
         // Create Ext4 instance
@@ -38,42 +39,4 @@ impl Ext4 {
         ext4.create_root_inode()?;
         Ok(ext4)
     }
-
-    /// Read an inode from block device, return an `InodeRef` that
-    /// combines the inode and its id.
-    fn read_inode(&self, inode_id: InodeId) -> InodeRef {
-        InodeRef::load_from_disk(self.block_device.clone(), &self.super_block, inode_id)
-    }
-
-    /// Read the root inode from block device
-    fn read_root_inode(&self) -> InodeRef {
-        self.read_inode(EXT4_ROOT_INO)
-    }
-
-    /// Write an inode to block device with checksum
-    fn write_inode_with_csum(&self, inode_ref: &mut InodeRef) {
-        inode_ref.sync_to_disk_with_csum(self.block_device.clone(), &self.super_block)
-    }
-
-    /// Write an inode to block device without checksum
-    fn write_inode_without_csum(&self, inode_ref: &InodeRef) {
-        inode_ref.sync_to_disk_without_csum(self.block_device.clone(), &self.super_block)
-    }
-
-    /// Read a block group descriptor from block device, return an `BlockGroupRef`
-    /// that combines the block group descriptor and its id.
-    fn read_block_group(&self, block_group_id: BlockGroupId) -> BlockGroupRef {
-        BlockGroupRef::load_from_disk(self.block_device.clone(), &self.super_block, block_group_id)
-    }
-
-    /// Write a block group descriptor to block device with checksum
-    fn write_block_group_with_csum(&self, bg_ref: &mut BlockGroupRef) {
-        bg_ref.sync_to_disk_with_csum(self.block_device.clone(), &self.super_block)
-    }
-
-    /// Write a block group descriptor to block device without checksum
-    #[allow(unused)]
-    fn write_block_group_without_csum(&self, bg_ref: &BlockGroupRef) {
-        bg_ref.sync_to_disk_without_csum(self.block_device.clone(), &self.super_block)
-    }
 }

+ 71 - 0
src/ext4/rw.rs

@@ -0,0 +1,71 @@
+use crate::constants::*;
+use crate::ext4_defs::*;
+use crate::prelude::*;
+
+use super::Ext4;
+
+impl Ext4 {
+    /// Read super block from block device
+    #[allow(unused)]
+    pub(super) fn read_super_block(&mut self) {
+        self.super_block = SuperBlock::load_from_disk(self.block_device.as_ref());
+    }
+
+    /// Write super block to block device
+    pub(super) fn write_super_block(&self) {
+        self.super_block.sync_to_disk(self.block_device.as_ref());
+    }
+
+    /// Read a block from block device
+    pub(super) fn read_block(&self, block_id: PBlockId) -> Block {
+        self.block_device.read_block(block_id)
+    }
+
+    /// Write a block to block device
+    pub(super) fn write_block(&self, block: &Block) {
+        self.block_device.write_block(block)
+    }
+
+    /// Read an inode from block device, return an `InodeRef` that
+    /// combines the inode and its id.
+    pub(super) fn read_inode(&self, inode_id: InodeId) -> InodeRef {
+        InodeRef::load_from_disk(self.block_device.as_ref(), &self.super_block, inode_id)
+    }
+
+    /// Read the root inode from block device
+    #[allow(unused)]
+    pub(super) fn read_root_inode(&self) -> InodeRef {
+        self.read_inode(EXT4_ROOT_INO)
+    }
+
+    /// Write an inode to block device with checksum
+    pub(super) fn write_inode_with_csum(&self, inode_ref: &mut InodeRef) {
+        inode_ref.sync_to_disk_with_csum(self.block_device.as_ref(), &self.super_block)
+    }
+
+    /// Write an inode to block device without checksum
+    pub(super) fn write_inode_without_csum(&self, inode_ref: &InodeRef) {
+        inode_ref.sync_to_disk_without_csum(self.block_device.as_ref(), &self.super_block)
+    }
+
+    /// Read a block group descriptor from block device, return an `BlockGroupRef`
+    /// that combines the block group descriptor and its id.
+    pub(super) fn read_block_group(&self, block_group_id: BlockGroupId) -> BlockGroupRef {
+        BlockGroupRef::load_from_disk(
+            self.block_device.as_ref(),
+            &self.super_block,
+            block_group_id,
+        )
+    }
+
+    /// Write a block group descriptor to block device with checksum
+    pub(super) fn write_block_group_with_csum(&self, bg_ref: &mut BlockGroupRef) {
+        bg_ref.sync_to_disk_with_csum(self.block_device.as_ref(), &self.super_block)
+    }
+
+    /// Write a block group descriptor to block device without checksum
+    #[allow(unused)]
+    pub(super) fn write_block_group_without_csum(&self, bg_ref: &BlockGroupRef) {
+        bg_ref.sync_to_disk_without_csum(self.block_device.as_ref(), &self.super_block)
+    }
+}

+ 0 - 5
src/ext4_defs/block_device.rs

@@ -66,11 +66,6 @@ impl Block {
     {
         self.write_offset(offset, value.to_bytes());
     }
-
-    /// Write block to disk
-    pub fn sync_to_disk(&self, block_device: Arc<dyn BlockDevice>) {
-        block_device.write_block(self);
-    }
 }
 
 /// Common interface for block devices

+ 30 - 30
src/ext4_defs/block_group.rs

@@ -10,7 +10,7 @@
 use super::crc::*;
 use super::Bitmap;
 use super::BlockDevice;
-use super::Superblock;
+use super::SuperBlock;
 use crate::constants::*;
 use crate::prelude::*;
 use crate::AsBytes;
@@ -47,7 +47,7 @@ pub struct BlockGroupDesc {
 impl AsBytes for BlockGroupDesc {}
 
 impl BlockGroupDesc {
-    pub fn block_bitmap_block(&self, s: &Superblock) -> PBlockId {
+    pub fn block_bitmap_block(&self, s: &SuperBlock) -> PBlockId {
         let mut v = self.block_bitmap_lo as u64;
         if s.desc_size() > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE {
             v |= (self.block_bitmap_hi as u64) << 32;
@@ -55,7 +55,7 @@ impl BlockGroupDesc {
         v
     }
 
-    pub fn inode_bitmap_block(&self, s: &Superblock) -> PBlockId {
+    pub fn inode_bitmap_block(&self, s: &SuperBlock) -> PBlockId {
         let mut v = self.inode_bitmap_lo as u64;
         if s.desc_size() > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE {
             v |= (self.inode_bitmap_hi as u64) << 32;
@@ -63,7 +63,7 @@ impl BlockGroupDesc {
         v
     }
 
-    pub fn itable_unused(&mut self, s: &Superblock) -> u32 {
+    pub fn itable_unused(&mut self, s: &SuperBlock) -> u32 {
         let mut v = self.itable_unused_lo as u32;
         if s.desc_size() > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE {
             v |= ((self.itable_unused_hi as u64) << 32) as u32;
@@ -71,7 +71,7 @@ impl BlockGroupDesc {
         v
     }
 
-    pub fn used_dirs_count(&self, s: &Superblock) -> u32 {
+    pub fn used_dirs_count(&self, s: &SuperBlock) -> u32 {
         let mut v = self.used_dirs_count_lo as u32;
         if s.desc_size() > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE {
             v |= ((self.used_dirs_count_hi as u64) << 32) as u32;
@@ -79,21 +79,21 @@ impl BlockGroupDesc {
         v
     }
 
-    pub fn set_used_dirs_count(&mut self, s: &Superblock, cnt: u32) {
+    pub fn set_used_dirs_count(&mut self, s: &SuperBlock, cnt: u32) {
         self.itable_unused_lo = ((cnt << 16) >> 16) as u16;
         if s.desc_size() > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE {
             self.itable_unused_hi = (cnt >> 16) as u16;
         }
     }
 
-    pub fn set_itable_unused(&mut self, s: &Superblock, cnt: u32) {
+    pub fn set_itable_unused(&mut self, s: &SuperBlock, cnt: u32) {
         self.itable_unused_lo = ((cnt << 16) >> 16) as u16;
         if s.desc_size() > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE {
             self.itable_unused_hi = (cnt >> 16) as u16;
         }
     }
 
-    pub fn set_free_inodes_count(&mut self, s: &Superblock, cnt: u32) {
+    pub fn set_free_inodes_count(&mut self, s: &SuperBlock, cnt: u32) {
         self.free_inodes_count_lo = ((cnt << 16) >> 16) as u16;
         if s.desc_size() > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE {
             self.free_inodes_count_hi = (cnt >> 16) as u16;
@@ -121,7 +121,7 @@ impl BlockGroupDesc {
         self.free_blocks_count_hi = (cnt >> 32) as u16;
     }
 
-    pub fn calc_inode_bitmap_csum(bitmap: &Bitmap, s: &Superblock) -> u32 {
+    pub fn calc_inode_bitmap_csum(bitmap: &Bitmap, s: &SuperBlock) -> u32 {
         let inodes_per_group = s.inodes_per_group();
         let uuid = s.uuid();
         let mut csum = ext4_crc32c(EXT4_CRC32_INIT, &uuid, uuid.len() as u32);
@@ -129,7 +129,7 @@ impl BlockGroupDesc {
         csum
     }
 
-    pub fn calc_block_bitmap_csum(bitmap: &Bitmap, s: &Superblock) -> u32 {
+    pub fn calc_block_bitmap_csum(bitmap: &Bitmap, s: &SuperBlock) -> u32 {
         let blocks_per_group = s.blocks_per_group();
         let uuid = s.uuid();
         let mut csum = ext4_crc32c(EXT4_CRC32_INIT, &uuid, uuid.len() as u32);
@@ -137,7 +137,7 @@ impl BlockGroupDesc {
         csum
     }
 
-    pub fn set_inode_bitmap_csum(&mut self, s: &Superblock, bitmap: &Bitmap) {
+    pub fn set_inode_bitmap_csum(&mut self, s: &SuperBlock, bitmap: &Bitmap) {
         let desc_size = s.desc_size();
 
         let csum = Self::calc_inode_bitmap_csum(&bitmap, s);
@@ -153,7 +153,7 @@ impl BlockGroupDesc {
         }
     }
 
-    pub fn set_block_bitmap_csum(&mut self, s: &Superblock, bitmap: &Bitmap) {
+    pub fn set_block_bitmap_csum(&mut self, s: &SuperBlock, bitmap: &Bitmap) {
         let desc_size = s.desc_size();
 
         let csum = Self::calc_block_bitmap_csum(&bitmap, s);
@@ -182,8 +182,8 @@ pub struct BlockGroupRef {
 impl BlockGroupRef {
     /// Load a block group descriptor from the disk
     pub fn load_from_disk(
-        block_device: Arc<dyn BlockDevice>,
-        super_block: &Superblock,
+        block_device: &dyn BlockDevice,
+        super_block: &SuperBlock,
         block_group_id: BlockGroupId,
     ) -> Self {
         let (block_id, offset) = Self::disk_pos(super_block, block_group_id);
@@ -194,37 +194,37 @@ impl BlockGroupRef {
             desc,
         }
     }
-
-    /// Find the position of a block group descriptor in the block device.
-    /// Return the block id and the offset within the block.
-    fn disk_pos(s: &Superblock, block_group_id: BlockGroupId) -> (PBlockId, usize) {
-        let desc_per_block = BLOCK_SIZE as u32 / s.desc_size() as u32;
-        let block_id = s.first_data_block() + block_group_id / desc_per_block + 1;
-        let offset = (block_group_id % desc_per_block) * s.desc_size() as u32;
-        (block_id as PBlockId, offset as usize)
-    }
-
+    
     pub fn sync_to_disk_without_csum(
         &self,
-        block_device: Arc<dyn BlockDevice>,
-        super_block: &Superblock,
+        block_device: &dyn BlockDevice,
+        super_block: &SuperBlock,
     ) {
         let (block_id, offset) = Self::disk_pos(super_block, self.id);
         let mut block = block_device.read_block(block_id as PBlockId);
         block.write_offset_as(offset, &self.desc);
-        block.sync_to_disk(block_device);
+        block_device.write_block(&block)
     }
 
     pub fn sync_to_disk_with_csum(
         &mut self,
-        block_device: Arc<dyn BlockDevice>,
-        super_block: &Superblock,
+        block_device: &dyn BlockDevice,
+        super_block: &SuperBlock,
     ) {
         self.set_checksum(super_block);
         self.sync_to_disk_without_csum(block_device, super_block);
     }
 
-    pub fn set_checksum(&mut self, super_block: &Superblock) {
+    /// Find the position of a block group descriptor in the block device.
+    /// Return the block id and the offset within the block.
+    fn disk_pos(s: &SuperBlock, block_group_id: BlockGroupId) -> (PBlockId, usize) {
+        let desc_per_block = BLOCK_SIZE as u32 / s.desc_size() as u32;
+        let block_id = s.first_data_block() + block_group_id / desc_per_block + 1;
+        let offset = (block_group_id % desc_per_block) * s.desc_size() as u32;
+        (block_id as PBlockId, offset as usize)
+    }
+
+    fn set_checksum(&mut self, super_block: &SuperBlock) {
         let desc_size = super_block.desc_size();
 
         // uuid checksum

+ 3 - 3
src/ext4_defs/dir_entry.rs

@@ -4,7 +4,7 @@
 //! linear array of directory entries.
 
 use super::crc::*;
-use super::Superblock;
+use super::SuperBlock;
 use crate::constants::*;
 use crate::prelude::*;
 use crate::AsBytes;
@@ -163,7 +163,7 @@ impl DirEntry {
         Self::required_size(self.name_len as usize)
     }
 
-    pub fn calc_csum(&self, s: &Superblock, blk_data: &[u8]) -> u32 {
+    pub fn calc_csum(&self, s: &SuperBlock, blk_data: &[u8]) -> u32 {
         let ino_index = self.inode;
         let ino_gen = 0 as u32;
 
@@ -194,7 +194,7 @@ pub struct DirEntryTail {
 impl AsBytes for DirEntryTail {}
 
 impl DirEntryTail {
-    pub fn set_csum(&mut self, s: &Superblock, diren: &DirEntry, blk_data: &[u8]) {
+    pub fn set_csum(&mut self, s: &SuperBlock, diren: &DirEntry, blk_data: &[u8]) {
         self.checksum = diren.calc_csum(s, blk_data);
     }
 }

+ 30 - 30
src/ext4_defs/inode.rs

@@ -11,7 +11,7 @@ use super::crc::*;
 use super::AsBytes;
 use super::BlockDevice;
 use super::BlockGroupRef;
-use super::Superblock;
+use super::SuperBlock;
 use super::{ExtentNode, ExtentNodeMut};
 use crate::constants::*;
 use crate::prelude::*;
@@ -89,7 +89,7 @@ impl Inode {
         self.mode |= mode;
     }
 
-    pub fn inode_type(&self, super_block: &Superblock) -> u32 {
+    pub fn inode_type(&self, super_block: &SuperBlock) -> u32 {
         let mut v = self.mode;
 
         if super_block.creator_os() == EXT4_SUPERBLOCK_OS_HURD {
@@ -99,11 +99,11 @@ impl Inode {
         (v & EXT4_INODE_MODE_TYPE_MASK) as u32
     }
 
-    pub fn is_dir(&self, super_block: &Superblock) -> bool {
+    pub fn is_dir(&self, super_block: &SuperBlock) -> bool {
         self.inode_type(super_block) == EXT4_INODE_MODE_DIRECTORY as u32
     }
 
-    pub fn is_softlink(&self, super_block: &Superblock) -> bool {
+    pub fn is_softlink(&self, super_block: &SuperBlock) -> bool {
         self.inode_type(super_block) == EXT4_INODE_MODE_SOFTLINK as u32
     }
 
@@ -215,11 +215,11 @@ impl InodeRef {
     }
 
     pub fn load_from_disk(
-        block_device: Arc<dyn BlockDevice>,
-        super_block: &Superblock,
+        block_device: &dyn BlockDevice,
+        super_block: &SuperBlock,
         id: InodeId,
     ) -> Self {
-        let (block_id, offset) = Self::disk_pos(super_block, block_device.clone(), id);
+        let (block_id, offset) = Self::disk_pos(super_block, block_device, id);
         let block = block_device.read_block(block_id);
         Self {
             id,
@@ -227,6 +227,26 @@ impl InodeRef {
         }
     }
 
+    pub fn sync_to_disk_without_csum(
+        &self,
+        block_device: &dyn BlockDevice,
+        super_block: &SuperBlock,
+    ) {
+        let (block_id, offset) = Self::disk_pos(super_block, block_device, self.id);
+        let mut block = block_device.read_block(block_id);
+        block.write_offset_as(offset, &self.inode);
+        block_device.write_block(&block)
+    }
+
+    pub fn sync_to_disk_with_csum(
+        &mut self,
+        block_device: &dyn BlockDevice,
+        super_block: &SuperBlock,
+    ) {
+        self.set_checksum(super_block);
+        self.sync_to_disk_without_csum(block_device, super_block);
+    }
+
     /// Find the position of an inode in the block device. Return the
     /// block id and the offset within the block.
     ///
@@ -240,8 +260,8 @@ impl InodeRef {
     /// To get the byte address within the inode table, use
     /// `offset = index * sb.inode_size`.
     fn disk_pos(
-        super_block: &Superblock,
-        block_device: Arc<dyn BlockDevice>,
+        super_block: &SuperBlock,
+        block_device: &dyn BlockDevice,
         inode_id: InodeId,
     ) -> (PBlockId, usize) {
         let inodes_per_group = super_block.inodes_per_group();
@@ -256,27 +276,7 @@ impl InodeRef {
         (block_id, offset)
     }
 
-    pub fn sync_to_disk_without_csum(
-        &self,
-        block_device: Arc<dyn BlockDevice>,
-        super_block: &Superblock,
-    ) {
-        let (block_id, offset) = Self::disk_pos(super_block, block_device.clone(), self.id);
-        let mut block = block_device.read_block(block_id);
-        block.write_offset_as(offset, &self.inode);
-        block.sync_to_disk(block_device);
-    }
-
-    pub fn sync_to_disk_with_csum(
-        &mut self,
-        block_device: Arc<dyn BlockDevice>,
-        super_block: &Superblock,
-    ) {
-        self.set_checksum(super_block);
-        self.sync_to_disk_without_csum(block_device, super_block);
-    }
-
-    pub fn set_checksum(&mut self, super_block: &Superblock) {
+    fn set_checksum(&mut self, super_block: &SuperBlock) {
         let inode_size = super_block.inode_size();
 
         let ino_index = self.id as u32;

+ 20 - 15
src/ext4_defs/super_block.rs

@@ -13,7 +13,7 @@ use crate::AsBytes;
 // 结构体表示超级块
 #[repr(C)]
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub struct Superblock {
+pub struct SuperBlock {
     inodes_count: u32,             // 节点数
     blocks_count_lo: u32,          // 块数
     reserved_blocks_count_lo: u32, // 保留块数
@@ -113,9 +113,20 @@ pub struct Superblock {
     checksum: u32,             // crc32c(superblock)
 }
 
-impl AsBytes for Superblock {}
+impl AsBytes for SuperBlock {}
+
+impl SuperBlock {
+    pub fn load_from_disk(block_device: &dyn BlockDevice) -> Self {
+        let block = block_device.read_block(0);
+        block.read_offset_as(BASE_OFFSET)
+    }
+
+    pub fn sync_to_disk(&self, block_device: &dyn BlockDevice) {
+        let mut block = block_device.read_block(0);
+        block.write_offset_as(BASE_OFFSET, self);
+        block_device.write_block(&block)
+    }
 
-impl Superblock {
     pub fn first_data_block(&self) -> u32 {
         self.first_data_block
     }
@@ -123,7 +134,7 @@ impl Superblock {
     pub fn free_inodes_count(&self) -> u32 {
         self.free_inodes_count
     }
-    
+
     pub fn features_read_only(&self) -> u32 {
         self.features_read_only
     }
@@ -136,7 +147,7 @@ impl Superblock {
     pub fn total_inodes(&self) -> u32 {
         self.inodes_count
     }
-    
+
     /// Returns the number of blocks in each block group.
     pub fn blocks_per_group(&self) -> u32 {
         self.blocks_per_group
@@ -146,19 +157,19 @@ impl Superblock {
     pub fn block_size(&self) -> u32 {
         1024 << self.log_block_size
     }
-    
+
     /// Returns the number of inodes in each block group.
     pub fn inodes_per_group(&self) -> u32 {
         self.inodes_per_group
     }
-    
+
     /// Returns the number of block groups.
     /// FIXME: This function is not correct.
     pub fn block_groups_count(&self) -> u32 {
         (((self.blocks_count_hi.to_le() as u64) << 32) as u32 | self.blocks_count_lo)
-        / self.blocks_per_group
+            / self.blocks_per_group
     }
-    
+
     /// Returns the size of inode structure.
     pub fn inode_size(&self) -> u16 {
         self.inode_size
@@ -223,10 +234,4 @@ impl Superblock {
         self.free_blocks_count_lo = ((free_blocks << 32) >> 32).to_le() as u32;
         self.free_blocks_count_hi = (free_blocks >> 32) as u32;
     }
-    
-    pub fn sync_to_disk(&self, block_device: Arc<dyn BlockDevice>) {
-        let mut block = block_device.read_block(0);
-        block.write_offset_as(BASE_OFFSET, self);
-        block.sync_to_disk(block_device);
-    }
 }