mod.rs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. use crate::constants::*;
  2. use crate::ext4_defs::*;
  3. use crate::prelude::*;
  4. mod alloc;
  5. mod dir;
  6. mod extent;
  7. mod file;
  8. mod journal;
  9. mod link;
  10. mod utils;
  11. #[derive(Debug)]
  12. pub struct Ext4 {
  13. pub block_device: Arc<dyn BlockDevice>,
  14. pub super_block: Ext4Superblock,
  15. pub block_groups: Vec<Ext4BlockGroupDesc>,
  16. pub inodes_per_group: u32,
  17. pub blocks_per_group: u32,
  18. pub inode_size: usize,
  19. pub last_inode_bg_id: u32,
  20. pub mount_point: Ext4MountPoint,
  21. }
  22. impl Ext4 {
  23. /// Opens and loads an Ext4 from the `block_device`.
  24. ///
  25. /// | Super Block | Group Descriptor | Reserved GDT Blocks |
  26. /// | Block Bitmap | Inode Bitmap | Inode Table | Data Blocks |
  27. pub fn load(block_device: Arc<dyn BlockDevice>) -> Self {
  28. // Load the superblock
  29. // TODO: if the main superblock is corrupted, should we load the backup?
  30. let raw_data = block_device.read_offset(BASE_OFFSET);
  31. let super_block = Ext4Superblock::try_from(raw_data).unwrap();
  32. let inodes_per_group = super_block.inodes_per_group();
  33. let blocks_per_group = super_block.blocks_per_group();
  34. let inode_size = super_block.inode_size() as usize;
  35. // Load the block groups description
  36. let block_groups_count = super_block.block_groups_count() as usize;
  37. let mut block_groups = Vec::with_capacity(block_groups_count);
  38. for idx in 0..block_groups_count {
  39. let block_group =
  40. Ext4BlockGroupDesc::load(block_device.clone(), &super_block, idx).unwrap();
  41. block_groups.push(block_group);
  42. }
  43. // Root mount point
  44. let mount_point = Ext4MountPoint::new("/");
  45. // Create Ext4 instance
  46. Self {
  47. super_block,
  48. inodes_per_group,
  49. blocks_per_group,
  50. inode_size,
  51. block_groups,
  52. block_device,
  53. mount_point,
  54. last_inode_bg_id: 0,
  55. }
  56. }
  57. /// Read an inode from block device, return an`Ext4InodeRef` that combines
  58. /// the inode and its id.
  59. fn get_inode_ref(&self, inode_id: u32) -> Ext4InodeRef {
  60. Ext4InodeRef::read_from_disk(self.block_device.clone(), &self.super_block, inode_id)
  61. }
  62. /// Read the root inode from block device
  63. fn get_root_inode_ref(&self) -> Ext4InodeRef {
  64. self.get_inode_ref(EXT4_ROOT_INO)
  65. }
  66. /// Write back an inode to block device with checksum
  67. fn write_back_inode_with_csum(&self, inode_ref: &mut Ext4InodeRef) {
  68. inode_ref
  69. .sync_to_disk_with_csum(self.block_device.clone(), &self.super_block)
  70. .unwrap()
  71. }
  72. /// Write back an inode to block device without checksum
  73. fn write_back_inode_without_csum(&self, inode_ref: &mut Ext4InodeRef) {
  74. inode_ref
  75. .sync_to_disk_without_csum(self.block_device.clone(), &self.super_block)
  76. .unwrap()
  77. }
  78. }