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:
chao an 2025-01-21 20:13:29 +08:00 committed by Xiang Xiao
parent 9fb96af643
commit 2c9b287b2e
3 changed files with 83 additions and 91 deletions

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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