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; FAR struct inode *inode = filep->f_inode;
ssize_t ntotal; ssize_t ntotal;
ssize_t nread; ssize_t nread;
size_t remaining;
FAR uint8_t *buffer;
int i; int i;
DEBUGASSERT(inode->u.i_ops->read != NULL);
/* Process each entry in the struct iovec array */ /* Process each entry in the struct iovec array */
for (i = 0, ntotal = 0; i < iovcnt; i++) 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; continue;
} }
buffer = iov[i].iov_base; /* Sanity check to avoid total length overflow */
remaining = iov[i].iov_len;
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 */ /* Check for a read error */
if (nread < 0) if (nread < 0)
{ {
return ntotal ? ntotal : nread; if (ntotal > 0)
{
break;
}
return nread;
} }
ntotal += nread; ntotal += nread;
/* Check for a parital success condition, including an end-of-file */ /* 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; return ntotal;
@ -146,7 +146,8 @@ static ssize_t file_readv_compat(FAR struct file *filep, FAR struct uio *uio)
* *
* Input Parameters: * Input Parameters:
* filep - File structure instance * filep - File structure instance
* uio - User buffer information * iov - User-provided iovec to save the data
* iovcnt - The number of iovec
* *
* Returned Value: * Returned Value:
* The positive non-zero number of bytes read on success, 0 on if an * 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; FAR struct inode *inode;
ssize_t ret = -EBADF; 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) 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) 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) ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes)
{ {
struct iovec iov; struct iovec iov;
struct uio uio;
ssize_t ret;
iov.iov_base = buf; iov.iov_base = buf;
iov.iov_len = nbytes; 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) ssize_t nx_readv(int fd, FAR const struct iovec *iov, int iovcnt)
{ {
struct uio uio;
FAR struct file *filep; FAR struct file *filep;
ssize_t ret; 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); 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; return ret;
} }

View file

@ -53,19 +53,13 @@
****************************************************************************/ ****************************************************************************/
static ssize_t file_writev_compat(FAR struct file *filep, 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; FAR struct inode *inode = filep->f_inode;
ssize_t ntotal;
ssize_t nwritten; ssize_t nwritten;
size_t remaining; ssize_t ntotal;
FAR uint8_t *buffer;
int i; int i;
DEBUGASSERT(inode->u.i_ops->write != NULL);
/* Process each entry in the struct iovec array */ /* Process each entry in the struct iovec array */
for (i = 0, ntotal = 0; i < iovcnt; i++) for (i = 0, ntotal = 0; i < iovcnt; i++)
@ -77,36 +71,41 @@ static ssize_t file_writev_compat(FAR struct file *filep,
continue; continue;
} }
buffer = iov[i].iov_base; /* Sanity check to avoid total length overflow */
remaining = iov[i].iov_len;
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 */ /* Check for a write error */
if (nwritten < 0) if (nwritten < 0)
{ {
return ntotal ? ntotal : nwritten; if (ntotal > 0)
{
break;
}
return nwritten;
} }
ntotal += nwritten; ntotal += nwritten;
/* Check for a parital success condition */ /* 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; return ntotal;
@ -130,7 +129,8 @@ static ssize_t file_writev_compat(FAR struct file *filep,
* *
* Input Parameters: * Input Parameters:
* filep - Instance of struct file to use with the write * 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: * Returned Value:
* On success, the number of bytes written are returned (zero indicates * 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; FAR struct inode *inode;
ssize_t ret = -EBADF; 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) 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) 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) size_t nbytes)
{ {
struct iovec iov; struct iovec iov;
struct uio uio;
ssize_t ret;
iov.iov_base = (FAR void *)buf; iov.iov_base = (FAR void *)buf;
iov.iov_len = nbytes; 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) ssize_t nx_writev(int fd, FAR const struct iovec *iov, int iovcnt)
{ {
struct uio uio;
FAR struct file *filep; FAR struct file *filep;
ssize_t ret; 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. * index. Note that file_writev() will return the errno on failure.
*/ */
ret = uio_init(&uio, iov, iovcnt); ret = file_writev(filep, iov, iovcnt);
if (ret == 0)
{
ret = file_writev(filep, &uio);
}
fs_putfilep(filep); 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_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 * 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, ssize_t file_write(FAR struct file *filep, FAR const void *buf,
size_t nbytes); 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 * Name: nx_write