dfs_vnode.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-05-05 Bernard Implement vnode in dfs v2.0
  9. */
  10. #include <dfs_file.h>
  11. #include <dfs_mnt.h>
  12. #ifdef RT_USING_PAGECACHE
  13. #include "dfs_pcache.h"
  14. #endif
  15. #define DBG_TAG "DFS.vnode"
  16. #define DBG_LVL DBG_WARNING
  17. #include <rtdbg.h>
  18. int dfs_vnode_init(struct dfs_vnode *vnode, int type, const struct dfs_file_ops *fops)
  19. {
  20. if (vnode)
  21. {
  22. rt_memset(vnode, 0, sizeof(struct dfs_vnode));
  23. vnode->type = type;
  24. rt_atomic_store(&(vnode->ref_count), 1);
  25. vnode->mnt = RT_NULL;
  26. vnode->fops = fops;
  27. }
  28. return 0;
  29. }
  30. struct dfs_vnode *dfs_vnode_create(void)
  31. {
  32. struct dfs_vnode *vnode = rt_calloc(1, sizeof(struct dfs_vnode));
  33. if (!vnode)
  34. {
  35. LOG_E("create a vnode failed.");
  36. return RT_NULL;
  37. }
  38. rt_atomic_store(&(vnode->ref_count), 1);
  39. LOG_I("create a vnode: %p", vnode);
  40. return vnode;
  41. }
  42. int dfs_vnode_destroy(struct dfs_vnode* vnode)
  43. {
  44. rt_err_t ret = RT_EOK;
  45. if (vnode)
  46. {
  47. ret = dfs_file_lock();
  48. if (ret == RT_EOK)
  49. {
  50. if (rt_atomic_load(&(vnode->ref_count)) == 1)
  51. {
  52. LOG_I("free a vnode: %p", vnode);
  53. #ifdef RT_USING_PAGECACHE
  54. if (vnode->aspace)
  55. {
  56. dfs_aspace_destroy(vnode->aspace);
  57. }
  58. #endif
  59. if (vnode->mnt)
  60. {
  61. DLOG(msg, "vnode", vnode->mnt->fs_ops->name, DLOG_MSG, "fs_ops->free_vnode");
  62. vnode->mnt->fs_ops->free_vnode(vnode);
  63. }
  64. else
  65. {
  66. DLOG(msg, "vnode", "vnode", DLOG_MSG, "destroy vnode(mnt=NULL)");
  67. }
  68. dfs_file_unlock();
  69. rt_free(vnode);
  70. }
  71. else
  72. {
  73. dfs_file_unlock();
  74. }
  75. }
  76. }
  77. return 0;
  78. }
  79. struct dfs_vnode *dfs_vnode_ref(struct dfs_vnode *vnode)
  80. {
  81. if (vnode)
  82. {
  83. rt_atomic_add(&(vnode->ref_count), 1);
  84. DLOG(note, "vnode", "vnode ref_count=%d", rt_atomic_load(&(vnode->ref_count)));
  85. }
  86. return vnode;
  87. }
  88. void dfs_vnode_unref(struct dfs_vnode *vnode)
  89. {
  90. rt_err_t ret = RT_EOK;
  91. if (vnode)
  92. {
  93. ret = dfs_file_lock();
  94. if (ret == RT_EOK)
  95. {
  96. rt_atomic_sub(&(vnode->ref_count), 1);
  97. DLOG(note, "vnode", "vnode ref_count=%d", rt_atomic_load(&(vnode->ref_count)));
  98. #ifdef RT_USING_PAGECACHE
  99. if (vnode->aspace)
  100. {
  101. dfs_aspace_destroy(vnode->aspace);
  102. }
  103. #endif
  104. if (rt_atomic_load(&(vnode->ref_count)) == 0)
  105. {
  106. LOG_I("free a vnode: %p", vnode);
  107. DLOG(msg, "vnode", "vnode", DLOG_MSG, "free vnode, ref_count=0");
  108. if (vnode->mnt)
  109. {
  110. DLOG(msg, "vnode", vnode->mnt->fs_ops->name, DLOG_MSG, "fs_ops->free_vnode");
  111. vnode->mnt->fs_ops->free_vnode(vnode);
  112. }
  113. dfs_file_unlock();
  114. rt_free(vnode);
  115. }
  116. else
  117. {
  118. dfs_file_unlock();
  119. DLOG(note, "vnode", "vnode ref_count=%d", rt_atomic_load(&(vnode->ref_count)));
  120. }
  121. }
  122. }
  123. return;
  124. }