From fa7865f109fb862b3cd138323a25dc679eb131f8 Mon Sep 17 00:00:00 2001 From: yukangzhi Date: Thu, 30 Jul 2026 14:44:08 +0800 Subject: [PATCH] fs/vfs: fix link() returning EXDEV instead of ENAMETOOLONG When inode_find() for path2 fails due to ENAMETOOLONG (or ELOOP), the else branch incorrectly falls through to the EXDEV check based on whether target is a mountpoint. This causes link() to report EXDEV for overly long path2, violating POSIX which requires ENAMETOOLONG in this case. Fix by propagating the original inode_find() error code when it is not ENOENT or ENOTDIR (i.e., not a simple "path does not exist" condition). Signed-off-by: yukangzhi --- fs/vfs/fs_link.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/fs/vfs/fs_link.c b/fs/vfs/fs_link.c index 21432eb6ad3..2b8c652a67a 100644 --- a/fs/vfs/fs_link.c +++ b/fs/vfs/fs_link.c @@ -180,12 +180,23 @@ int link(FAR const char *path1, FAR const char *path2) else { + /* If inode_find for path2 failed for a reason other than "path does + * not exist" (e.g. ENAMETOOLONG, ELOOP), propagate that error + * directly instead of falling through to the EXDEV check. + */ + + if (ret != -ENOENT && ret != -ENOTDIR) + { + errcode = -ret; + goto errout_with_newinode; + } + /* Cannot link between pseudofs and other mountpoints */ if (INODE_IS_MOUNTPT(target)) { errcode = EXDEV; - goto errout_with_target; + goto errout_with_newinode; } /* Create an inode in the pseudo-filesystem at this path. */