From f32800568b368edc102c61ef9d8be6792cc36dd5 Mon Sep 17 00:00:00 2001 From: zhaoxingyu1 Date: Thu, 30 Oct 2025 11:40:50 +0800 Subject: [PATCH] fs/inode: support relative path when inode_search Add support for resolving relative path components (in particular the ".." parent references) during the inode search. A helper _compute_path_depth() computes the remaining path depth so that a mount point is only treated as the terminal node when the depth is positive, and "../" components walk back up to the parent inode. Signed-off-by: zhaoxingyu1 --- fs/inode/fs_inodesearch.c | 48 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/fs/inode/fs_inodesearch.c b/fs/inode/fs_inodesearch.c index fa02871984e..640dee936fc 100644 --- a/fs/inode/fs_inodesearch.c +++ b/fs/inode/fs_inodesearch.c @@ -192,6 +192,35 @@ static int _inode_linktarget(FAR struct inode *inode, } #endif +/**************************************************************************** + * Name: _compute_path_depth + ****************************************************************************/ + +static int _compute_path_depth(FAR const char *path) +{ + FAR const char *name = path; + int depth = 0; + + while (*name != '\0') + { + if (strncmp(name, "../", 3) == 0) + { + if (--depth < 0) + { + break; + } + } + else + { + depth++; + } + + name = inode_nextname(name); + } + + return depth; +} + /**************************************************************************** * Name: _inode_search * @@ -280,7 +309,8 @@ static int _inode_search(FAR struct inode_search_s *desc) */ name = inode_nextname(name); - if (*name == '\0' || INODE_IS_MOUNTPT(inode)) + if (*name == '\0' || + (INODE_IS_MOUNTPT(inode) && _compute_path_depth(name) > 0)) { /* Either (1) we are at the end of the path, so this must be * the node we are looking for or else (2) this node is a @@ -292,6 +322,22 @@ static int _inode_search(FAR struct inode_search_s *desc) ret = OK; break; } + else if (strncmp(name, "../", 3) == 0) + { + above = inode; + left = NULL; + inode = inode->i_child; + + while (strncmp(name, "../", 3) == 0) + { + name = inode_nextname(name); + if (above != g_root_inode) + { + above = above->i_parent; + inode = above->i_child; + } + } + } else { /* More nodes to be examined in the path "below" this one. */