diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-12-16 13:44:13 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-12-20 10:31:53 +0100 |
commit | 2f68778f08471fb7f13a8634ebb48c6db13c0f69 (patch) | |
tree | eae0deea88cc0d81052f8497a668dfaeecd6de40 /cpukit/libcsupport | |
parent | libcsupport: Add and use rtems_libio_iovec_eval() (diff) | |
download | rtems-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.h | 73 | ||||
-rw-r--r-- | cpukit/libcsupport/src/__usrenv.c | 4 | ||||
-rw-r--r-- | cpukit/libcsupport/src/readv.c | 21 | ||||
-rw-r--r-- | cpukit/libcsupport/src/writev.c | 21 |
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; |