Преглед на файлове

fix: unmatched inode block size

liujingx преди 9 месеца
родител
ревизия
fe0c4d2e7a
променени са 6 файла, в които са добавени 27 реда и са изтрити 14 реда
  1. 2 2
      src/constants.rs
  2. 2 2
      src/ext4/alloc.rs
  3. 4 4
      src/ext4/dir.rs
  4. 1 1
      src/ext4/high_level.rs
  5. 1 1
      src/ext4/low_level.rs
  6. 17 4
      src/ext4_defs/inode.rs

+ 2 - 2
src/constants.rs

@@ -15,7 +15,7 @@ pub const NAME_MAX: usize = 255;
 pub const SYMLINKS_MAX: usize = 40;
 
 /// The inode number of root inode
-pub const EXT4_ROOT_INO: InodeId = 1;
+pub const EXT4_ROOT_INO: InodeId = 2;
 
 /// The base offset of the super block
 pub const BASE_OFFSET: usize = 1024;
@@ -24,7 +24,7 @@ pub const BASE_OFFSET: usize = 1024;
 pub const BLOCK_SIZE: usize = 4096;
 
 /// For simplicity define this the same as block size
-pub const INODE_BLOCK_SIZE: usize = 4096;
+pub const INODE_BLOCK_SIZE: usize = 512;
 
 /// CRC32 initial value
 pub const CRC32_INIT: u32 = 0xFFFFFFFF;

+ 2 - 2
src/ext4/alloc.rs

@@ -91,11 +91,11 @@ impl Ext4 {
     /// newly created block.
     pub(super) fn inode_append_block(&self, inode: &mut InodeRef) -> Result<(LBlockId, PBlockId)> {
         // The new logical block id
-        let iblock = inode.inode.block_count() as LBlockId;
+        let iblock = inode.inode.fs_block_count() as LBlockId;
         // Check the extent tree to get the physical block id
         let fblock = self.extent_query_or_create(inode, iblock, 1)?;
         // Update block count
-        inode.inode.set_block_count(inode.inode.block_count() + 1);
+        inode.inode.set_fs_block_count(iblock as u64 + 1);
         self.write_inode_without_csum(inode);
 
         Ok((iblock, fblock))

+ 4 - 4
src/ext4/dir.rs

@@ -8,7 +8,7 @@ impl Ext4 {
     /// Find a directory entry that matches a given name under a parent directory
     pub(super) fn dir_find_entry(&self, dir: &InodeRef, name: &str) -> Result<InodeId> {
         trace!("Dir find entry: dir {}, name {}", dir.id, name);
-        let total_blocks: u32 = dir.inode.block_count() as u32;
+        let total_blocks = dir.inode.fs_block_count() as u32;
         let mut iblock: LBlockId = 0;
         while iblock < total_blocks {
             // Get the fs block id
@@ -43,7 +43,7 @@ impl Ext4 {
             child.id,
             name
         );
-        let total_blocks: u32 = dir.inode.block_count() as u32;
+        let total_blocks = dir.inode.fs_block_count() as u32;
         let mut iblock: LBlockId = 0;
         // Try finding a block with enough space
         while iblock < total_blocks {
@@ -90,7 +90,7 @@ impl Ext4 {
     /// Remove a entry from a directory
     pub(super) fn dir_remove_entry(&self, dir: &InodeRef, name: &str) -> Result<()> {
         trace!("Dir remove entry: dir {}, name {}", dir.id, name);
-        let total_blocks: u32 = dir.inode.block_count() as u32;
+        let total_blocks = dir.inode.fs_block_count() as u32;
         // Check each block
         let mut iblock: LBlockId = 0;
         while iblock < total_blocks {
@@ -124,7 +124,7 @@ impl Ext4 {
 
     /// Get all entries under a directory
     pub(super) fn dir_list_entries(&self, dir: &InodeRef) -> Vec<DirEntry> {
-        let total_blocks = dir.inode.block_count() as u32;
+        let total_blocks = dir.inode.fs_block_count() as u32;
         let mut entries: Vec<DirEntry> = Vec::new();
         let mut iblock: LBlockId = 0;
         while iblock < total_blocks {

+ 1 - 1
src/ext4/high_level.rs

@@ -80,7 +80,7 @@ impl Ext4 {
         // Search recursively
         for (i, path) in search_path.iter().enumerate() {
             if !cur.inode.is_dir() {
-                return_error!(ErrCode::ENOTDIR, "Parent directory is not a directory");
+                return_error!(ErrCode::ENOTDIR, "Parent {} is not a directory", cur.id);
             }
             match self.dir_find_entry(&cur, &path) {
                 Ok(de) => {

+ 1 - 1
src/ext4/low_level.rs

@@ -231,7 +231,7 @@ impl Ext4 {
         let start_iblock = (offset / BLOCK_SIZE) as LBlockId;
         let end_iblock = ((offset + write_size) / BLOCK_SIZE) as LBlockId;
         // Append enough block for writing
-        let append_block_count = end_iblock as i64 + 1 - file.inode.block_count() as i64;
+        let append_block_count = end_iblock as i64 + 1 - file.inode.fs_block_count() as i64;
         for _ in 0..append_block_count {
             self.inode_append_block(&mut file)?;
         }

+ 17 - 4
src/ext4_defs/inode.rs

@@ -124,10 +124,7 @@ pub struct Inode {
     gid: u16,
     /// Hard link count.
     link_count: u16,
-    /// Lower 32-bits of "block" count.
-    /// Note: this field is different from ext4 inode by now.
-    /// Ext4 defines this as the count of 512-byte blocks.
-    /// To simplify, we define this as the count of 4096-byte blocks.
+    /// Lower 32-bits of "512-byte block" count.
     block_count: u32,
     /// Inode flags.
     flags: u32,
@@ -283,15 +280,31 @@ impl Inode {
         self.crtime = crtime;
     }
 
+    /// Get the number of 512-byte blocks (`INODE_BLOCK_SIZE`) used by the inode.
+    ///
+    /// WARN: This is different from filesystem block (`BLOCK_SIZE`)!
     pub fn block_count(&self) -> u64 {
         self.block_count as u64 | ((self.osd2.l_blocks_hi as u64) << 32)
     }
 
+    /// Get the number of filesystem blocks (`BLOCK_SIZE`) used by the inode.
+    pub fn fs_block_count(&self) -> u64 {
+        self.block_count() * INODE_BLOCK_SIZE as u64 / BLOCK_SIZE as u64
+    }
+
+    /// Set the number of 512-byte blocks (`INODE_BLOCK_SIZE`) used by the inode.
+    ///
+    /// WARN: This is different from filesystem block (`BLOCK_SIZE`)!
     pub fn set_block_count(&mut self, cnt: u64) {
         self.block_count = cnt as u32;
         self.osd2.l_blocks_hi = (cnt >> 32) as u16;
     }
 
+    /// Set the number of filesystem blocks (`BLOCK_SIZE`) used by the inode.
+    pub fn set_fs_block_count(&mut self, cnt: u64) {
+        self.set_block_count(cnt * BLOCK_SIZE as u64 / INODE_BLOCK_SIZE as u64);
+    }
+
     pub fn generation(&self) -> u32 {
         self.generation
     }