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