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

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

commit e7da2383bfcbbe98bd3576d005cb9c6e24812c5f
Author: Marco Casaroli <[email protected]>
AuthorDate: Sat Oct 17 19:52:47 2026 +0200

    fs/driver: Return EPERM for a pipe inside a mount point.
    
    Pipes and FIFOs exist only in the pseudo file system.  inode_reserve()
    returns -EEXIST when the path lies inside a mounted file system,
    because it does not look into the mount.  Thus mkfifo("/tmp/f") on a
    tmpfs, hostfs or v9fs mount failed with EEXIST although no file
    exists at that path.  A caller that sees EEXIST thinks that the file
    is there and does not try a different location.
    
    When inode_reserve() returns -EEXIST, register_pipedriver() now does
    an lstat of the path.  If no file exists, it returns -EPERM.  If a
    file exists (in the pseudo file system or in the mount), the result
    stays -EEXIST.
    
    EPERM is the error that Linux returns from mknod() and mkfifo() when
    the file system of the path does not support the node type (for
    example vfat).  POSIX lists EPERM for mknod().  The POSIX mkfifo()
    error list has no error for this case, and EEXIST is wrong because
    nothing exists at the path.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 fs/driver/fs_registerpipedriver.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/fs/driver/fs_registerpipedriver.c 
b/fs/driver/fs_registerpipedriver.c
index b9a8329eb2d..70ec547f419 100644
--- a/fs/driver/fs_registerpipedriver.c
+++ b/fs/driver/fs_registerpipedriver.c
@@ -27,6 +27,7 @@
 #include <nuttx/config.h>
 
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <errno.h>
 
 #include <nuttx/fs/fs.h>
@@ -60,6 +61,8 @@
  *   EINVAL - 'path' is invalid for this operation
  *   EEXIST - An inode already exists at 'path'
  *   ENOMEM - Failed to allocate in-memory resources for the operation
+ *   EPERM  - 'path' lies inside a mounted file system.  Pipes and FIFOs
+ *            can exist only in the pseudo file system.
  *
  ****************************************************************************/
 
@@ -68,6 +71,7 @@ int register_pipedriver(FAR const char *path,
                         mode_t mode, FAR void *priv)
 {
   FAR struct inode *node;
+  struct stat buf;
   int ret;
 
   /* Insert a dummy node -- we need to hold the inode semaphore because we
@@ -94,6 +98,17 @@ int register_pipedriver(FAR const char *path,
     }
 
   inode_unlock();
+
+  /* inode_reserve() also returns -EEXIST if 'path' lies inside a mounted
+   * file system.  The mounted file system cannot hold a pipe node.  If no
+   * file exists at 'path', report that the node type is not supported.
+   */
+
+  if (ret == -EEXIST && nx_stat(path, &buf, 0) == -ENOENT)
+    {
+      ret = -EPERM;
+    }
+
   return ret;
 }
 

Reply via email to