diff --git a/fs/vfs/fs_read.c b/fs/vfs/fs_read.c index 1d93af0e04bf1..0c5f61545b54a 100644 --- a/fs/vfs/fs_read.c +++ b/fs/vfs/fs_read.c @@ -50,19 +50,14 @@ * ****************************************************************************/ -static ssize_t file_readv_compat(FAR struct file *filep, FAR struct uio *uio) +static ssize_t file_readv_compat(FAR struct file *filep, + FAR const struct iovec *iov, int iovcnt) { - FAR const struct iovec *iov = uio->uio_iov; - int iovcnt = uio->uio_iovcnt; FAR struct inode *inode = filep->f_inode; ssize_t ntotal; ssize_t nread; - size_t remaining; - FAR uint8_t *buffer; int i; - DEBUGASSERT(inode->u.i_ops->read != NULL); - /* Process each entry in the struct iovec array */ for (i = 0, ntotal = 0; i < iovcnt; i++) @@ -74,36 +69,28 @@ static ssize_t file_readv_compat(FAR struct file *filep, FAR struct uio *uio) continue; } - buffer = iov[i].iov_base; - remaining = iov[i].iov_len; - - nread = inode->u.i_ops->read(filep, (void *)buffer, remaining); + nread = inode->u.i_ops->read(filep, iov[i].iov_base, iov[i].iov_len); /* Check for a read error */ if (nread < 0) { - return ntotal ? ntotal : nread; + if (ntotal > 0) + { + break; + } + + return nread; } ntotal += nread; /* Check for a parital success condition, including an end-of-file */ - if (nread < remaining) + if (nread < iov[i].iov_len) { - return ntotal; + break; } - - /* Update the pointer */ - - buffer += nread; - remaining -= nread; - } - - if (ntotal >= 0) - { - uio_advance(uio, ntotal); } return ntotal; @@ -126,7 +113,8 @@ static ssize_t file_readv_compat(FAR struct file *filep, FAR struct uio *uio) * * Input Parameters: * filep - File structure instance - * uio - User buffer information + * iov - User-provided iovec to save the data + * iovcnt - The number of iovec * * Returned Value: * The positive non-zero number of bytes read on success, 0 on if an @@ -134,10 +122,12 @@ static ssize_t file_readv_compat(FAR struct file *filep, FAR struct uio *uio) * ****************************************************************************/ -ssize_t file_readv(FAR struct file *filep, FAR struct uio *uio) +ssize_t file_readv(FAR struct file *filep, + FAR const struct iovec *iov, int iovcnt) { FAR struct inode *inode; ssize_t ret = -EBADF; + struct uio uio; DEBUGASSERT(filep); inode = filep->f_inode; @@ -162,11 +152,15 @@ ssize_t file_readv(FAR struct file *filep, FAR struct uio *uio) { if (inode->u.i_ops->readv) { - ret = inode->u.i_ops->readv(filep, uio); + ret = uio_init(&uio, iov, iovcnt); + if (ret == 0) + { + ret = inode->u.i_ops->readv(filep, &uio); + } } else if (inode->u.i_ops->read) { - ret = file_readv_compat(filep, uio); + ret = file_readv_compat(filep, iov, iovcnt); } } @@ -207,18 +201,11 @@ ssize_t file_readv(FAR struct file *filep, FAR struct uio *uio) ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes) { struct iovec iov; - struct uio uio; - ssize_t ret; iov.iov_base = buf; iov.iov_len = nbytes; - ret = uio_init(&uio, &iov, 1); - if (ret != 0) - { - return ret; - } - return file_readv(filep, &uio); + return file_readv(filep, &iov, 1); } /**************************************************************************** @@ -244,7 +231,6 @@ ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes) ssize_t nx_readv(int fd, FAR const struct iovec *iov, int iovcnt) { - struct uio uio; FAR struct file *filep; ssize_t ret; @@ -253,20 +239,15 @@ ssize_t nx_readv(int fd, FAR const struct iovec *iov, int iovcnt) */ ret = (ssize_t)fs_getfilep(fd, &filep); - if (ret < 0) + if (ret >= 0) { - return ret; - } + /* Then let file_readv do all of the work. */ - /* Then let file_readv do all of the work. */ + ret = file_readv(filep, iov, iovcnt); - ret = uio_init(&uio, iov, iovcnt); - if (ret == 0) - { - ret = file_readv(filep, &uio); + fs_putfilep(filep); } - fs_putfilep(filep); return ret; } @@ -297,6 +278,7 @@ ssize_t nx_read(int fd, FAR void *buf, size_t nbytes) iov.iov_base = buf; iov.iov_len = nbytes; + return nx_readv(fd, &iov, 1); } @@ -361,5 +343,6 @@ ssize_t read(int fd, FAR void *buf, size_t nbytes) iov.iov_base = buf; iov.iov_len = nbytes; + return readv(fd, &iov, 1); } diff --git a/fs/vfs/fs_uio.c b/fs/vfs/fs_uio.c index 0ee178bfbfec8..e0193b7342223 100644 --- a/fs/vfs/fs_uio.c +++ b/fs/vfs/fs_uio.c @@ -82,8 +82,8 @@ ssize_t uio_calc_resid(FAR const struct uio *uio) void uio_advance(FAR struct uio *uio, size_t sz) { FAR const struct iovec *iov = uio->uio_iov; - int iovcnt = uio->uio_iovcnt; size_t offset_in_iov = uio->uio_offset_in_iov; + int iovcnt = uio->uio_iovcnt; DEBUGASSERT(sz <= SSIZE_MAX); DEBUGASSERT(uio->uio_resid <= SSIZE_MAX); @@ -126,12 +126,14 @@ int uio_init(FAR struct uio *uio, FAR const struct iovec *iov, int iovcnt) ssize_t resid; memset(uio, 0, sizeof(*uio)); + uio->uio_iov = iov; uio->uio_iovcnt = iovcnt; + resid = uio_calc_resid(uio); if (resid < 0) { - return -EINVAL; + return resid; } uio->uio_resid = resid; diff --git a/fs/vfs/fs_write.c b/fs/vfs/fs_write.c index 16be9ea957f38..97141702d7590 100644 --- a/fs/vfs/fs_write.c +++ b/fs/vfs/fs_write.c @@ -51,19 +51,13 @@ ****************************************************************************/ static ssize_t file_writev_compat(FAR struct file *filep, - FAR struct uio *uio) + FAR const struct iovec *iov, int iovcnt) { - FAR const struct iovec *iov = uio->uio_iov; - int iovcnt = uio->uio_iovcnt; FAR struct inode *inode = filep->f_inode; - ssize_t ntotal; ssize_t nwritten; - size_t remaining; - FAR uint8_t *buffer; + ssize_t ntotal; int i; - DEBUGASSERT(inode->u.i_ops->write != NULL); - /* Process each entry in the struct iovec array */ for (i = 0, ntotal = 0; i < iovcnt; i++) @@ -75,36 +69,29 @@ static ssize_t file_writev_compat(FAR struct file *filep, continue; } - buffer = iov[i].iov_base; - remaining = iov[i].iov_len; - - nwritten = inode->u.i_ops->write(filep, (void *)buffer, remaining); + nwritten = inode->u.i_ops->write(filep, iov[i].iov_base, + iov[i].iov_len); /* Check for a write error */ if (nwritten < 0) { - return ntotal ? ntotal : nwritten; + if (ntotal > 0) + { + break; + } + + return nwritten; } ntotal += nwritten; /* Check for a parital success condition */ - if (nwritten < remaining) + if (nwritten < iov[i].iov_len) { - return ntotal; + break; } - - /* Update the pointer */ - - buffer += nwritten; - remaining -= nwritten; - } - - if (ntotal >= 0) - { - uio_advance(uio, ntotal); } return ntotal; @@ -128,7 +115,8 @@ static ssize_t file_writev_compat(FAR struct file *filep, * * Input Parameters: * filep - Instance of struct file to use with the write - * uio - User buffer information + * iov - Data to write + * iovcnt - The number of vectors * * Returned Value: * On success, the number of bytes written are returned (zero indicates @@ -138,10 +126,12 @@ static ssize_t file_writev_compat(FAR struct file *filep, * ****************************************************************************/ -ssize_t file_writev(FAR struct file *filep, FAR struct uio *uio) +ssize_t file_writev(FAR struct file *filep, + FAR const struct iovec *iov, int iovcnt) { FAR struct inode *inode; ssize_t ret = -EBADF; + struct uio uio; /* Was this file opened for write access? */ @@ -159,11 +149,15 @@ ssize_t file_writev(FAR struct file *filep, FAR struct uio *uio) { if (inode->u.i_ops->writev) { - ret = inode->u.i_ops->writev(filep, uio); + ret = uio_init(&uio, iov, iovcnt); + if (ret == 0) + { + ret = inode->u.i_ops->writev(filep, &uio); + } } else if (inode->u.i_ops->write) { - ret = file_writev_compat(filep, uio); + ret = file_writev_compat(filep, iov, iovcnt); } } @@ -206,18 +200,11 @@ ssize_t file_write(FAR struct file *filep, FAR const void *buf, size_t nbytes) { struct iovec iov; - struct uio uio; - ssize_t ret; iov.iov_base = (FAR void *)buf; iov.iov_len = nbytes; - ret = uio_init(&uio, &iov, 1); - if (ret != 0) - { - return ret; - } - return file_writev(filep, &uio); + return file_writev(filep, &iov, 1); } /**************************************************************************** @@ -247,7 +234,6 @@ ssize_t file_write(FAR struct file *filep, FAR const void *buf, ssize_t nx_writev(int fd, FAR const struct iovec *iov, int iovcnt) { - struct uio uio; FAR struct file *filep; ssize_t ret; @@ -262,11 +248,7 @@ ssize_t nx_writev(int fd, FAR const struct iovec *iov, int iovcnt) * index. Note that file_writev() will return the errno on failure. */ - ret = uio_init(&uio, iov, iovcnt); - if (ret == 0) - { - ret = file_writev(filep, &uio); - } + ret = file_writev(filep, iov, iovcnt); fs_putfilep(filep); } diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h index 72edf64d65543..156d67279a146 100644 --- a/include/nuttx/fs/fs.h +++ b/include/nuttx/fs/fs.h @@ -1419,7 +1419,8 @@ int close_mtddriver(FAR struct inode *pinode); ****************************************************************************/ ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes); -ssize_t file_readv(FAR struct file *filep, FAR struct uio *uio); +ssize_t file_readv(FAR struct file *filep, + FAR const struct iovec *iov, int iovcnt); /**************************************************************************** * Name: nx_read @@ -1473,7 +1474,8 @@ ssize_t nx_readv(int fd, FAR const struct iovec *iov, int iovcnt); ssize_t file_write(FAR struct file *filep, FAR const void *buf, size_t nbytes); -ssize_t file_writev(FAR struct file *filep, FAR struct uio *uio); +ssize_t file_writev(FAR struct file *filep, + FAR const struct iovec *iov, int iovcnt); /**************************************************************************** * Name: nx_write