dcache.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #include "internal.h"
  2. #include <common/kfifo.h>
  3. #include <debug/bug.h>
  4. /**
  5. * @brief 释放dentry
  6. *
  7. * @param dentry 目标dentry
  8. */
  9. void vfs_dentry_put(struct vfs_dir_entry_t *dentry)
  10. {
  11. int retval = 0;
  12. uint64_t in_value = 0;
  13. // todo: 加锁、放锁
  14. // 创建一个用来存放指向dentry的指针的fifo队列
  15. struct kfifo_t fifo;
  16. // 暂时假设队列大小为1024个元素
  17. // todo: 实现队列的自动扩容功能
  18. retval = kfifo_alloc(&fifo, 1024 * sizeof(uint64_t), 0);
  19. if (retval != 0)
  20. goto failed;
  21. // 将根dentry加入队列
  22. in_value = (uint64_t)dentry;
  23. kfifo_in(&fifo, &in_value, sizeof(uint64_t));
  24. list_del(&dentry->child_node_list); // 从父dentry中删除
  25. while (!kfifo_empty(&fifo))
  26. {
  27. // 取出队列中的下一个元素
  28. kfifo_out(&fifo, &dentry, sizeof(uint64_t));
  29. BUG_ON(dentry == NULL);
  30. struct List *list = &dentry->subdirs_list;
  31. if (!list_empty(list))
  32. {
  33. // 将当前dentry下的所有dentry加入队列
  34. do
  35. {
  36. list = list_next(list);
  37. in_value = (uint64_t)container_of(list, struct vfs_dir_entry_t, child_node_list);
  38. if (in_value != NULL)
  39. kfifo_in(&fifo, &in_value, sizeof(uint64_t));
  40. } while (list_next(list) != (&dentry->subdirs_list));
  41. }
  42. // 释放inode
  43. vfs_free_inode(dentry->dir_inode);
  44. // 若当前dentry是否为挂载点,则umount
  45. if (is_local_mountpoint(dentry))
  46. do_umount(dentry);
  47. dentry->dir_ops->release(dentry);
  48. kfree(dentry);
  49. }
  50. kfifo_free_alloc(&fifo);
  51. return;
  52. failed:;
  53. if (fifo.buffer != NULL)
  54. kfifo_free_alloc(&fifo);
  55. kerror("dentry_put failed.");
  56. }
  57. /**
  58. * @brief 释放inode
  59. *
  60. * @param inode 待释放的inode
  61. * @return int 错误码
  62. */
  63. int vfs_free_inode(struct vfs_index_node_t *inode)
  64. {
  65. --inode->ref_count;
  66. BUG_ON(inode->ref_count < 0);
  67. if (inode->ref_count == 0)
  68. {
  69. kfree(inode->private_inode_info);
  70. kfree(inode);
  71. }
  72. return 0;
  73. }