Skip to content

Commit

Permalink
fs/vfs: initialize uio only if lower implement readv/writev
Browse files Browse the repository at this point in the history
to simple signle read/write logic, initialize uio only if lower implement readv/writev

Signed-off-by: chao an <[email protected]>
  • Loading branch information
anchao committed Jan 20, 2025
1 parent 4857ea2 commit 7e7b069
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 93 deletions.
75 changes: 29 additions & 46 deletions fs/vfs/fs_read.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++)
Expand All @@ -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;
Expand All @@ -126,18 +113,21 @@ 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
* end-of-file condition, or a negated errno value on any failure.
*
****************************************************************************/

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

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

/****************************************************************************
Expand All @@ -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;

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

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

Expand Down Expand Up @@ -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);
}
6 changes: 4 additions & 2 deletions fs/vfs/fs_uio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
68 changes: 25 additions & 43 deletions fs/vfs/fs_write.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++)
Expand All @@ -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;
Expand All @@ -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
Expand All @@ -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? */

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

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

/****************************************************************************
Expand Down Expand Up @@ -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;

Expand All @@ -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);
}
Expand Down
6 changes: 4 additions & 2 deletions include/nuttx/fs/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 7e7b069

Please sign in to comment.