inode_ref.rs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. use super::Ext4Inode;
  2. use crate::Ext4;
  3. use crate::prelude::*;
  4. use crate::constants::*;
  5. pub struct Ext4InodeRef {
  6. pub inode_num: u32,
  7. pub inner: InodeRefInner,
  8. pub fs: Weak<Ext4>,
  9. }
  10. impl Ext4InodeRef {
  11. pub fn new(fs: Weak<Ext4>) -> Self {
  12. let inner = InodeRefInner {
  13. inode: Ext4Inode::default(),
  14. weak_self: Weak::new(),
  15. };
  16. let inode = Self {
  17. inode_num: 0,
  18. inner,
  19. fs,
  20. };
  21. inode
  22. }
  23. pub fn fs(&self) -> Arc<Ext4> {
  24. self.fs.upgrade().unwrap()
  25. }
  26. pub fn get_inode_ref(fs: Weak<Ext4>, inode_num: u32) -> Self {
  27. let fs_clone = fs.clone();
  28. let fs = fs.upgrade().unwrap();
  29. let super_block = fs.super_block;
  30. let inodes_per_group = super_block.inodes_per_group();
  31. let inode_size = super_block.inode_size() as u64;
  32. let group = (inode_num - 1) / inodes_per_group;
  33. let index = (inode_num - 1) % inodes_per_group;
  34. let group = fs.block_groups[group as usize];
  35. let inode_table_blk_num = group.get_inode_table_blk_num();
  36. let offset =
  37. inode_table_blk_num as usize * BLOCK_SIZE + index as usize * inode_size as usize;
  38. let data = fs.block_device.read_offset(offset);
  39. let inode_data = &data[..core::mem::size_of::<Ext4Inode>()];
  40. let inode = Ext4Inode::try_from(inode_data).unwrap();
  41. let inner = InodeRefInner {
  42. inode,
  43. weak_self: Weak::new(),
  44. };
  45. let inode = Self {
  46. inode_num,
  47. inner,
  48. fs: fs_clone,
  49. };
  50. inode
  51. }
  52. pub fn write_back_inode(&mut self) {
  53. let fs = self.fs();
  54. let block_device = fs.block_device.clone();
  55. let super_block = fs.super_block.clone();
  56. let inode_id = self.inode_num;
  57. self.inner
  58. .inode
  59. .sync_inode_to_disk_with_csum(block_device, &super_block, inode_id)
  60. .unwrap()
  61. }
  62. pub fn write_back_inode_without_csum(&mut self) {
  63. let fs = self.fs();
  64. let block_device = fs.block_device.clone();
  65. let super_block = fs.super_block.clone();
  66. let inode_id = self.inode_num;
  67. self.inner
  68. .inode
  69. .sync_inode_to_disk(block_device, &super_block, inode_id)
  70. .unwrap()
  71. }
  72. }
  73. pub struct InodeRefInner {
  74. pub inode: Ext4Inode,
  75. pub weak_self: Weak<Ext4InodeRef>,
  76. }
  77. impl InodeRefInner {
  78. pub fn inode(&self) -> Arc<Ext4InodeRef> {
  79. self.weak_self.upgrade().unwrap()
  80. }
  81. pub fn write_back_inode(&mut self) {
  82. let weak_inode_ref = self.weak_self.clone().upgrade().unwrap();
  83. let fs = weak_inode_ref.fs();
  84. let block_device = fs.block_device.clone();
  85. let super_block = fs.super_block.clone();
  86. let inode_id = weak_inode_ref.inode_num;
  87. self.inode
  88. .sync_inode_to_disk_with_csum(block_device, &super_block, inode_id)
  89. .unwrap()
  90. }
  91. }