link.rs 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. use super::Ext4;
  2. use crate::ext4_defs::*;
  3. use crate::prelude::*;
  4. impl Ext4 {
  5. /// Link a child inode to a parent directory.
  6. pub(super) fn link_inode(
  7. &self,
  8. parent: &mut InodeRef,
  9. child: &mut InodeRef,
  10. name: &str,
  11. ) -> Result<()> {
  12. // Add entry to parent directory
  13. self.dir_add_entry(parent, child, name)?;
  14. let child_link_count = child.inode.link_count();
  15. if child.inode.is_dir() && child_link_count == 0 {
  16. // Add '.' and '..' entries if child is a newly created directory
  17. let child_self = child.clone();
  18. self.dir_add_entry(child, &child_self, ".")?;
  19. self.dir_add_entry(child, parent, "..")?;
  20. // Link child/".."
  21. parent.inode.set_link_count(parent.inode.link_count() + 1);
  22. self.write_inode_with_csum(parent);
  23. // Link parent/child + child/"."
  24. child.inode.set_link_count(child_link_count + 2);
  25. } else {
  26. // Link parent/child
  27. child.inode.set_link_count(child_link_count + 1);
  28. }
  29. self.write_inode_with_csum(child);
  30. Ok(())
  31. }
  32. /// Unlink a child inode from a parent directory.
  33. /// Free the inode if link count is 0.
  34. pub(super) fn unlink_inode(
  35. &self,
  36. parent: &mut InodeRef,
  37. child: &mut InodeRef,
  38. name: &str,
  39. ) -> Result<()> {
  40. // Remove entry from parent directory
  41. self.dir_remove_entry(parent, name)?;
  42. let child_link_cnt = child.inode.link_count();
  43. if child.inode.is_dir() && child_link_cnt <= 2 {
  44. // Child is an empty directory
  45. // Unlink "child/.."
  46. parent.inode.set_link_count(parent.inode.link_count() - 1);
  47. self.write_inode_with_csum(parent);
  48. // Remove directory
  49. self.free_inode(child)
  50. } else if child_link_cnt <= 1 {
  51. // Child is a file
  52. // Remove file
  53. self.free_inode(child)
  54. } else {
  55. // Not remove
  56. child.inode.set_link_count(child_link_cnt - 1);
  57. self.write_inode_with_csum(child);
  58. Ok(())
  59. }
  60. }
  61. }