mirror of
https://github.com/apache/nuttx.git
synced 2026-05-29 04:19:37 +08:00
Major structure of file system functions to better support asynchronous I/O. Respository should not be trusted until I have a chance to verify everything
This commit is contained in:
+4
-1
@@ -67,10 +67,12 @@
|
||||
* pre-allocated, the number pre-allocated controlled by CONFIG_FS_NAIOC.
|
||||
*/
|
||||
|
||||
struct file;
|
||||
struct aio_container_s
|
||||
{
|
||||
dq_entry_t aioc_link; /* Supports a doubly linked list */
|
||||
FAR struct aiocb *aioc_aiocbp; /* The contained AIO control block */
|
||||
FAR struct file *aioc_filep; /* File structure to use with the I/O */
|
||||
struct work_s aioc_work; /* Used to defer I/O to the work thread */
|
||||
pid_t aioc_pid; /* ID of the waiting task */
|
||||
uint8_t aioc_prio; /* Priority of the waiting task */
|
||||
@@ -182,7 +184,8 @@ void aioc_free(FAR struct aio_container_s *aioc);
|
||||
* Returned Value:
|
||||
* A reference to the new AIO control block container. This function
|
||||
* will not fail but will wait if necessary for the resources to perform
|
||||
* this operation.
|
||||
* this operation. NULL will be returned on certain errors with the
|
||||
* errno value already set appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
+12
-5
@@ -46,6 +46,7 @@
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
#include "aio/aio.h"
|
||||
|
||||
@@ -103,9 +104,9 @@ static void aio_fsync_worker(FAR void *arg)
|
||||
pid = aioc->aioc_pid;
|
||||
aiocbp = aioc_decant(aioc);
|
||||
|
||||
/* Perform the fsync using aio_fildes */
|
||||
/* Perform the fsync using aioc_filep */
|
||||
|
||||
ret = fsync(aiocbp->aio_fildes);
|
||||
ret = file_fsync(aioc->aioc_filep);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = get_errno();
|
||||
@@ -218,12 +219,18 @@ int aio_fsync(int op, FAR struct aiocb *aiocbp)
|
||||
aiocbp->aio_result = -EINPROGRESS;
|
||||
aiocbp->aio_priv = NULL;
|
||||
|
||||
/* Create a container for the AIO control block. This will not fail but
|
||||
* may cause us to block if there are insufficient resources to satisfy
|
||||
* the request.
|
||||
/* Create a container for the AIO control block. This may cause us to
|
||||
* block if there are insufficient resources to satisfy the request.
|
||||
*/
|
||||
|
||||
aioc = aio_contain(aiocbp);
|
||||
if (!aioc)
|
||||
{
|
||||
/* The errno has already been set (probably EBADF) */
|
||||
|
||||
aiocbp->aio_result = -get_errno();
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Defer the work to the worker thread */
|
||||
|
||||
|
||||
+12
-6
@@ -106,14 +106,14 @@ static void aio_read_worker(FAR void *arg)
|
||||
|
||||
/* Perform the read using:
|
||||
*
|
||||
* aio_fildes - File descriptor
|
||||
* aioc_filep - File structure pointer
|
||||
* aio_buf - Location of buffer
|
||||
* aio_nbytes - Length of transfer
|
||||
* aio_offset - File offset
|
||||
*/
|
||||
|
||||
nread = pread(aiocbp->aio_fildes, (FAR void *)aiocbp->aio_buf,
|
||||
aiocbp->aio_nbytes, aiocbp->aio_offset);
|
||||
nread = file_pread(aioc->aioc_filep, (FAR void *)aiocbp->aio_buf,
|
||||
aiocbp->aio_nbytes, aiocbp->aio_offset);
|
||||
|
||||
/* Set the result of the read */
|
||||
|
||||
@@ -266,12 +266,18 @@ int aio_read(FAR struct aiocb *aiocbp)
|
||||
aiocbp->aio_result = -EINPROGRESS;
|
||||
aiocbp->aio_priv = NULL;
|
||||
|
||||
/* Create a container for the AIO control block. This will not fail but
|
||||
* may cause us to block if there are insufficient resources to satisfy
|
||||
* the request.
|
||||
/* Create a container for the AIO control block. This may cause us to
|
||||
* block if there are insufficient resources to satisfy the request.
|
||||
*/
|
||||
|
||||
aioc = aio_contain(aiocbp);
|
||||
if (!aioc)
|
||||
{
|
||||
/* The errno has already been set (probably EBADF) */
|
||||
|
||||
aiocbp->aio_result = -get_errno();
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Defer the work to the worker thread */
|
||||
|
||||
|
||||
+34
-12
@@ -39,6 +39,7 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sched.h>
|
||||
@@ -73,6 +74,21 @@
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: file_fcntl
|
||||
****************************************************************************/
|
||||
|
||||
static inline int file_fcntl(FAR struct file *filep, int cmd, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start(ap, cmd);
|
||||
ret = file_vfcntl(filep, cmd, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: aio_write_worker
|
||||
*
|
||||
@@ -108,7 +124,7 @@ static void aio_write_worker(FAR void *arg)
|
||||
|
||||
/* Call fcntl(F_GETFL) to get the file open mode. */
|
||||
|
||||
oflags = fcntl(aiocbp->aio_fildes, F_GETFL);
|
||||
oflags = file_fcntl(aioc->aioc_filep, F_GETFL);
|
||||
if (oflags < 0)
|
||||
{
|
||||
int errcode = get_errno();
|
||||
@@ -119,7 +135,7 @@ static void aio_write_worker(FAR void *arg)
|
||||
{
|
||||
/* Perform the write using:
|
||||
*
|
||||
* aio_fildes - File descriptor
|
||||
* aioc_filep - File descriptor
|
||||
* aio_buf - Location of buffer
|
||||
* aio_nbytes - Length of transfer
|
||||
* aio_offset - File offset
|
||||
@@ -131,16 +147,16 @@ static void aio_write_worker(FAR void *arg)
|
||||
{
|
||||
/* Append to the current file position */
|
||||
|
||||
nwritten = write(aiocbp->aio_fildes,
|
||||
(FAR const void *)aiocbp->aio_buf,
|
||||
aiocbp->aio_nbytes);
|
||||
nwritten = file_write(aioc->aioc_filep,
|
||||
(FAR const void *)aiocbp->aio_buf,
|
||||
aiocbp->aio_nbytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
nwritten = pwrite(aiocbp->aio_fildes,
|
||||
(FAR const void *)aiocbp->aio_buf,
|
||||
aiocbp->aio_nbytes,
|
||||
aiocbp->aio_offset);
|
||||
nwritten = file_pwrite(aioc->aioc_filep,
|
||||
(FAR const void *)aiocbp->aio_buf,
|
||||
aiocbp->aio_nbytes,
|
||||
aiocbp->aio_offset);
|
||||
}
|
||||
|
||||
/* Set the result of the write */
|
||||
@@ -297,12 +313,18 @@ int aio_write(FAR struct aiocb *aiocbp)
|
||||
aiocbp->aio_result = -EINPROGRESS;
|
||||
aiocbp->aio_priv = NULL;
|
||||
|
||||
/* Create a container for the AIO control block. This will not fail but
|
||||
* may cause us to block if there are insufficient resources to satisfy
|
||||
* the request.
|
||||
/* Create a container for the AIO control block. This may cause us to
|
||||
* block if there are insufficient resources to satisfy the request.
|
||||
*/
|
||||
|
||||
aioc = aio_contain(aiocbp);
|
||||
if (!aioc)
|
||||
{
|
||||
/* The errno has already been set (probably EBADF) */
|
||||
|
||||
aiocbp->aio_result = -get_errno();
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Defer the work to the worker thread */
|
||||
|
||||
|
||||
+16
-1
@@ -41,6 +41,8 @@
|
||||
|
||||
#include <sched.h>
|
||||
|
||||
#include <nuttx/fs.h>
|
||||
|
||||
#include "aio/aio.h"
|
||||
|
||||
#ifdef CONFIG_FS_AIO
|
||||
@@ -80,15 +82,27 @@
|
||||
* Returned Value:
|
||||
* A reference to the new AIO control block container. This function
|
||||
* will not fail but will wait if necessary for the resources to perform
|
||||
* this operation.
|
||||
* this operation. NULL will be returned on certain errors with the
|
||||
* errno value already set appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct aio_container_s *aio_contain(FAR struct aiocb *aiocbp)
|
||||
{
|
||||
FAR struct aio_container_s *aioc;
|
||||
FAR struct file *filep;
|
||||
struct sched_param param;
|
||||
|
||||
/* Get the file structure corresponding to the file descriptor. */
|
||||
|
||||
filep = fs_getfilep(aiocbp->aio_fildes);
|
||||
if (!filep)
|
||||
{
|
||||
/* The errno value has already been set */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate the AIO control block container, waiting for one to become
|
||||
* available if necessary. This should never fail.
|
||||
*/
|
||||
@@ -100,6 +114,7 @@ FAR struct aio_container_s *aio_contain(FAR struct aiocb *aiocbp)
|
||||
|
||||
memset(aioc, 0, sizeof(struct aio_container_s));
|
||||
aioc->aioc_aiocbp = aiocbp;
|
||||
aioc->aioc_filep = filep;
|
||||
aioc->aioc_pid = getpid();
|
||||
|
||||
DEBUGVERIFY(sched_getparam (aioc->aioc_pid, ¶m));
|
||||
|
||||
Reference in New Issue
Block a user