瀏覽代碼

feat: bitmap methods in bg

liujingx 11 月之前
父節點
當前提交
8f62f99e16
共有 4 個文件被更改,包括 40 次插入34 次删除
  1. 0 1
      src/ext4/mod.rs
  2. 14 2
      src/ext4_defs/bitmap.rs
  3. 20 27
      src/ext4_defs/block_group.rs
  4. 6 4
      src/ext4_defs/mod.rs

+ 0 - 1
src/ext4/mod.rs

@@ -8,7 +8,6 @@ mod extent;
 mod file;
 mod journal;
 mod link;
-mod bitmap;
 mod utils;
 
 #[derive(Debug)]

+ 14 - 2
src/ext4/bitmap.rs → src/ext4_defs/bitmap.rs

@@ -5,6 +5,10 @@ impl<'a> Bitmap<'a> {
         Self(bmap)
     }
 
+    pub fn as_raw(&self) -> &[u8] {
+        self.0
+    }
+
     pub fn is_bit_clear(&self, bit: usize) -> bool {
         self.0[bit / 8] & (1 << (bit % 8)) == 0
     }
@@ -21,8 +25,8 @@ impl<'a> Bitmap<'a> {
         self.0[bit / 8] &= !(1 << (bit % 8));
     }
 
-    /// Find the first clear bit in the range `[start, end)``
-    pub fn find_clear(&self, start: usize, end: usize) -> Option<usize> {
+    /// Find the first clear bit in the range `[start, end)`
+    pub fn first_clear_bit(&self, start: usize, end: usize) -> Option<usize> {
         for i in start..end {
             if self.is_bit_clear(i) {
                 return Some(i);
@@ -30,4 +34,12 @@ impl<'a> Bitmap<'a> {
         }
         None
     }
+
+    /// Find the first clear bit in the range `[start, end)` and set it if found
+    pub fn find_and_set_first_clear_bit(&mut self, start: usize, end: usize) -> Option<usize> {
+        self.first_clear_bit(start, end).map(|bit| {
+            self.set_bit(bit);
+            bit
+        })
+    }
 }

+ 20 - 27
src/ext4_defs/block_group.rs

@@ -8,6 +8,7 @@
 //! See [`super`] for more information.
 
 use super::crc::*;
+use super::Bitmap;
 use super::BlockDevice;
 use super::Ext4Superblock;
 use crate::constants::*;
@@ -128,19 +129,11 @@ impl Ext4BlockGroupDesc {
         }
     }
 
-    pub fn inode_table_first_block_hi(&self) -> u32 {
-        self.inode_table_first_block_hi
-    }
-
-    pub fn inode_table_first_block_lo(&self) -> u32 {
-        self.inode_table_first_block_lo
-    }
-
     pub fn free_inodes_count(&self) -> u32 {
         ((self.free_inodes_count_hi as u32) << 16) | self.free_inodes_count_lo as u32
     }
 
-    pub fn inode_table_blk_num(&self) -> u64 {
+    pub fn inode_table_first_block(&self) -> u64 {
         ((self.inode_table_first_block_hi as u64) << 32) | self.inode_table_first_block_lo as u64
     }
 
@@ -214,10 +207,10 @@ impl Ext4BlockGroupDesc {
         self.sync_to_disk(block_device, bgid, super_block)
     }
 
-    pub fn set_block_group_ialloc_bitmap_csum(&mut self, s: &Ext4Superblock, bitmap: &[u8]) {
+    pub fn set_inode_bitmap_csum(&mut self, s: &Ext4Superblock, bitmap: &Bitmap) {
         let desc_size = s.desc_size();
 
-        let csum = ext4_ialloc_bitmap_csum(bitmap, s);
+        let csum = Self::calc_inode_bitmap_csum(&bitmap, s);
         let lo_csum = (csum & 0xFFFF).to_le();
         let hi_csum = (csum >> 16).to_le();
 
@@ -230,10 +223,10 @@ impl Ext4BlockGroupDesc {
         }
     }
 
-    pub fn set_block_group_balloc_bitmap_csum(&mut self, s: &Ext4Superblock, bitmap: &[u8]) {
+    pub fn set_block_bitmap_csum(&mut self, s: &Ext4Superblock, bitmap: &Bitmap) {
         let desc_size = s.desc_size();
 
-        let csum = ext4_balloc_bitmap_csum(bitmap, s);
+        let csum = Self::calc_block_bitmap_csum(&bitmap, s);
         let lo_csum = (csum & 0xFFFF).to_le();
         let hi_csum = (csum >> 16).to_le();
 
@@ -258,20 +251,20 @@ impl Ext4BlockGroupDesc {
         self.free_blocks_count_lo = ((cnt << 32) >> 32) as u16;
         self.free_blocks_count_hi = (cnt >> 32) as u16;
     }
-}
 
-fn ext4_ialloc_bitmap_csum(bitmap: &[u8], s: &Ext4Superblock) -> 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);
-    csum = ext4_crc32c(csum, bitmap, (inodes_per_group + 7) / 8);
-    csum
-}
+    pub fn calc_inode_bitmap_csum(bitmap: &Bitmap, s: &Ext4Superblock) -> 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);
+        csum = ext4_crc32c(csum, bitmap.as_raw(), (inodes_per_group + 7) / 8);
+        csum
+    }
 
-fn ext4_balloc_bitmap_csum(bitmap: &[u8], s: &Ext4Superblock) -> 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);
-    csum = ext4_crc32c(csum, bitmap, (blocks_per_group / 8) as u32);
-    csum
+    pub fn calc_block_bitmap_csum(bitmap: &Bitmap, s: &Ext4Superblock) -> 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);
+        csum = ext4_crc32c(csum, bitmap.as_raw(), (blocks_per_group / 8) as u32);
+        csum
+    }
 }

+ 6 - 4
src/ext4_defs/mod.rs

@@ -1,7 +1,7 @@
 //! # The Defination of Ext4 File System Data Structures
-//! 
+//!
 //! The layout of a standard block group is approximately as follows:
-//! 
+//!
 //! - Group 0 Padding: 1024 bytes
 //! - Superblock: 1 block
 //! - Group Descriptors: many blocks
@@ -10,10 +10,11 @@
 //! - inode Bitmap: 1 block
 //! - inode Table: many blocks
 //! - Data Blocks: many more blocks
-//! 
+//!
 //! For the special case of block group 0, the first 1024 bytes are unused.
 //! For all other block groups, there is no padding.
 
+mod bitmap;
 mod block;
 mod block_device;
 mod block_group;
@@ -25,6 +26,7 @@ mod inode;
 mod mount_point;
 mod super_block;
 
+pub use bitmap::*;
 pub use block::*;
 pub use block_device::*;
 pub use block_group::*;
@@ -33,4 +35,4 @@ pub use extent::*;
 pub use file::*;
 pub use inode::*;
 pub use mount_point::*;
-pub use super_block::*;
+pub use super_block::*;