summaryrefslogtreecommitdiffstats
path: root/cpukit/libcsupport
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-12-16 13:44:13 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-12-20 10:31:53 +0100
commit2f68778f08471fb7f13a8634ebb48c6db13c0f69 (patch)
treeeae0deea88cc0d81052f8497a668dfaeecd6de40 /cpukit/libcsupport
parentlibcsupport: Add and use rtems_libio_iovec_eval() (diff)
downloadrtems-2f68778f08471fb7f13a8634ebb48c6db13c0f69.tar.bz2
Filesystem: Add readv/writev handlers
The readv() and writev() support was implemented in terms of multiple 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.
Diffstat (limited to 'cpukit/libcsupport')
-rw-r--r--cpukit/libcsupport/include/rtems/libio.h73
-rw-r--r--cpukit/libcsupport/src/__usrenv.c4
-rw-r--r--cpukit/libcsupport/src/readv.c21
-rw-r--r--cpukit/libcsupport/src/writev.c21
4 files changed, 78 insertions, 41 deletions
diff --git a/cpukit/libcsupport/include/rtems/libio.h b/cpukit/libcsupport/include/rtems/libio.h
index 21d57ebddf..4bfa02a3a5 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 88058c4714..f8604479a5 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 e47f22850a..6a4e0579f3 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 4a8dc735b8..7fa55bdbe5 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;