aio_fsync.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /****************************************************************************
  2. * fs/aio/aio_fsync.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 <unistd.h>
  25. #include <fcntl.h>
  26. #include <aio.h>
  27. #include <assert.h>
  28. #include <errno.h>
  29. #include <debug.h>
  30. #include <nuttx/fs/fs.h>
  31. #include "aio/aio.h"
  32. #ifdef CONFIG_FS_AIO
  33. /****************************************************************************
  34. * Private Functions
  35. ****************************************************************************/
  36. /****************************************************************************
  37. * Name: aio_fsync_worker
  38. *
  39. * Description:
  40. * This function executes on the worker thread and performs the
  41. * asynchronous I/O operation.
  42. *
  43. * Input Parameters:
  44. * arg - Worker argument. In this case, a pointer to an instance of
  45. * struct aiocb cast to void *.
  46. *
  47. * Returned Value:
  48. * None
  49. *
  50. ****************************************************************************/
  51. static void aio_fsync_worker(FAR void *arg)
  52. {
  53. FAR struct aio_container_s *aioc = (FAR struct aio_container_s *)arg;
  54. FAR struct aiocb *aiocbp;
  55. pid_t pid;
  56. #ifdef CONFIG_PRIORITY_INHERITANCE
  57. uint8_t prio;
  58. #endif
  59. int ret;
  60. /* Get the information from the container, decant the AIO control block,
  61. * and free the container before starting any I/O. That will minimize
  62. * the delays by any other threads waiting for a pre-allocated container.
  63. */
  64. DEBUGASSERT(aioc && aioc->aioc_aiocbp);
  65. pid = aioc->aioc_pid;
  66. #ifdef CONFIG_PRIORITY_INHERITANCE
  67. prio = aioc->aioc_prio;
  68. #endif
  69. aiocbp = aioc_decant(aioc);
  70. /* Perform the fsync using aioc_filep */
  71. ret = file_fsync(aioc->aioc_filep);
  72. if (ret < 0)
  73. {
  74. ferr("ERROR: file_fsync failed: %d\n", ret);
  75. aiocbp->aio_result = ret;
  76. }
  77. else
  78. {
  79. aiocbp->aio_result = OK;
  80. }
  81. /* Signal the client */
  82. aio_signal(pid, aiocbp);
  83. #ifdef CONFIG_PRIORITY_INHERITANCE
  84. /* Restore the low priority worker thread default priority */
  85. lpwork_restorepriority(prio);
  86. #endif
  87. }
  88. /****************************************************************************
  89. * Public Functions
  90. ****************************************************************************/
  91. /****************************************************************************
  92. * Name: aio_fsync
  93. *
  94. * Description:
  95. * The aio_fsync() function asynchronously forces all I/O operations
  96. * associated with the file indicated by the file descriptor aio_fildes
  97. * member of the aiocb structure referenced by the aiocbp argument and
  98. * queued at the time of the call to aio_fsync() to the synchronized
  99. * I/O completion state. The function call will return when the
  100. * synchronization request has been initiated or queued to the file or
  101. * device (even when the data cannot be synchronized immediately).
  102. *
  103. * If op is O_DSYNC, all currently queued I/O operations will be
  104. * completed as if by a call to fdatasync(); that is, as defined for
  105. * synchronized I/O data integrity completion. If op is O_SYNC, all
  106. * currently queued I/O operations will be completed as if by a call to
  107. * fsync(); that is, as defined for synchronized I/O file integrity
  108. * completion. If the aio_fsync() function fails, or if the operation
  109. * queued by aio_fsync() fails, then, as for fsync() and fdatasync(),
  110. * outstanding I/O operations are not guaranteed to have been completed.
  111. * [See "POSIX Compliance" below]
  112. *
  113. * If aio_fsync() succeeds, then it is only the I/O that was queued at
  114. * the time of the call to aio_fsync() that is guaranteed to be forced
  115. * to the relevant completion state. The completion of subsequent I/O
  116. * on the file descriptor is not guaranteed to be completed in a
  117. * synchronized fashion.
  118. *
  119. * The aiocbp argument refers to an asynchronous I/O control block. The
  120. * aiocbp value may be used as an argument to aio_error() and aio_return()
  121. * in order to determine the error status and return status, respectively,
  122. * of the asynchronous operation while it is proceeding. When the request
  123. * is queued, the error status for the operation is [EINPROGRESS]. When
  124. * all data has been successfully transferred, the error status will be
  125. * reset to reflect the success or failure of the operation. If the
  126. * operation does not complete successfully, the error status for the
  127. * operation will be set to indicate the error. The aio_sigevent member
  128. * determines the asynchronous notification to occur when all operations
  129. * have achieved synchronized I/O completion. All other members of the
  130. * structure referenced by aiocbp are ignored. If the control block
  131. * referenced by aiocbp becomes an illegal address prior to asynchronous
  132. * I/O completion, then the behavior is undefined.
  133. *
  134. * If the aio_fsync() function fails or aiocbp indicates an error
  135. * condition, data is not guaranteed to have been successfully transferred.
  136. *
  137. * Input Parameters:
  138. * op - Should be either O_SYNC or O_DSYNC. Ignored in this
  139. * implementation.
  140. * aiocbp - A pointer to an instance of struct aiocb
  141. *
  142. * Returned Value:
  143. * The aio_fsync() function will return the value 0 if the I/O operation is
  144. * successfully queued; otherwise, the function will return the value -1
  145. * and set errno to indicate the error.
  146. *
  147. * The aio_fsync() function will fail if:
  148. *
  149. * EAGAIN - The requested asynchronous operation was not queued due to
  150. * temporary resource limitations.
  151. * EBADF - The aio_fildes member of the aiocb structure referenced by
  152. * the aiocbp argument is not a valid file descriptor open for writing.
  153. * EINVAL - This implementation does not support synchronized I/O for
  154. * this file.
  155. * EINVAL - A value of op other than O_DSYNC or O_SYNC was specified.
  156. *
  157. * In the event that any of the queued I/O operations fail, aio_fsync()
  158. * will return the error condition defined for read() and write(). The
  159. * error is returned in the error status for the asynchronous fsync()
  160. * operation, which can be retrieved using aio_error().
  161. *
  162. * POSIX Compliance
  163. * - NuttX does not currently make any distinction between O_DYSNC and
  164. * O_SYNC. Hence, the 'op' argument is ignored altogether.
  165. * - Most errors required in the standard are not detected at this point.
  166. * There are no pre-queuing checks for the validity of the operation.
  167. *
  168. ****************************************************************************/
  169. int aio_fsync(int op, FAR struct aiocb *aiocbp)
  170. {
  171. FAR struct aio_container_s *aioc;
  172. int ret;
  173. DEBUGASSERT(op == O_SYNC); /* || op == O_DSYNC */
  174. DEBUGASSERT(aiocbp);
  175. /* The result -EINPROGRESS means that the transfer has not yet completed */
  176. sigwork_init(&aiocbp->aio_sigwork);
  177. aiocbp->aio_result = -EINPROGRESS;
  178. aiocbp->aio_priv = NULL;
  179. /* Create a container for the AIO control block. This may cause us to
  180. * block if there are insufficient resources to satisfy the request.
  181. */
  182. aioc = aio_contain(aiocbp);
  183. if (!aioc)
  184. {
  185. /* The errno has already been set (probably EBADF) */
  186. aiocbp->aio_result = -get_errno();
  187. return ERROR;
  188. }
  189. /* Defer the work to the worker thread */
  190. ret = aio_queue(aioc, aio_fsync_worker);
  191. if (ret < 0)
  192. {
  193. /* The result and the errno have already been set */
  194. aioc_decant(aioc);
  195. return ERROR;
  196. }
  197. return OK;
  198. }
  199. #endif /* CONFIG_FS_AIO */