fs/vfs: initialize uio only if lower implement readv/writev
to simple signle read/write logic, initialize uio only if lower implement readv/writev Signed-off-by: chao an <anchao.archer@bytedance.com>
This commit is contained in:
parent
9fb96af643
commit
2c9b287b2e
3 changed files with 83 additions and 91 deletions
|
|
@ -70,19 +70,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++)
|
||||
|
|
@ -94,36 +89,41 @@ 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;
|
||||
/* Sanity check to avoid total length overflow */
|
||||
|
||||
nread = inode->u.i_ops->read(filep, (void *)buffer, remaining);
|
||||
if (SSIZE_MAX - ntotal < iov[i].iov_len)
|
||||
{
|
||||
if (ntotal > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
@ -146,7 +146,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
|
||||
|
|
@ -154,7 +155,8 @@ 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;
|
||||
|
|
@ -182,11 +184,17 @@ 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);
|
||||
struct uio 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -227,18 +235,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);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -264,7 +265,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;
|
||||
|
||||
|
|
@ -273,20 +273,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. */
|
||||
|
||||
ret = file_readv(filep, iov, iovcnt);
|
||||
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
/* Then let file_readv do all of the work. */
|
||||
|
||||
ret = uio_init(&uio, iov, iovcnt);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = file_readv(filep, &uio);
|
||||
}
|
||||
|
||||
fs_putfilep(filep);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,19 +53,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++)
|
||||
|
|
@ -77,36 +71,41 @@ static ssize_t file_writev_compat(FAR struct file *filep,
|
|||
continue;
|
||||
}
|
||||
|
||||
buffer = iov[i].iov_base;
|
||||
remaining = iov[i].iov_len;
|
||||
/* Sanity check to avoid total length overflow */
|
||||
|
||||
nwritten = inode->u.i_ops->write(filep, (void *)buffer, remaining);
|
||||
if (SSIZE_MAX - ntotal < iov[i].iov_len)
|
||||
{
|
||||
if (ntotal > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
@ -130,7 +129,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
|
||||
|
|
@ -140,7 +140,8 @@ 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;
|
||||
|
|
@ -161,11 +162,17 @@ 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);
|
||||
struct uio 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -208,18 +215,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);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -249,7 +249,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;
|
||||
|
||||
|
|
@ -264,11 +263,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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue