fs_inoderemove.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /****************************************************************************
  2. * fs/inode/fs_inoderemove.c
  3. *
  4. * Licensed to the Apache Software Foundation (ASF) under one or more
  5. * contributor license agreements. See the NOTICE file distributed with
  6. * this work for additional information regarding copyright ownership. The
  7. * ASF licenses this file to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance with the
  9. * License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  16. * License for the specific language governing permissions and limitations
  17. * under the License.
  18. *
  19. ****************************************************************************/
  20. /****************************************************************************
  21. * Included Files
  22. ****************************************************************************/
  23. #include <nuttx/config.h>
  24. #include <errno.h>
  25. #include <nuttx/kmalloc.h>
  26. #include <nuttx/fs/fs.h>
  27. #include "inode/inode.h"
  28. /****************************************************************************
  29. * Public Functions
  30. ****************************************************************************/
  31. /****************************************************************************
  32. * Name: inode_unlink
  33. *
  34. * Description:
  35. * Given a path, remove a the node from the in-memory, inode tree that the
  36. * path refers to. This is normally done in preparation to removing or
  37. * moving an inode.
  38. *
  39. * In symbolic links in the pseduo file system are enabled, then this
  40. * logic will follow the symbolic links up until the terminal node. Then
  41. * that link in removed. So if this the terminal node is a symbolic link,
  42. * the symbolic link node will be removed, not the target of the link.
  43. *
  44. * Assumptions/Limitations:
  45. * The caller must hold the inode semaphore
  46. *
  47. ****************************************************************************/
  48. FAR struct inode *inode_unlink(FAR const char *path)
  49. {
  50. struct inode_search_s desc;
  51. FAR struct inode *node = NULL;
  52. int ret;
  53. /* Verify parameters. Ignore null paths */
  54. if (path == NULL)
  55. {
  56. return NULL;
  57. }
  58. /* Find the node to unlink */
  59. SETUP_SEARCH(&desc, path, true);
  60. ret = inode_search(&desc);
  61. if (ret >= 0)
  62. {
  63. node = desc.node;
  64. DEBUGASSERT(node != NULL);
  65. /* If peer is non-null, then remove the node from the right of
  66. * of that peer node.
  67. */
  68. if (desc.peer != NULL)
  69. {
  70. desc.peer->i_peer = node->i_peer;
  71. }
  72. /* Then remove the node from head of the list of children. */
  73. else
  74. {
  75. DEBUGASSERT(desc.parent != NULL);
  76. desc.parent->i_child = node->i_peer;
  77. }
  78. node->i_peer = NULL;
  79. }
  80. RELEASE_SEARCH(&desc);
  81. return node;
  82. }
  83. /****************************************************************************
  84. * Name: inode_remove
  85. *
  86. * Description:
  87. * Given a path, remove a the node from the in-memory, inode tree that the
  88. * path refers to and free all resources related to the inode. If the
  89. * inode is in-use, then it will be unlinked, but will not be freed until
  90. * the last reference to the inode is released.
  91. *
  92. * Assumptions/Limitations:
  93. * The caller must hold the inode semaphore
  94. *
  95. ****************************************************************************/
  96. int inode_remove(FAR const char *path)
  97. {
  98. FAR struct inode *node;
  99. /* Find the inode and unlink it from the in-memory inode tree */
  100. node = inode_unlink(path);
  101. if (node)
  102. {
  103. /* Found it! But we cannot delete the inode if there are references
  104. * to it
  105. */
  106. if (node->i_crefs)
  107. {
  108. /* In that case, we will mark it deleted, when the filesystem
  109. * releases the inode, we will then, finally delete the subtree
  110. */
  111. node->i_flags |= FSNODEFLAG_DELETED;
  112. return -EBUSY;
  113. }
  114. else
  115. {
  116. /* And delete it now -- recursively to delete all of its children.
  117. * Since it has been unlinked, then the peer pointer should be
  118. * NULL.
  119. */
  120. DEBUGASSERT(node->i_peer == NULL);
  121. inode_free(node);
  122. return OK;
  123. }
  124. }
  125. /* The node does not exist */
  126. return -ENOENT;
  127. }