This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 327059ae3c742e9b16f15371da33846cdc240279
Author: chao an <[email protected]>
AuthorDate: Tue Oct 27 12:29:56 2026 +0800

    fs/vfs: Fast path single-buffer I/O
    
    Avoid routing file_read() and file_write() through the vector I/O path when
    the target file operation already provides a plain read or write method.
    
    With CONFIG_FS_UIO enabled, the scalar helpers previously built a single
    entry iovec, initialized a uio object, and then dispatched through
    file_readv() or file_writev().  Use the existing scalar operation directly
    for this common path, while preserving the vector fallback for drivers that
    only implement readv or writev.
    
    Signed-off-by: chao an <[email protected]>
---
 fs/vfs/fs_read.c  | 25 +++++++++++++++----------
 fs/vfs/fs_write.c | 25 +++++++++++++++----------
 2 files changed, 30 insertions(+), 20 deletions(-)

diff --git a/fs/vfs/fs_read.c b/fs/vfs/fs_read.c
index 584c043bc86..9be340d9ba5 100644
--- a/fs/vfs/fs_read.c
+++ b/fs/vfs/fs_read.c
@@ -278,18 +278,24 @@ ssize_t file_readv(FAR struct file *filep,
 
 ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes)
 {
-#ifdef CONFIG_FS_UIO
-  struct iovec iov;
-
-  iov.iov_base = buf;
-  iov.iov_len = nbytes;
-
-  return file_readv(filep, &iov, 1);
-#else
-  FAR struct inode *inode = filep->f_inode;
+  FAR struct inode *inode;
   ssize_t ret = -EBADF;
 
   DEBUGASSERT(filep);
+  inode = filep->f_inode;
+
+#ifdef CONFIG_FS_UIO
+  if (inode == NULL || inode->u.i_ops == NULL ||
+      inode->u.i_ops->read == NULL)
+    {
+      struct iovec iov;
+
+      iov.iov_base = buf;
+      iov.iov_len = nbytes;
+
+      return file_readv(filep, &iov, 1);
+    }
+#endif
 
   /* Was this file opened for read access? */
 
@@ -353,7 +359,6 @@ ssize_t file_read(FAR struct file *filep, FAR void *buf, 
size_t nbytes)
 #endif
 
   return ret;
-#endif
 }
 
 /****************************************************************************
diff --git a/fs/vfs/fs_write.c b/fs/vfs/fs_write.c
index 399e0c3ceae..2a225bb86a6 100644
--- a/fs/vfs/fs_write.c
+++ b/fs/vfs/fs_write.c
@@ -253,18 +253,24 @@ ssize_t file_writev(FAR struct file *filep,
 ssize_t file_write(FAR struct file *filep, FAR const void *buf,
                    size_t nbytes)
 {
-#ifdef CONFIG_FS_UIO
-  struct iovec iov;
-
-  iov.iov_base = (FAR void *)buf;
-  iov.iov_len = nbytes;
-
-  return file_writev(filep, &iov, 1);
-#else
-  FAR struct inode *inode = filep->f_inode;
+  FAR struct inode *inode;
   ssize_t ret = -EBADF;
 
   DEBUGASSERT(filep);
+  inode = filep->f_inode;
+
+#ifdef CONFIG_FS_UIO
+  if (inode == NULL || inode->u.i_ops == NULL ||
+      inode->u.i_ops->write == NULL)
+    {
+      struct iovec iov;
+
+      iov.iov_base = (FAR void *)buf;
+      iov.iov_len = nbytes;
+
+      return file_writev(filep, &iov, 1);
+    }
+#endif
 
   /* Was this file opened for write access? */
 
@@ -319,7 +325,6 @@ ssize_t file_write(FAR struct file *filep, FAR const void 
*buf,
 #endif
 
   return ret;
-#endif
 }
 
 /****************************************************************************

Reply via email to