Skip to content

Commit

Permalink
Major structure of file system functions to better support asynchrono…
Browse files Browse the repository at this point in the history
…us I/O. Respository should not be trusted until I have a chance to verify everything
  • Loading branch information
gregory-nutt committed Oct 6, 2014
1 parent 1d45f80 commit d914f3c
Show file tree
Hide file tree
Showing 33 changed files with 706 additions and 316 deletions.
5 changes: 4 additions & 1 deletion fs/aio/aio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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.
*
****************************************************************************/

Expand Down
17 changes: 12 additions & 5 deletions fs/aio/aio_fsync.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include <debug.h>

#include <nuttx/wqueue.h>
#include <nuttx/fs/fs.h>

#include "aio/aio.h"

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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 */

Expand Down
18 changes: 12 additions & 6 deletions fs/aio/aio_read.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down Expand Up @@ -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 */

Expand Down
46 changes: 34 additions & 12 deletions fs/aio/aio_write.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

#include <nuttx/config.h>

#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
#include <sched.h>
Expand Down Expand Up @@ -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
*
Expand Down Expand Up @@ -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();
Expand All @@ -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
Expand All @@ -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 */
Expand Down Expand Up @@ -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 */

Expand Down
17 changes: 16 additions & 1 deletion fs/aio/aioc_contain.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@

#include <sched.h>

#include <nuttx/fs.h>

#include "aio/aio.h"

#ifdef CONFIG_FS_AIO
Expand Down Expand Up @@ -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.
*/
Expand All @@ -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));
Expand Down
4 changes: 2 additions & 2 deletions fs/inode/fs_files.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,15 +200,15 @@ void files_releaselist(FAR struct filelist *list)
}

/****************************************************************************
* Name: files_dup
* Name: file_dup2
*
* Description:
* Assign an inode to a specific files structure. This is the heart of
* dup2.
*
****************************************************************************/

int files_dup(FAR struct file *filep1, FAR struct file *filep2)
int file_dup2(FAR struct file *filep1, FAR struct file *filep2)
{
FAR struct filelist *list;
FAR struct inode *inode;
Expand Down
8 changes: 4 additions & 4 deletions fs/vfs/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ else

# Common file/socket descriptor support

CSRCS += fs_close.c fs_dup.c fs_dup2.c fs_fcntl.c fs_filedup.c fs_filedup2.c
CSRCS += fs_fsync.c fs_ioctl.c fs_lseek.c fs_mkdir.c fs_open.c fs_poll.c
CSRCS += fs_read.c fs_rename.c fs_rmdir.c fs_stat.c fs_statfs.c fs_select.c
CSRCS += fs_unlink.c fs_write.c
CSRCS += fs_close.c fs_dup.c fs_dup2.c fs_fcntl.c fs_dupfd.c fs_dupfd2.c
CSRCS += fs_fsync.c fs_getfilep.c fs_ioctl.c fs_lseek.c fs_mkdir.c fs_open.c
CSRCS += fs_poll.c fs_read.c fs_rename.c fs_rmdir.c fs_stat.c fs_statfs.c
CSRCS += fs_select.c fs_unlink.c fs_write.c

# Support for positional file access

Expand Down
8 changes: 4 additions & 4 deletions fs/vfs/fs_dup.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@

int dup(int fd)
{
int ret = OK;
int ret = OK;

/* Check the range of the descriptor to see if we got a file or a socket
* descriptor. */
Expand All @@ -79,19 +79,19 @@ int dup(int fd)
/* Its a valid file descriptor.. dup the file descriptor using any
* other file descriptor*/

ret = file_dup(fd, 0);
ret = fs_dupfd(fd, 0);
}
else
#endif
{
/* Not a vailid file descriptor. Did we get a valid socket descriptor? */
/* Not a valid file descriptor. Did we get a valid socket descriptor? */

#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
if ((unsigned int)fd < (CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS))
{
/* Yes.. dup the socket descriptor */

ret = net_dup(fd, CONFIG_NFILE_DESCRIPTORS);
ret = net_dupsd(fd, CONFIG_NFILE_DESCRIPTORS);
}
else
#endif
Expand Down
4 changes: 2 additions & 2 deletions fs/vfs/fs_dup2.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ int dup2(int fd1, int fd2)
{
/* Yes.. dup the socket descriptor */

return net_dup2(fd1, fd2);
return net_dupsd2(fd1, fd2);
}
else
{
Expand All @@ -101,7 +101,7 @@ int dup2(int fd1, int fd2)
{
/* Its a valid file descriptor.. dup the file descriptor */

return file_dup2(fd1, fd2);
return fs_dupfd2(fd1, fd2);
}
}

Expand Down
Loading

0 comments on commit d914f3c

Please sign in to comment.