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:
Gregory Nutt
2014-10-06 10:53:25 -06:00
parent 1d45f80a9b
commit d914f3ceec
33 changed files with 731 additions and 341 deletions
+4 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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, &param));