mq_unlink.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /****************************************************************************
  2. * fs/mqueue/mq_unlink.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 <stdbool.h>
  25. #include <stdio.h>
  26. #include <mqueue.h>
  27. #include <assert.h>
  28. #include <errno.h>
  29. #include <nuttx/mqueue.h>
  30. #include "inode/inode.h"
  31. #include "mqueue/mqueue.h"
  32. /****************************************************************************
  33. * Private Functions
  34. ****************************************************************************/
  35. /****************************************************************************
  36. * Name: mq_inode_release
  37. *
  38. * Description:
  39. * Release a reference count on a message queue inode.
  40. *
  41. * Input Parameters:
  42. * inode - The message queue inode
  43. *
  44. * Returned Value:
  45. * None
  46. *
  47. ****************************************************************************/
  48. static void mq_inode_release(FAR struct inode *inode)
  49. {
  50. if (inode->i_crefs <= 1)
  51. {
  52. FAR struct mqueue_inode_s *msgq = inode->i_private;
  53. if (msgq)
  54. {
  55. nxmq_free_msgq(msgq);
  56. inode->i_private = NULL;
  57. }
  58. }
  59. }
  60. /****************************************************************************
  61. * Public Functions
  62. ****************************************************************************/
  63. /****************************************************************************
  64. * Name: file_mq_unlink
  65. *
  66. * Description:
  67. * This is an internal OS interface. It is functionally equivalent to
  68. * mq_unlink() except that:
  69. *
  70. * - It is not a cancellation point, and
  71. * - It does not modify the errno value.
  72. *
  73. * See comments with mq_unlink() for a more complete description of the
  74. * behavior of this function
  75. *
  76. * Input Parameters:
  77. * mq_name - Name of the message queue
  78. *
  79. * Returned Value:
  80. * This is an internal OS interface and should not be used by applications.
  81. * It follows the NuttX internal error return policy: Zero (OK) is
  82. * returned on success. A negated errno value is returned on failure.
  83. *
  84. ****************************************************************************/
  85. int file_mq_unlink(FAR const char *mq_name)
  86. {
  87. FAR struct inode *inode;
  88. struct inode_search_s desc;
  89. char fullpath[MAX_MQUEUE_PATH];
  90. int ret;
  91. /* Get the full path to the message queue */
  92. snprintf(fullpath, MAX_MQUEUE_PATH, CONFIG_FS_MQUEUE_MPATH "/%s", mq_name);
  93. /* Get the inode for this message queue. */
  94. SETUP_SEARCH(&desc, fullpath, false);
  95. sched_lock();
  96. ret = inode_find(&desc);
  97. if (ret < 0)
  98. {
  99. /* There is no inode that includes in this path */
  100. goto errout_with_search;
  101. }
  102. /* Get the search results */
  103. inode = desc.node;
  104. DEBUGASSERT(inode != NULL);
  105. /* Verify that what we found is, indeed, a message queue */
  106. if (!INODE_IS_MQUEUE(inode))
  107. {
  108. ret = -ENXIO;
  109. goto errout_with_inode;
  110. }
  111. /* Refuse to unlink the inode if it has children. I.e., if it is
  112. * functioning as a directory and the directory is not empty.
  113. */
  114. ret = inode_semtake();
  115. if (ret < 0)
  116. {
  117. goto errout_with_inode;
  118. }
  119. if (inode->i_child != NULL)
  120. {
  121. ret = -ENOTEMPTY;
  122. goto errout_with_semaphore;
  123. }
  124. /* Remove the old inode from the tree. Because we hold a reference count
  125. * on the inode, it will not be deleted now. This will set the
  126. * FSNODEFLAG_DELETED bit in the inode flags.
  127. */
  128. ret = inode_remove(fullpath);
  129. /* inode_remove() should always fail with -EBUSY because we hae a reference
  130. * on the inode. -EBUSY means that the inode was, indeed, unlinked but
  131. * thatis could not be freed because there are references.
  132. */
  133. DEBUGASSERT(ret >= 0 || ret == -EBUSY);
  134. /* Now we do not release the reference count in the normal way (by calling
  135. * inode release. Rather, we call mq_inode_release(). mq_inode_release
  136. * will decrement the reference count on the inode. But it will also free
  137. * the message queue if that reference count decrements to zero. Since we
  138. * hold one reference, that can only occur if the message queue is not
  139. * in-use.
  140. */
  141. inode_semgive();
  142. mq_inode_release(inode);
  143. RELEASE_SEARCH(&desc);
  144. sched_unlock();
  145. return OK;
  146. errout_with_semaphore:
  147. inode_semgive();
  148. errout_with_inode:
  149. inode_release(inode);
  150. errout_with_search:
  151. RELEASE_SEARCH(&desc);
  152. sched_unlock();
  153. return ret;
  154. }
  155. /****************************************************************************
  156. * Name: nxmq_unlink
  157. *
  158. * Description:
  159. * This is an internal OS interface. It is functionally equivalent to
  160. * mq_unlink() except that:
  161. *
  162. * - It is not a cancellation point, and
  163. * - It does not modify the errno value.
  164. *
  165. * See comments with mq_unlink() for a more complete description of the
  166. * behavior of this function
  167. *
  168. * Input Parameters:
  169. * mq_name - Name of the message queue
  170. *
  171. * Returned Value:
  172. * This is an internal OS interface and should not be used by applications.
  173. * It follows the NuttX internal error return policy: Zero (OK) is
  174. * returned on success. A negated errno value is returned on failure.
  175. *
  176. ****************************************************************************/
  177. int nxmq_unlink(FAR const char *mq_name)
  178. {
  179. return file_mq_unlink(mq_name);
  180. }
  181. /****************************************************************************
  182. * Name: mq_unlink
  183. *
  184. * Description:
  185. * This function removes the message queue named by "mq_name." If one
  186. * or more tasks have the message queue open when mq_unlink() is called,
  187. * removal of the message queue is postponed until all references to the
  188. * message queue have been closed.
  189. *
  190. * Input Parameters:
  191. * mq_name - Name of the message queue
  192. *
  193. * Returned Value:
  194. * None
  195. *
  196. * Assumptions:
  197. *
  198. ****************************************************************************/
  199. int mq_unlink(FAR const char *mq_name)
  200. {
  201. int ret;
  202. ret = nxmq_unlink(mq_name);
  203. if (ret < 0)
  204. {
  205. set_errno(-ret);
  206. return ERROR;
  207. }
  208. return OK;
  209. }