[PATCH 2/3] Filesystem: Add readv/writev handlers

Sebastian Huber sebastian.huber at embedded-brains.de
Mon Dec 16 13:29:05 UTC 2013


The readv() and writev() support was implemented in terms of single
calls to the read and write handlers.  This imposes a problem on device
files which use an IO vector as single request entity.  For example a
low-level network device (e.g. BPF(4)) may use an IO vector to create
one frame from multiple protocol layers each with its own IO vector
entry.
---
 c/src/lib/libbsp/shared/umon/tfsDriver.c        |    4 +-
 cpukit/libblock/src/blkdev-imfs.c               |    4 +-
 cpukit/libcsupport/include/rtems/libio.h        |   73 +++++++++++++++++++++++
 cpukit/libcsupport/src/__usrenv.c               |    4 +-
 cpukit/libcsupport/src/readv.c                  |   21 +------
 cpukit/libcsupport/src/writev.c                 |   21 +------
 cpukit/libfs/Makefile.am                        |    2 +
 cpukit/libfs/src/defaults/default_handlers.c    |    4 +-
 cpukit/libfs/src/defaults/default_readv.c       |   60 +++++++++++++++++++
 cpukit/libfs/src/defaults/default_writev.c      |   60 +++++++++++++++++++
 cpukit/libfs/src/devfs/devfs_init.c             |    4 +-
 cpukit/libfs/src/dosfs/msdos_handlers_dir.c     |   24 ++++----
 cpukit/libfs/src/dosfs/msdos_handlers_file.c    |   24 ++++----
 cpukit/libfs/src/imfs/imfs_fifo.c               |   24 ++++----
 cpukit/libfs/src/imfs/imfs_handlers_device.c    |   24 ++++----
 cpukit/libfs/src/imfs/imfs_handlers_directory.c |   24 ++++----
 cpukit/libfs/src/imfs/imfs_handlers_link.c      |   24 ++++----
 cpukit/libfs/src/imfs/imfs_handlers_memfile.c   |   24 ++++----
 cpukit/libfs/src/jffs2/src/fs-rtems.c           |   12 +++-
 cpukit/libfs/src/nfsclient/src/nfs.c            |   12 +++-
 cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c      |    4 +-
 cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c      |    4 +-
 cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c     |    4 +-
 cpukit/libfs/src/rfs/rtems-rfs-rtems.c          |    4 +-
 cpukit/libnetworking/lib/ftpfs.c                |    8 ++-
 cpukit/libnetworking/lib/tftpDriver.c           |    4 +-
 cpukit/libnetworking/rtems/rtems_syscall.c      |   24 ++++----
 testsuites/fstests/fsimfsgeneric01/init.c       |   49 +++++++++++++++-
 28 files changed, 402 insertions(+), 148 deletions(-)
 create mode 100644 cpukit/libfs/src/defaults/default_readv.c
 create mode 100644 cpukit/libfs/src/defaults/default_writev.c

diff --git a/c/src/lib/libbsp/shared/umon/tfsDriver.c b/c/src/lib/libbsp/shared/umon/tfsDriver.c
index 20e5883..41c5809 100644
--- a/c/src/lib/libbsp/shared/umon/tfsDriver.c
+++ b/c/src/lib/libbsp/shared/umon/tfsDriver.c
@@ -675,5 +675,7 @@ static const rtems_filesystem_file_handlers_r rtems_tfs_handlers = {
   .ftruncate_h = rtems_tfs_ftruncate,
   .fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
-  .fcntl_h = rtems_filesystem_default_fcntl
+  .fcntl_h = rtems_filesystem_default_fcntl,
+  .readv_h = rtems_filesystem_default_readv,
+  .writev_h = rtems_filesystem_default_writev
 };
diff --git a/cpukit/libblock/src/blkdev-imfs.c b/cpukit/libblock/src/blkdev-imfs.c
index 256f90c..48d5515 100644
--- a/cpukit/libblock/src/blkdev-imfs.c
+++ b/cpukit/libblock/src/blkdev-imfs.c
@@ -220,7 +220,9 @@ static const rtems_filesystem_file_handlers_r rtems_blkdev_imfs_node = {
   .ftruncate_h = rtems_filesystem_default_ftruncate,
   .fsync_h = rtems_blkdev_imfs_fsync_or_fdatasync,
   .fdatasync_h = rtems_blkdev_imfs_fsync_or_fdatasync,
-  .fcntl_h = rtems_filesystem_default_fcntl
+  .fcntl_h = rtems_filesystem_default_fcntl,
+  .readv_h = rtems_filesystem_default_readv,
+  .writev_h = rtems_filesystem_default_writev
 };
 
 static IMFS_jnode_t *rtems_blkdev_imfs_initialize(
diff --git a/cpukit/libcsupport/include/rtems/libio.h b/cpukit/libcsupport/include/rtems/libio.h
index 21d57eb..4bfa02a 100644
--- a/cpukit/libcsupport/include/rtems/libio.h
+++ b/cpukit/libcsupport/include/rtems/libio.h
@@ -29,6 +29,7 @@
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <sys/statvfs.h>
+#include <sys/uio.h>
 
 #include <unistd.h>
 #include <termios.h>
@@ -808,6 +809,29 @@ typedef ssize_t (*rtems_filesystem_read_t)(
 );
 
 /**
+ * @brief Reads an IO vector from a node.
+ *
+ * This handler is responsible to update the offset field of the IO descriptor.
+ *
+ * @param[in, out] iop The IO pointer.
+ * @param[in] iov The IO vector with buffer for read data.  The caller must
+ * ensure that the IO vector values are valid.
+ * @param[in] iovcnt The count of buffers in the IO vector.
+ * @param[in] total The total count of bytes in the buffers in the IO vector.
+ *
+ * @retval non-negative Count of read characters.
+ * @retval -1 An error occurred.  The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_readv().
+ */
+typedef ssize_t (*rtems_filesystem_readv_t)(
+  rtems_libio_t      *iop,
+  const struct iovec *iov,
+  int                 iovcnt,
+  ssize_t             total
+);
+
+/**
  * @brief Writes to a node.
  *
  * This handler is responsible to update the offset field of the IO descriptor.
@@ -828,6 +852,29 @@ typedef ssize_t (*rtems_filesystem_write_t)(
 );
 
 /**
+ * @brief Writes an IO vector to a node.
+ *
+ * This handler is responsible to update the offset field of the IO descriptor.
+ *
+ * @param[in, out] iop The IO pointer.
+ * @param[in] iov The IO vector with buffer for write data.  The caller must
+ * ensure that the IO vector values are valid.
+ * @param[in] iovcnt The count of buffers in the IO vector.
+ * @param[in] total The total count of bytes in the buffers in the IO vector.
+ *
+ * @retval non-negative Count of written characters.
+ * @retval -1 An error occurred.  The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_writev().
+ */
+typedef ssize_t (*rtems_filesystem_writev_t)(
+  rtems_libio_t      *iop,
+  const struct iovec *iov,
+  int                 iovcnt,
+  ssize_t             total
+);
+
+/**
  * @brief IO control of a node.
  *
  * @param[in, out] iop The IO pointer.
@@ -992,6 +1039,8 @@ struct _rtems_filesystem_file_handlers_r {
   rtems_filesystem_fcntl_t fcntl_h;
   rtems_filesystem_poll_t poll_h;
   rtems_filesystem_kqfilter_t kqfilter_h;
+  rtems_filesystem_readv_t readv_h;
+  rtems_filesystem_writev_t writev_h;
 };
 
 /**
@@ -1033,6 +1082,18 @@ ssize_t rtems_filesystem_default_read(
 );
 
 /**
+ * @brief Calls the read handler for each IO vector entry.
+ *
+ * @see rtems_filesystem_readv_t.
+ */
+ssize_t rtems_filesystem_default_readv(
+  rtems_libio_t      *iop,
+  const struct iovec *iov,
+  int                 iovcnt,
+  ssize_t             total
+);
+
+/**
  * @retval -1 Always.  The errno is set to ENOTSUP.
  *
  * @see rtems_filesystem_write_t.
@@ -1044,6 +1105,18 @@ ssize_t rtems_filesystem_default_write(
 );
 
 /**
+ * @brief Calls the write handler for each IO vector entry.
+ *
+ * @see rtems_filesystem_write_t.
+ */
+ssize_t rtems_filesystem_default_writev(
+  rtems_libio_t      *iop,
+  const struct iovec *iov,
+  int                 iovcnt,
+  ssize_t             total
+);
+
+/**
  * @retval -1 Always.  The errno is set to ENOTTY.
  *
  * @see rtems_filesystem_ioctl_t.
diff --git a/cpukit/libcsupport/src/__usrenv.c b/cpukit/libcsupport/src/__usrenv.c
index 88058c4..f860447 100644
--- a/cpukit/libcsupport/src/__usrenv.c
+++ b/cpukit/libcsupport/src/__usrenv.c
@@ -54,7 +54,9 @@ const rtems_filesystem_file_handlers_r rtems_filesystem_null_handlers = {
   .ftruncate_h = rtems_filesystem_default_ftruncate,
   .fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
-  .fcntl_h = rtems_filesystem_default_fcntl
+  .fcntl_h = rtems_filesystem_default_fcntl,
+  .readv_h = rtems_filesystem_default_readv,
+  .writev_h = rtems_filesystem_default_writev
 };
 
 static void null_op_lock_or_unlock(
diff --git a/cpukit/libcsupport/src/readv.c b/cpukit/libcsupport/src/readv.c
index 2400834..9720afd 100644
--- a/cpukit/libcsupport/src/readv.c
+++ b/cpukit/libcsupport/src/readv.c
@@ -36,31 +36,12 @@ ssize_t readv(
 )
 {
   ssize_t        total;
-  int            v;
   rtems_libio_t *iop;
 
   total = rtems_libio_iovec_eval( fd, iov, iovcnt, LIBIO_FLAGS_READ, &iop );
 
   if ( total >= 0 ) {
-    /*
-     *  Now process the readv().
-     */
-    total = 0;
-    for ( v = 0 ; v < iovcnt ; v++ ) {
-      ssize_t bytes = ( *iop->pathinfo.handlers->read_h )(
-        iop,
-        iov[ v ].iov_base,
-        iov[ v ].iov_len
-      );
-
-      if ( bytes < 0 )
-        return -1;
-
-      total += bytes;
-
-      if ( bytes != iov[ v ].iov_len )
-        break;
-    }
+    total = ( *iop->pathinfo.handlers->readv_h )( iop, iov, iovcnt, total );
   }
 
   return total;
diff --git a/cpukit/libcsupport/src/writev.c b/cpukit/libcsupport/src/writev.c
index 1c7caf1..c6d1274 100644
--- a/cpukit/libcsupport/src/writev.c
+++ b/cpukit/libcsupport/src/writev.c
@@ -28,31 +28,12 @@ ssize_t writev(
 )
 {
   ssize_t        total;
-  int            v;
   rtems_libio_t *iop;
 
   total = rtems_libio_iovec_eval( fd, iov, iovcnt, LIBIO_FLAGS_WRITE, &iop );
 
   if ( total >= 0 ) {
-    /*
-     *  Now process the writev().
-     */
-    total = 0;
-    for ( v = 0 ; v < iovcnt ; v++ ) {
-      ssize_t bytes = ( *iop->pathinfo.handlers->write_h )(
-        iop,
-        iov[ v ].iov_base,
-        iov[ v ].iov_len
-      );
-
-      if ( bytes < 0 )
-        return -1;
-
-      total += bytes;
-
-      if ( bytes != iov[ v ].iov_len )
-        break;
-    }
+    total = ( *iop->pathinfo.handlers->writev_h )( iop, iov, iovcnt, total );
   }
 
   return total;
diff --git a/cpukit/libfs/Makefile.am b/cpukit/libfs/Makefile.am
index 21bb7ef..b8c7790 100644
--- a/cpukit/libfs/Makefile.am
+++ b/cpukit/libfs/Makefile.am
@@ -35,6 +35,8 @@ libdefaultfs_a_SOURCES = \
     src/defaults/default_handlers.c src/defaults/default_ops.c
 libdefaultfs_a_SOURCES += src/defaults/default_kqfilter.c
 libdefaultfs_a_SOURCES += src/defaults/default_poll.c
+libdefaultfs_a_SOURCES += src/defaults/default_readv.c
+libdefaultfs_a_SOURCES += src/defaults/default_writev.c
 
 noinst_LIBRARIES += libimfs.a
 libimfs_a_SOURCES =
diff --git a/cpukit/libfs/src/defaults/default_handlers.c b/cpukit/libfs/src/defaults/default_handlers.c
index 2a10a19..ce262b6 100644
--- a/cpukit/libfs/src/defaults/default_handlers.c
+++ b/cpukit/libfs/src/defaults/default_handlers.c
@@ -32,5 +32,7 @@ const rtems_filesystem_file_handlers_r rtems_filesystem_handlers_default = {
   .ftruncate_h = rtems_filesystem_default_ftruncate,
   .fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
-  .fcntl_h = rtems_filesystem_default_fcntl
+  .fcntl_h = rtems_filesystem_default_fcntl,
+  .readv_h = rtems_filesystem_default_readv,
+  .writev_h = rtems_filesystem_default_writev
 };
diff --git a/cpukit/libfs/src/defaults/default_readv.c b/cpukit/libfs/src/defaults/default_readv.c
new file mode 100644
index 0000000..eb09e60
--- /dev/null
+++ b/cpukit/libfs/src/defaults/default_readv.c
@@ -0,0 +1,60 @@
+/**
+ * @file
+ *
+ * @brief Default Read IO Vector Handler
+ *
+ * @ingroup LibIOFSHandler
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems/libio_.h>
+
+int rtems_filesystem_default_readv(
+  rtems_libio_t      *iop,
+  const struct iovec *iov,
+  int                 iovcnt,
+  ssize_t             total
+)
+{
+  int v;
+
+  total = 0;
+
+  for ( v = 0 ; v < iovcnt ; v++ ) {
+    ssize_t bytes = ( *iop->pathinfo.handlers->read_h )(
+      iop,
+      iov[ v ].iov_base,
+      iov[ v ].iov_len
+    );
+
+    if ( bytes < 0 )
+      return -1;
+
+    total += bytes;
+
+    if ( bytes != iov[ v ].iov_len )
+      break;
+  }
+
+  return total;
+}
diff --git a/cpukit/libfs/src/defaults/default_writev.c b/cpukit/libfs/src/defaults/default_writev.c
new file mode 100644
index 0000000..abac0b8
--- /dev/null
+++ b/cpukit/libfs/src/defaults/default_writev.c
@@ -0,0 +1,60 @@
+/**
+ * @file
+ *
+ * @brief Default Read IO Vector Handler
+ *
+ * @ingroup LibIOFSHandler
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems/libio_.h>
+
+int rtems_filesystem_default_writev(
+  rtems_libio_t      *iop,
+  const struct iovec *iov,
+  int                 iovcnt,
+  ssize_t             total
+)
+{
+  int v;
+
+  total = 0;
+
+  for ( v = 0 ; v < iovcnt ; v++ ) {
+    ssize_t bytes = ( *iop->pathinfo.handlers->write_h )(
+      iop,
+      iov[ v ].iov_base,
+      iov[ v ].iov_len
+    );
+
+    if ( bytes < 0 )
+      return -1;
+
+    total += bytes;
+
+    if ( bytes != iov[ v ].iov_len )
+      break;
+  }
+
+  return total;
+}
diff --git a/cpukit/libfs/src/devfs/devfs_init.c b/cpukit/libfs/src/devfs/devfs_init.c
index e0dbe2f..4aa9f93 100644
--- a/cpukit/libfs/src/devfs/devfs_init.c
+++ b/cpukit/libfs/src/devfs/devfs_init.c
@@ -52,7 +52,9 @@ const rtems_filesystem_file_handlers_r devFS_file_handlers = {
   .ftruncate_h = rtems_filesystem_default_ftruncate,
   .fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
-  .fcntl_h = rtems_filesystem_default_fcntl
+  .fcntl_h = rtems_filesystem_default_fcntl,
+  .readv_h = rtems_filesystem_default_readv,
+  .writev_h = rtems_filesystem_default_writev
 };
 
 int devFS_initialize(
diff --git a/cpukit/libfs/src/dosfs/msdos_handlers_dir.c b/cpukit/libfs/src/dosfs/msdos_handlers_dir.c
index 41efdb4..6d91603 100644
--- a/cpukit/libfs/src/dosfs/msdos_handlers_dir.c
+++ b/cpukit/libfs/src/dosfs/msdos_handlers_dir.c
@@ -22,15 +22,17 @@
 #include "msdos.h"
 
 const rtems_filesystem_file_handlers_r msdos_dir_handlers = {
-    rtems_filesystem_default_open,
-    rtems_filesystem_default_close,
-    msdos_dir_read,
-    rtems_filesystem_default_write,
-    rtems_filesystem_default_ioctl,
-    rtems_filesystem_default_lseek_directory,
-    msdos_dir_stat,
-    rtems_filesystem_default_ftruncate_directory,
-    msdos_sync,
-    msdos_sync,
-    rtems_filesystem_default_fcntl
+  .open_h = rtems_filesystem_default_open,
+  .close_h = rtems_filesystem_default_close,
+  .read_h = msdos_dir_read,
+  .write_h = rtems_filesystem_default_write,
+  .ioctl_h = rtems_filesystem_default_ioctl,
+  .lseek_h = rtems_filesystem_default_lseek_directory,
+  .fstat_h = msdos_dir_stat,
+  .ftruncate_h = rtems_filesystem_default_ftruncate_directory,
+  .fsync_h = msdos_sync,
+  .fdatasync_h = msdos_sync,
+  .fcntl_h = rtems_filesystem_default_fcntl,
+  .readv_h = rtems_filesystem_default_readv,
+  .writev_h = rtems_filesystem_default_writev
 };
diff --git a/cpukit/libfs/src/dosfs/msdos_handlers_file.c b/cpukit/libfs/src/dosfs/msdos_handlers_file.c
index 2a3938d..d5885bb 100644
--- a/cpukit/libfs/src/dosfs/msdos_handlers_file.c
+++ b/cpukit/libfs/src/dosfs/msdos_handlers_file.c
@@ -22,15 +22,17 @@
 #include "msdos.h"
 
 const rtems_filesystem_file_handlers_r msdos_file_handlers = {
-    rtems_filesystem_default_open,
-    msdos_file_close,
-    msdos_file_read,
-    msdos_file_write,
-    rtems_filesystem_default_ioctl,
-    rtems_filesystem_default_lseek_file,
-    msdos_file_stat,
-    msdos_file_ftruncate,
-    msdos_file_sync,
-    msdos_sync,
-    rtems_filesystem_default_fcntl
+  .open_h = rtems_filesystem_default_open,
+  .close_h = msdos_file_close,
+  .read_h = msdos_file_read,
+  .write_h = msdos_file_write,
+  .ioctl_h = rtems_filesystem_default_ioctl,
+  .lseek_h = rtems_filesystem_default_lseek_file,
+  .fstat_h = msdos_file_stat,
+  .ftruncate_h = msdos_file_ftruncate,
+  .fsync_h = msdos_file_sync,
+  .fdatasync_h = msdos_sync,
+  .fcntl_h = rtems_filesystem_default_fcntl,
+  .readv_h = rtems_filesystem_default_readv,
+  .writev_h = rtems_filesystem_default_writev
 };
diff --git a/cpukit/libfs/src/imfs/imfs_fifo.c b/cpukit/libfs/src/imfs/imfs_fifo.c
index 03e6936..743261a 100644
--- a/cpukit/libfs/src/imfs/imfs_fifo.c
+++ b/cpukit/libfs/src/imfs/imfs_fifo.c
@@ -113,17 +113,19 @@ static int IMFS_fifo_ioctl(
 }
 
 static const rtems_filesystem_file_handlers_r IMFS_fifo_handlers = {
-  IMFS_fifo_open,
-  IMFS_fifo_close,
-  IMFS_fifo_read,
-  IMFS_fifo_write,
-  IMFS_fifo_ioctl,
-  rtems_filesystem_default_lseek,
-  IMFS_stat,
-  rtems_filesystem_default_ftruncate,
-  rtems_filesystem_default_fsync_or_fdatasync,
-  rtems_filesystem_default_fsync_or_fdatasync,
-  rtems_filesystem_default_fcntl
+  .open_h = IMFS_fifo_open,
+  .close_h = IMFS_fifo_close,
+  .read_h = IMFS_fifo_read,
+  .write_h = IMFS_fifo_write,
+  .ioctl_h = IMFS_fifo_ioctl,
+  .lseek_h = rtems_filesystem_default_lseek,
+  .fstat_h = IMFS_stat,
+  .ftruncate_h = rtems_filesystem_default_ftruncate,
+  .fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
+  .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
+  .fcntl_h = rtems_filesystem_default_fcntl,
+  .readv_h = rtems_filesystem_default_readv,
+  .writev_h = rtems_filesystem_default_writev
 };
 
 const IMFS_node_control IMFS_node_control_fifo = {
diff --git a/cpukit/libfs/src/imfs/imfs_handlers_device.c b/cpukit/libfs/src/imfs/imfs_handlers_device.c
index 899b3dc..451e201 100644
--- a/cpukit/libfs/src/imfs/imfs_handlers_device.c
+++ b/cpukit/libfs/src/imfs/imfs_handlers_device.c
@@ -34,17 +34,19 @@ static int IMFS_stat_device(
 }
 
 static const rtems_filesystem_file_handlers_r IMFS_device_handlers = {
-  device_open,
-  device_close,
-  device_read,
-  device_write,
-  device_ioctl,
-  rtems_filesystem_default_lseek_file,
-  IMFS_stat_device,
-  device_ftruncate,
-  rtems_filesystem_default_fsync_or_fdatasync,
-  rtems_filesystem_default_fsync_or_fdatasync,
-  rtems_filesystem_default_fcntl
+  .open_h = device_open,
+  .close_h = device_close,
+  .read_h = device_read,
+  .write_h = device_write,
+  .ioctl_h = device_ioctl,
+  .lseek_h = rtems_filesystem_default_lseek_file,
+  .fstat_h = IMFS_stat_device,
+  .ftruncate_h = device_ftruncate,
+  .fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
+  .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
+  .fcntl_h = rtems_filesystem_default_fcntl,
+  .readv_h = rtems_filesystem_default_readv,
+  .writev_h = rtems_filesystem_default_writev
 };
 
 static IMFS_jnode_t *IMFS_node_initialize_device(
diff --git a/cpukit/libfs/src/imfs/imfs_handlers_directory.c b/cpukit/libfs/src/imfs/imfs_handlers_directory.c
index 61ca552..ab267d7 100644
--- a/cpukit/libfs/src/imfs/imfs_handlers_directory.c
+++ b/cpukit/libfs/src/imfs/imfs_handlers_directory.c
@@ -50,17 +50,19 @@ static int IMFS_stat_directory(
 }
 
 static const rtems_filesystem_file_handlers_r IMFS_directory_handlers = {
-  rtems_filesystem_default_open,
-  rtems_filesystem_default_close,
-  imfs_dir_read,
-  rtems_filesystem_default_write,
-  rtems_filesystem_default_ioctl,
-  rtems_filesystem_default_lseek_directory,
-  IMFS_stat_directory,
-  rtems_filesystem_default_ftruncate_directory,
-  rtems_filesystem_default_fsync_or_fdatasync_success,
-  rtems_filesystem_default_fsync_or_fdatasync_success,
-  rtems_filesystem_default_fcntl
+  .open_h = rtems_filesystem_default_open,
+  .close_h = rtems_filesystem_default_close,
+  .read_h = imfs_dir_read,
+  .write_h = rtems_filesystem_default_write,
+  .ioctl_h = rtems_filesystem_default_ioctl,
+  .lseek_h = rtems_filesystem_default_lseek_directory,
+  .fstat_h = IMFS_stat_directory,
+  .ftruncate_h = rtems_filesystem_default_ftruncate_directory,
+  .fsync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
+  .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
+  .fcntl_h = rtems_filesystem_default_fcntl,
+  .readv_h = rtems_filesystem_default_readv,
+  .writev_h = rtems_filesystem_default_writev
 };
 
 static IMFS_jnode_t *IMFS_node_initialize_directory(
diff --git a/cpukit/libfs/src/imfs/imfs_handlers_link.c b/cpukit/libfs/src/imfs/imfs_handlers_link.c
index 5118eb5..00f09fc 100644
--- a/cpukit/libfs/src/imfs/imfs_handlers_link.c
+++ b/cpukit/libfs/src/imfs/imfs_handlers_link.c
@@ -45,17 +45,19 @@ static int IMFS_stat_link(
 }
 
 static const rtems_filesystem_file_handlers_r IMFS_link_handlers = {
-  rtems_filesystem_default_open,
-  rtems_filesystem_default_close,
-  rtems_filesystem_default_read,
-  rtems_filesystem_default_write,
-  rtems_filesystem_default_ioctl,
-  rtems_filesystem_default_lseek,
-  IMFS_stat_link,
-  rtems_filesystem_default_ftruncate,
-  rtems_filesystem_default_fsync_or_fdatasync,
-  rtems_filesystem_default_fsync_or_fdatasync,
-  rtems_filesystem_default_fcntl
+  .open_h = rtems_filesystem_default_open,
+  .close_h = rtems_filesystem_default_close,
+  .read_h = rtems_filesystem_default_read,
+  .write_h = rtems_filesystem_default_write,
+  .ioctl_h = rtems_filesystem_default_ioctl,
+  .lseek_h = rtems_filesystem_default_lseek,
+  .fstat_h = IMFS_stat_link,
+  .ftruncate_h = rtems_filesystem_default_ftruncate,
+  .fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
+  .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
+  .fcntl_h = rtems_filesystem_default_fcntl,
+  .readv_h = rtems_filesystem_default_readv,
+  .writev_h = rtems_filesystem_default_writev
 };
 
 static IMFS_jnode_t *IMFS_node_initialize_hard_link(
diff --git a/cpukit/libfs/src/imfs/imfs_handlers_memfile.c b/cpukit/libfs/src/imfs/imfs_handlers_memfile.c
index d0c5912..44ed856 100644
--- a/cpukit/libfs/src/imfs/imfs_handlers_memfile.c
+++ b/cpukit/libfs/src/imfs/imfs_handlers_memfile.c
@@ -34,17 +34,19 @@ static int IMFS_stat_file(
 }
 
 static const rtems_filesystem_file_handlers_r IMFS_memfile_handlers = {
-  memfile_open,
-  rtems_filesystem_default_close,
-  memfile_read,
-  memfile_write,
-  rtems_filesystem_default_ioctl,
-  rtems_filesystem_default_lseek_file,
-  IMFS_stat_file,
-  memfile_ftruncate,
-  rtems_filesystem_default_fsync_or_fdatasync_success,
-  rtems_filesystem_default_fsync_or_fdatasync_success,
-  rtems_filesystem_default_fcntl
+  .open_h = memfile_open,
+  .close_h = rtems_filesystem_default_close,
+  .read_h = memfile_read,
+  .write_h = memfile_write,
+  .ioctl_h = rtems_filesystem_default_ioctl,
+  .lseek_h = rtems_filesystem_default_lseek_file,
+  .fstat_h = IMFS_stat_file,
+  .ftruncate_h = memfile_ftruncate,
+  .fsync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
+  .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
+  .fcntl_h = rtems_filesystem_default_fcntl,
+  .readv_h = rtems_filesystem_default_readv,
+  .writev_h = rtems_filesystem_default_writev
 };
 
 const IMFS_node_control IMFS_node_control_memfile = {
diff --git a/cpukit/libfs/src/jffs2/src/fs-rtems.c b/cpukit/libfs/src/jffs2/src/fs-rtems.c
index 1b7d719..c8d6b9b 100644
--- a/cpukit/libfs/src/jffs2/src/fs-rtems.c
+++ b/cpukit/libfs/src/jffs2/src/fs-rtems.c
@@ -516,7 +516,9 @@ static const rtems_filesystem_file_handlers_r rtems_jffs2_directory_handlers = {
 	.ftruncate_h = rtems_filesystem_default_ftruncate_directory,
 	.fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
 	.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
-	.fcntl_h = rtems_filesystem_default_fcntl
+	.fcntl_h = rtems_filesystem_default_fcntl,
+	.readv_h = rtems_filesystem_default_readv,
+	.writev_h = rtems_filesystem_default_writev
 };
 
 static ssize_t rtems_jffs2_file_read(rtems_libio_t *iop, void *buf, size_t len)
@@ -654,7 +656,9 @@ static const rtems_filesystem_file_handlers_r rtems_jffs2_file_handlers = {
 	.ftruncate_h = rtems_jffs2_file_ftruncate,
 	.fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
 	.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
-	.fcntl_h = rtems_filesystem_default_fcntl
+	.fcntl_h = rtems_filesystem_default_fcntl,
+	.readv_h = rtems_filesystem_default_readv,
+	.writev_h = rtems_filesystem_default_writev
 };
 
 static const rtems_filesystem_file_handlers_r rtems_jffs2_link_handlers = {
@@ -668,7 +672,9 @@ static const rtems_filesystem_file_handlers_r rtems_jffs2_link_handlers = {
 	.ftruncate_h = rtems_filesystem_default_ftruncate,
 	.fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
 	.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
-	.fcntl_h = rtems_filesystem_default_fcntl
+	.fcntl_h = rtems_filesystem_default_fcntl,
+	.readv_h = rtems_filesystem_default_readv,
+	.writev_h = rtems_filesystem_default_writev
 };
 
 static void rtems_jffs2_set_location(rtems_filesystem_location_info_t *loc, struct _inode *inode)
diff --git a/cpukit/libfs/src/nfsclient/src/nfs.c b/cpukit/libfs/src/nfsclient/src/nfs.c
index 99e34d5..c249522 100644
--- a/cpukit/libfs/src/nfsclient/src/nfs.c
+++ b/cpukit/libfs/src/nfsclient/src/nfs.c
@@ -2869,7 +2869,9 @@ struct _rtems_filesystem_file_handlers_r nfs_file_file_handlers = {
 	.ftruncate_h = nfs_file_ftruncate,
 	.fsync_h     = rtems_filesystem_default_fsync_or_fdatasync,
 	.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
-	.fcntl_h     = rtems_filesystem_default_fcntl
+	.fcntl_h     = rtems_filesystem_default_fcntl,
+	.readv_h     = rtems_filesystem_default_readv,
+	.writev_h    = rtems_filesystem_default_writev
 };
 
 /* the directory handlers table */
@@ -2885,7 +2887,9 @@ struct _rtems_filesystem_file_handlers_r nfs_dir_file_handlers = {
 	.ftruncate_h = rtems_filesystem_default_ftruncate_directory,
 	.fsync_h     = rtems_filesystem_default_fsync_or_fdatasync,
 	.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
-	.fcntl_h     = rtems_filesystem_default_fcntl
+	.fcntl_h     = rtems_filesystem_default_fcntl,
+	.readv_h     = rtems_filesystem_default_readv,
+	.writev_h    = rtems_filesystem_default_writev
 };
 
 /* the link handlers table */
@@ -2901,7 +2905,9 @@ struct _rtems_filesystem_file_handlers_r nfs_link_file_handlers = {
 	.ftruncate_h = rtems_filesystem_default_ftruncate,
 	.fsync_h     = rtems_filesystem_default_fsync_or_fdatasync,
 	.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
-	.fcntl_h     = rtems_filesystem_default_fcntl
+	.fcntl_h     = rtems_filesystem_default_fcntl,
+	.readv_h     = rtems_filesystem_default_readv,
+	.writev_h    = rtems_filesystem_default_writev
 };
 
 /* we need a dummy driver entry table to get a
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c
index dbf9c16..ce1b77f 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c
@@ -193,5 +193,7 @@ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_device_handlers = {
   .ftruncate_h = rtems_rfs_rtems_device_ftruncate,
   .fsync_h     = rtems_filesystem_default_fsync_or_fdatasync,
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
-  .fcntl_h     = rtems_filesystem_default_fcntl
+  .fcntl_h     = rtems_filesystem_default_fcntl,
+  .readv_h     = rtems_filesystem_default_readv,
+  .writev_h    = rtems_filesystem_default_writev
 };
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c
index baf7155..eed110e 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c
@@ -162,5 +162,7 @@ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_dir_handlers = {
   .ftruncate_h = rtems_filesystem_default_ftruncate_directory,
   .fsync_h     = rtems_filesystem_default_fsync_or_fdatasync,
   .fdatasync_h = rtems_rfs_rtems_fdatasync,
-  .fcntl_h     = rtems_filesystem_default_fcntl
+  .fcntl_h     = rtems_filesystem_default_fcntl,
+  .readv_h     = rtems_filesystem_default_readv,
+  .writev_h    = rtems_filesystem_default_writev
 };
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c
index a811ee5..412586d 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c
@@ -353,5 +353,7 @@ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_file_handlers = {
   .ftruncate_h = rtems_rfs_rtems_file_ftruncate,
   .fsync_h     = rtems_rfs_rtems_fdatasync,
   .fdatasync_h = rtems_rfs_rtems_fdatasync,
-  .fcntl_h     = rtems_filesystem_default_fcntl
+  .fcntl_h     = rtems_filesystem_default_fcntl,
+  .readv_h     = rtems_filesystem_default_readv,
+  .writev_h    = rtems_filesystem_default_writev
 };
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems.c
index 5f30cf7..60ab3bb 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-rtems.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems.c
@@ -780,7 +780,9 @@ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_link_handlers =
   .ftruncate_h = rtems_filesystem_default_ftruncate,
   .fsync_h     = rtems_filesystem_default_fsync_or_fdatasync,
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
-  .fcntl_h     = rtems_filesystem_default_fcntl
+  .fcntl_h     = rtems_filesystem_default_fcntl,
+  .readv_h     = rtems_filesystem_default_readv,
+  .writev_h    = rtems_filesystem_default_writev
 };
 
 /**
diff --git a/cpukit/libnetworking/lib/ftpfs.c b/cpukit/libnetworking/lib/ftpfs.c
index 784ff48..d622ff6 100644
--- a/cpukit/libnetworking/lib/ftpfs.c
+++ b/cpukit/libnetworking/lib/ftpfs.c
@@ -1412,7 +1412,9 @@ static const rtems_filesystem_file_handlers_r rtems_ftpfs_handlers = {
   .ftruncate_h = rtems_ftpfs_ftruncate,
   .fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
-  .fcntl_h = rtems_filesystem_default_fcntl
+  .fcntl_h = rtems_filesystem_default_fcntl,
+  .readv_h = rtems_filesystem_default_readv,
+  .writev_h = rtems_filesystem_default_writev
 };
 
 static const rtems_filesystem_file_handlers_r rtems_ftpfs_root_handlers = {
@@ -1426,5 +1428,7 @@ static const rtems_filesystem_file_handlers_r rtems_ftpfs_root_handlers = {
   .ftruncate_h = rtems_filesystem_default_ftruncate,
   .fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
-  .fcntl_h = rtems_filesystem_default_fcntl
+  .fcntl_h = rtems_filesystem_default_fcntl,
+  .readv_h = rtems_filesystem_default_readv,
+  .writev_h = rtems_filesystem_default_writev
 };
diff --git a/cpukit/libnetworking/lib/tftpDriver.c b/cpukit/libnetworking/lib/tftpDriver.c
index d549436..c6461e0 100644
--- a/cpukit/libnetworking/lib/tftpDriver.c
+++ b/cpukit/libnetworking/lib/tftpDriver.c
@@ -1051,5 +1051,7 @@ static const rtems_filesystem_file_handlers_r rtems_tftp_handlers = {
    .ftruncate_h = rtems_tftp_ftruncate,
    .fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
    .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
-   .fcntl_h = rtems_filesystem_default_fcntl
+   .fcntl_h = rtems_filesystem_default_fcntl,
+   .readv_h = rtems_filesystem_default_readv,
+   .writev_h = rtems_filesystem_default_writev
 };
diff --git a/cpukit/libnetworking/rtems/rtems_syscall.c b/cpukit/libnetworking/rtems/rtems_syscall.c
index 727eac6..4aa7ad8 100644
--- a/cpukit/libnetworking/rtems/rtems_syscall.c
+++ b/cpukit/libnetworking/rtems/rtems_syscall.c
@@ -812,15 +812,17 @@ rtems_bsdnet_fstat (const rtems_filesystem_location_info_t *loc, struct stat *sp
 }
 
 static const rtems_filesystem_file_handlers_r socket_handlers = {
-	rtems_filesystem_default_open,		/* open */
-	rtems_bsdnet_close,			/* close */
-	rtems_bsdnet_read,			/* read */
-	rtems_bsdnet_write,			/* write */
-	rtems_bsdnet_ioctl,			/* ioctl */
-	rtems_filesystem_default_lseek,		/* lseek */
-	rtems_bsdnet_fstat,			/* fstat */
-	rtems_filesystem_default_ftruncate,	/* ftruncate */
-	rtems_filesystem_default_fsync_or_fdatasync,	/* fsync */
-	rtems_filesystem_default_fsync_or_fdatasync,	/* fdatasync */
-	rtems_bsdnet_fcntl 			/* fcntl */
+	.open_h = rtems_filesystem_default_open,
+	.close_h = rtems_bsdnet_close,
+	.read_h = rtems_bsdnet_read,
+	.write_h = rtems_bsdnet_write,
+	.ioctl_h = rtems_bsdnet_ioctl,
+	.lseek_h = rtems_filesystem_default_lseek,
+	.fstat_h = rtems_bsdnet_fstat,
+	.ftruncate_h = rtems_filesystem_default_ftruncate,
+	.fstat_h = rtems_filesystem_default_fsync_or_fdatasync,
+	.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
+	.fcntl_h = rtems_bsdnet_fcntl,
+	.readv_h = rtems_filesystem_default_readv,
+	.writev_h = rtems_filesystem_default_writev
 };
diff --git a/testsuites/fstests/fsimfsgeneric01/init.c b/testsuites/fstests/fsimfsgeneric01/init.c
index 720a963..2eab2e4 100644
--- a/testsuites/fstests/fsimfsgeneric01/init.c
+++ b/testsuites/fstests/fsimfsgeneric01/init.c
@@ -20,6 +20,7 @@
 
 #include <sys/stat.h>
 #include <sys/ioctl.h>
+#include <sys/uio.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
@@ -41,6 +42,8 @@ typedef enum {
   TEST_FSYNC,
   TEST_FDATASYNC,
   TEST_FCNTL,
+  TEST_READV,
+  TEST_WRITEV,
   TEST_CLOSED,
   TEST_FSTAT_UNLINK,
   TEST_REMOVED,
@@ -68,7 +71,7 @@ static int handler_close(
 {
   test_state *state = IMFS_generic_get_context_by_iop(iop);
 
-  rtems_test_assert(*state == TEST_FCNTL);
+  rtems_test_assert(*state == TEST_WRITEV);
   *state = TEST_CLOSED;
 
   return 0;
@@ -202,6 +205,36 @@ static int handler_fcntl(
   return 0;
 }
 
+static ssize_t handler_readv(
+  rtems_libio_t *iop,
+  const struct iovec *iov,
+  int iovcnt,
+  ssize_t total
+)
+{
+  test_state *state = IMFS_generic_get_context_by_iop(iop);
+
+  rtems_test_assert(*state == TEST_FCNTL);
+  *state = TEST_READV;
+
+  return 0;
+}
+
+static ssize_t handler_writev(
+  rtems_libio_t *iop,
+  const struct iovec *iov,
+  int iovcnt,
+  ssize_t total
+)
+{
+  test_state *state = IMFS_generic_get_context_by_iop(iop);
+
+  rtems_test_assert(*state == TEST_READV);
+  *state = TEST_WRITEV;
+
+  return 0;
+}
+
 static const rtems_filesystem_file_handlers_r node_handlers = {
   .open_h = handler_open,
   .close_h = handler_close,
@@ -213,7 +246,9 @@ static const rtems_filesystem_file_handlers_r node_handlers = {
   .ftruncate_h = handler_ftruncate,
   .fsync_h = handler_fsync,
   .fdatasync_h = handler_fdatasync,
-  .fcntl_h = handler_fcntl
+  .fcntl_h = handler_fcntl,
+  .readv_h = handler_readv,
+  .writev_h = handler_writev
 };
 
 static IMFS_jnode_t *node_initialize(
@@ -269,6 +304,10 @@ static void test_imfs_make_generic_node(void)
   char buf [1];
   ssize_t n = 0;
   off_t off = 0;
+  struct iovec iov = {
+    .iov_base = &buf [0],
+    .iov_len = (int) sizeof(buf)
+  };
 
   rv = IMFS_make_generic_node(
     path,
@@ -305,6 +344,12 @@ static void test_imfs_make_generic_node(void)
   rv = fcntl(fd, F_GETFD);
   rtems_test_assert(rv >= 0);
 
+  rv = readv(fd, &iov, 1);
+  rtems_test_assert(rv == 0);
+
+  rv = writev(fd, &iov, 1);
+  rtems_test_assert(rv == 0);
+
   rv = close(fd);
   rtems_test_assert(rv == 0);
 
-- 
1.7.7




More information about the devel mailing list