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 a0adad660264881acc1f83d901bf7f2f3a2f81bd Author: Abhishek Mishra <[email protected]> AuthorDate: Wed Aug 19 08:07:17 2026 +0000 fs: start absolute lookups at the jail root Prepare paths in inode_search_setup(): prepend tg_root, canonicalize with a jail-floor dst_min, then walk from g_root_inode. Replace SETUP_SEARCH / RELEASE_SEARCH with inode_search_setup() / inode_search_release(). Signed-off-by: Abhishek Mishra <[email protected]> --- fs/driver/fs_findblockdriver.c | 17 +- fs/driver/fs_finddriver.c | 14 +- fs/driver/fs_findmtddriver.c | 17 +- fs/event/event_open.c | 14 +- fs/fat/fs_fat32attrib.c | 16 +- fs/inode/fs_inodefind.c | 14 +- fs/inode/fs_inoderemove.c | 10 +- fs/inode/fs_inodereserve.c | 10 +- fs/inode/fs_inodesearch.c | 402 ++++++++++++++++++++++++----------------- fs/inode/inode.h | 65 ++++--- fs/littlefs/lfs_vfs.c | 3 + fs/mount/fs_automount.c | 16 +- fs/mount/fs_mount.c | 31 ++-- fs/mount/fs_umount2.c | 13 +- fs/mqueue/mq_open.c | 31 ++-- fs/mqueue/mq_unlink.c | 14 +- fs/partition/fs_partition.c | 2 + fs/semaphore/sem_open.c | 14 +- fs/semaphore/sem_unlink.c | 14 +- fs/shm/shm_open.c | 24 +-- fs/shm/shm_unlink.c | 16 +- fs/unionfs/fs_unionfs.c | 13 +- fs/vfs/fs_chstat.c | 11 +- fs/vfs/fs_close.c | 1 + fs/vfs/fs_link.c | 50 ++--- fs/vfs/fs_mkdir.c | 31 ++-- fs/vfs/fs_open.c | 17 +- fs/vfs/fs_readlink.c | 27 ++- fs/vfs/fs_rename.c | 66 ++++--- fs/vfs/fs_rmdir.c | 37 ++-- fs/vfs/fs_stat.c | 11 +- fs/vfs/fs_statfs.c | 13 +- fs/vfs/fs_symlink.c | 35 ++-- fs/vfs/fs_unlink.c | 15 +- 34 files changed, 604 insertions(+), 480 deletions(-) diff --git a/fs/driver/fs_findblockdriver.c b/fs/driver/fs_findblockdriver.c index 656bdc7a866..abc6ac54401 100644 --- a/fs/driver/fs_findblockdriver.c +++ b/fs/driver/fs_findblockdriver.c @@ -77,20 +77,19 @@ int find_blockdriver(FAR const char *pathname, int mountflags, /* Find the inode registered with this pathname */ - SETUP_SEARCH(&desc, pathname, false); + ret = inode_search_setup(&desc, pathname, false); + if (ret < 0) + { + return ret; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &inode); if (ret < 0) { ferr("ERROR: Failed to find %s\n", pathname); - ret = -ENOENT; goto errout_with_search; } - /* Get the search results */ - - inode = desc.node; - /* Verify that the inode is a block driver. */ if (!INODE_IS_BLOCK(inode)) @@ -121,12 +120,12 @@ int find_blockdriver(FAR const char *pathname, int mountflags, } *ppinode = inode; - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return OK; errout_with_inode: inode_release(inode); errout_with_search: - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return ret; } diff --git a/fs/driver/fs_finddriver.c b/fs/driver/fs_finddriver.c index f2724ba43d7..4f071510a3c 100644 --- a/fs/driver/fs_finddriver.c +++ b/fs/driver/fs_finddriver.c @@ -50,29 +50,33 @@ FAR void *find_driver(FAR const char *pathname) { struct inode_search_s desc; + FAR struct inode *inode; FAR void *drvr = NULL; DEBUGASSERT(pathname != NULL); /* Find the inode registered with this pathname */ - SETUP_SEARCH(&desc, pathname, false); + if (inode_search_setup(&desc, pathname, false) < 0) + { + return NULL; + } /* Get the search results */ inode_lock(); - if (inode_find(&desc) < 0) + if (inode_find(&desc, &inode) < 0) { ferr("ERROR: Failed to find %s\n", pathname); } else { - drvr = desc.node->i_private; - inode_release(desc.node); + drvr = inode->i_private; + inode_release(inode); } inode_unlock(); - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return drvr; } diff --git a/fs/driver/fs_findmtddriver.c b/fs/driver/fs_findmtddriver.c index e20e490acef..df3b0fe679e 100644 --- a/fs/driver/fs_findmtddriver.c +++ b/fs/driver/fs_findmtddriver.c @@ -70,20 +70,19 @@ int find_mtddriver(FAR const char *pathname, FAR struct inode **ppinode) /* Find the inode registered with this pathname */ - SETUP_SEARCH(&desc, pathname, false); + ret = inode_search_setup(&desc, pathname, false); + if (ret < 0) + { + return ret; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &inode); if (ret < 0) { ferr("ERROR: Failed to find %s\n", pathname); - ret = -ENOENT; goto errout_with_search; } - /* Get the search results */ - - inode = desc.node; - /* Verify that the inode is a block driver. */ if (!INODE_IS_MTD(inode)) @@ -98,14 +97,14 @@ int find_mtddriver(FAR const char *pathname, FAR struct inode **ppinode) DEBUGASSERT(inode->u.i_mtd != NULL); *ppinode = inode; - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return OK; errout_with_inode: inode_release(inode); errout_with_search: - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return ret; } diff --git a/fs/event/event_open.c b/fs/event/event_open.c index 6781d055029..f6d40d7b953 100644 --- a/fs/event/event_open.c +++ b/fs/event/event_open.c @@ -102,15 +102,17 @@ int nxevent_open(FAR nxevent_t **event, FAR const char *name, * will have incremented the reference count on the inode. */ - SETUP_SEARCH(&desc, fullpath, false); + ret = inode_search_setup(&desc, fullpath, false); + if (ret < 0) + { + return ret; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &inode); if (ret >= 0) { /* Something exists at this path. Get the search results */ - inode = desc.node; - /* Verify that the inode is a event group */ if (!INODE_IS_NAMEDEVENT(inode)) @@ -206,7 +208,7 @@ int nxevent_open(FAR nxevent_t **event, FAR const char *name, *event = &nevent->ne_event; } - RELEASE_SEARCH(&desc); + inode_search_release(&desc); #ifdef CONFIG_FS_NOTIFY notify_open(fullpath, oflags); #endif @@ -216,6 +218,6 @@ errout_with_inode: inode_release(inode); errout_with_search: - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return ret; } diff --git a/fs/fat/fs_fat32attrib.c b/fs/fat/fs_fat32attrib.c index 66880492234..fb2dbcc0b4d 100644 --- a/fs/fat/fs_fat32attrib.c +++ b/fs/fat/fs_fat32attrib.c @@ -59,9 +59,13 @@ static int fat_attrib(const char *path, fat_attrib_t *retattrib, /* Find the inode for this file */ - SETUP_SEARCH(&desc, path, false); + ret = inode_search_setup(&desc, path, false); + if (ret < 0) + { + return ret; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &inode); if (ret < 0) { /* There is no mountpoint that includes in this path */ @@ -69,10 +73,6 @@ static int fat_attrib(const char *path, fat_attrib_t *retattrib, goto errout; } - /* Get the search results */ - - inode = desc.node; - /* Verify that the inode is a valid mountpoint. */ if (!INODE_IS_MOUNTPT(inode) || !inode->u.i_mops || !inode->i_private) @@ -154,7 +154,7 @@ static int fat_attrib(const char *path, fat_attrib_t *retattrib, nxmutex_unlock(&fs->fs_lock); inode_release(inode); - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return OK; errout_with_lock: @@ -164,7 +164,7 @@ errout_with_inode: inode_release(inode); errout: - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return ret; } diff --git a/fs/inode/fs_inodefind.c b/fs/inode/fs_inodefind.c index 78cd426cf13..b975cf6fcaa 100644 --- a/fs/inode/fs_inodefind.c +++ b/fs/inode/fs_inodefind.c @@ -49,7 +49,7 @@ * ****************************************************************************/ -int inode_find(FAR struct inode_search_s *desc) +int inode_find(FAR struct inode_search_s *desc, FAR struct inode **inode) { int ret; @@ -57,18 +57,22 @@ int inode_find(FAR struct inode_search_s *desc) * references on the node. */ + if (inode == NULL) + { + return -EINVAL; + } + inode_rlock(); - ret = inode_search(desc); + ret = inode_search(desc, inode); if (ret >= 0) { /* Found it */ - FAR struct inode *inode = desc->node; - DEBUGASSERT(inode != NULL); + DEBUGASSERT(*inode != NULL); /* Increment the reference count on the inode */ - atomic_add(&inode->i_crefs, 1); + atomic_add(&(*inode)->i_crefs, 1); } inode_runlock(); diff --git a/fs/inode/fs_inoderemove.c b/fs/inode/fs_inoderemove.c index 064d4a7ccfe..921244bcb80 100644 --- a/fs/inode/fs_inoderemove.c +++ b/fs/inode/fs_inoderemove.c @@ -71,12 +71,14 @@ static FAR struct inode *inode_unlink(FAR const char *path) /* Find the node to unlink */ - SETUP_SEARCH(&desc, path, true); + if (inode_search_setup(&desc, path, true) < 0) + { + return NULL; + } - ret = inode_search(&desc); + ret = inode_search(&desc, &inode); if (ret >= 0) { - inode = desc.node; DEBUGASSERT(inode != NULL); if (desc.parent != NULL) @@ -137,7 +139,7 @@ static FAR struct inode *inode_unlink(FAR const char *path) } errout: - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return inode; } diff --git a/fs/inode/fs_inodereserve.c b/fs/inode/fs_inodereserve.c index 1b3c970e7e1..a547e28026e 100644 --- a/fs/inode/fs_inodereserve.c +++ b/fs/inode/fs_inodereserve.c @@ -208,9 +208,13 @@ int inode_reserve(FAR const char *path, /* Find the location to insert the new subtree */ - SETUP_SEARCH(&desc, path, false); + ret = inode_search_setup(&desc, path, false); + if (ret < 0) + { + return ret; + } - ret = inode_search(&desc); + ret = inode_search(&desc, NULL); if (ret != -ENOENT) { /* It is an error if the node already exists in the tree (or if it @@ -291,6 +295,6 @@ int inode_reserve(FAR const char *path, } errout_with_search: - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return ret; } diff --git a/fs/inode/fs_inodesearch.c b/fs/inode/fs_inodesearch.c index fac611a7c8f..7862c21e15a 100644 --- a/fs/inode/fs_inodesearch.c +++ b/fs/inode/fs_inodesearch.c @@ -34,6 +34,8 @@ #include <errno.h> #include <nuttx/fs/fs.h> +#include <nuttx/sched.h> +#include <nuttx/lib/lib.h> #include "inode/inode.h" @@ -43,12 +45,11 @@ static int _inode_compare(FAR const char *fname, FAR struct inode *inode); #ifdef CONFIG_FS_LINKS -static int _inode_linktarget(FAR struct inode *inode, +static int _inode_linktarget(FAR struct inode **inode, FAR struct inode_search_s *desc); #endif -static int _inode_search(FAR struct inode_search_s *desc); static FAR const char *_inode_getcwd(void); -static int _inode_canonicalize(FAR char *path); +static int _inode_canonicalize(FAR char *path, FAR char *dst_min); /**************************************************************************** * Public Data @@ -154,30 +155,34 @@ static int _inode_compare(FAR const char *fname, FAR struct inode *inode) ****************************************************************************/ #ifdef CONFIG_FS_LINKS -static int _inode_linktarget(FAR struct inode *inode, +static int _inode_linktarget(FAR struct inode **inode, FAR struct inode_search_s *desc) { unsigned int count = 0; bool save; int ret = -ENOENT; - DEBUGASSERT(desc != NULL && inode != NULL); + DEBUGASSERT(desc != NULL && inode != NULL && *inode != NULL); /* An infinite loop is avoided only by the loop count. */ save = desc->nofollow; - while (INODE_IS_SOFTLINK(inode)) + while (INODE_IS_SOFTLINK(*inode)) { - FAR const char *link = (FAR const char *)inode->u.i_link; + FAR const char *link = (FAR const char *)(*inode)->u.i_link; /* Reset and reinitialize the search descriptor. */ - RELEASE_SEARCH(desc); - SETUP_SEARCH(desc, link, true); + inode_search_release(desc); + ret = inode_search_setup(desc, link, true); + if (ret < 0) + { + break; + } /* Look up inode associated with the target of the symbolic link */ - ret = inode_search(desc); + ret = inode_search(desc, inode); if (ret < 0) { break; @@ -193,8 +198,7 @@ static int _inode_linktarget(FAR struct inode *inode, /* Set up for the next time through the loop */ - inode = desc->node; - DEBUGASSERT(inode != NULL); + DEBUGASSERT(*inode != NULL); } desc->nofollow = save; @@ -229,13 +233,15 @@ static int _compute_path_depth(FAR const char *path) * * Description: * Remove "." and ".." segments from an absolute path in-place. - * The path MUST start with '/'. Returns -EINVAL if ".." attempts - * to ascend beyond the root directory, or -ENAMETOOLONG if the - * canonicalized result is >= PATH_MAX bytes. + * The path MUST start with '/'. 'dst_min' is the lowest write + * position ".." may pop to (path + 1 for the host root, or just + * past the chroot prefix). ".." that would ascend beyond that + * floor is dropped. Returns -ENAMETOOLONG if the canonicalized + * result is >= PATH_MAX bytes. * ****************************************************************************/ -static int _inode_canonicalize(FAR char *path) +static int _inode_canonicalize(FAR char *path, FAR char *dst_min) { /* Skip the initial '/' -- caller guarantees absolute path */ @@ -265,22 +271,18 @@ static int _inode_canonicalize(FAR char *path) if (src[0] == '.' && src[1] == '.' && (src[2] == '/' || src[2] == '\0')) { - /* Cannot go above root */ - - if (dst <= path + 1) + if (dst > dst_min) { - return -EINVAL; - } + /* Remove trailing slash first */ - /* Remove trailing slash first */ - - dst--; + dst--; - /* Scan backward to find the previous '/' */ + /* Scan backward to find the previous '/' */ - while (dst > path + 1 && *(dst - 1) != '/') - { - dst--; + while (dst > dst_min && *(dst - 1) != '/') + { + dst--; + } } src += (src[2] == '/') ? 3 : 2; @@ -358,108 +360,240 @@ static int _inode_checkpath(const char *path) return pathlen >= PATH_MAX ? -ENAMETOOLONG : OK; } +#ifdef CONFIG_FS_CHROOT /**************************************************************************** - * Name: _inode_search + * Name: _inode_root_path * * Description: - * Find the inode associated with 'path' returning the inode references - * and references to its companion nodes. This is the internal, common - * implementation of inode_search(). + * Return the calling group's jail prefix, or NULL if none is installed. * - * If a mountpoint is encountered in the search prior to encountering the - * terminal node, the search will terminate at the mountpoint inode. That - * inode and the relative path from the mountpoint, 'relpath' will be - * returned. + ****************************************************************************/ + +static FAR const char *_inode_root_path(void) +{ + FAR struct tcb_s *tcb = nxsched_self(); + + if (tcb != NULL && tcb->group != NULL) + { + return tcb->group->tg_root; + } + + return NULL; +} +#endif + +/**************************************************************************** + * Name: _inode_getcwd * - * If a soft link is encountered that is not the terminal node in the path, - * that link WILL be deferenced unconditionally. + * Description: + * Return the current working directory * - * Assumptions: - * The caller holds the g_inode_sem semaphore + ****************************************************************************/ + +static FAR const char *_inode_getcwd(void) +{ + FAR const char *pwd = ""; + +#ifndef CONFIG_DISABLE_ENVIRON + pwd = getenv("PWD"); + if (pwd == NULL) + { + pwd = CONFIG_LIBC_HOMEDIR; + } +#endif + + return pwd; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: inode_search_release + * + * Description: + * Release any buffer allocated by inode_search_setup(). * ****************************************************************************/ -static int _inode_search(FAR struct inode_search_s *desc) +void inode_search_release(FAR struct inode_search_s *desc) { - FAR const char *name; - FAR struct inode *inode = g_root_inode; - FAR struct inode *left = NULL; - FAR struct inode *above = NULL; - FAR const char *relpath = NULL; + if (desc->buffer != NULL) + { + lib_put_tempbuffer(desc->buffer); + desc->buffer = NULL; + } +} + +/**************************************************************************** + * Name: inode_search_setup + * + * Description: + * Initialize a search descriptor and make 'path' host-absolute: join + * $PWD if it is relative, prepend the chroot jail if one is installed, + * and canonicalize "." / "..". On success desc->path points at + * desc->buffer. + * + ****************************************************************************/ + +int inode_search_setup(FAR struct inode_search_s *desc, + FAR const char *path, bool nofollow) +{ + FAR const char *cwd = NULL; + FAR const char *root = NULL; + FAR char *dst_min; + size_t rootlen = 0; + size_t buflen; int ret; - ret = _inode_checkpath(desc->path); + desc->path = path; + desc->peer = NULL; + desc->parent = NULL; + desc->relpath = NULL; + desc->buffer = NULL; + desc->nofollow = nofollow; + + if (path == NULL) + { + return -EINVAL; + } + + ret = _inode_checkpath(path); if (ret < 0) { return ret; } - /* Ensure we have a writable buffer for path manipulation */ - - if (desc->buffer == NULL) +#ifdef CONFIG_FS_CHROOT + root = _inode_root_path(); + if (root != NULL) { - FAR const char *cwd = NULL; - size_t buflen; - - /* For a relative path the absolute form is "<cwd>/<path>". That - * concatenation can exceed PATH_MAX even when the relative path - * itself is within PATH_MAX: a relative path of PATH_MAX-1 bytes - * is legal per pathconf(_PC_PATH_MAX), but the prefix added by the - * cwd pushes the uncanonicalized form past the limit. Size the - * buffer to hold the full absolute form so that ".." segments are - * collapsed against the correct suffix; truncating first could - * drop the trailing component and let ".." collapse the path onto - * a directory (yielding the wrong errno, e.g. EISDIR, instead of - * resolving the file). _inode_canonicalize() still rejects any - * result whose canonicalized length reaches PATH_MAX. - */ + rootlen = strlen(root); + } +#endif - if (*desc->path != '/') - { - cwd = _inode_getcwd(); - buflen = strlen(cwd) + 1 + strlen(desc->path) + 1; - } - else - { - buflen = strlen(desc->path) + 1; - } + /* For a relative path the absolute form is "<cwd>/<path>". That + * concatenation can exceed PATH_MAX even when the relative path + * itself is within PATH_MAX: a relative path of PATH_MAX-1 bytes + * is legal per pathconf(_PC_PATH_MAX), but the prefix added by the + * cwd pushes the uncanonicalized form past the limit. Size the + * buffer to hold the full absolute form so that ".." segments are + * collapsed against the correct suffix; truncating first could + * drop the trailing component and let ".." collapse the path onto + * a directory (yielding the wrong errno, e.g. EISDIR, instead of + * resolving the file). _inode_canonicalize() still rejects any + * result whose canonicalized length reaches PATH_MAX. + */ - if (buflen < PATH_MAX) - { - buflen = PATH_MAX; - } + if (*path != '/') + { + cwd = _inode_getcwd(); + buflen = strlen(cwd) + 1 + strlen(path) + 1; + } + else + { + buflen = strlen(path) + 1; + } - desc->buffer = lib_get_tempbuffer(buflen); - if (desc->buffer == NULL) - { - return -ENOMEM; - } + buflen += rootlen; + if (buflen < PATH_MAX) + { + buflen = PATH_MAX; + } + + desc->buffer = lib_get_tempbuffer(buflen); + if (desc->buffer == NULL) + { + return -ENOMEM; + } + if (root != NULL) + { if (cwd != NULL) { - snprintf(desc->buffer, buflen, "%s/%s", cwd, desc->path); + snprintf(desc->buffer, buflen, "%s%s/%s", root, cwd, path); } else { - strlcpy(desc->buffer, desc->path, buflen); + snprintf(desc->buffer, buflen, "%s%s", root, path); } - - desc->path = desc->buffer; } + else if (cwd != NULL) + { + snprintf(desc->buffer, buflen, "%s/%s", cwd, path); + } + else + { + strlcpy(desc->buffer, path, buflen); + } + + desc->path = desc->buffer; /* Canonicalize the path to remove "." and ".." segments. This ensures * that mountpoint relpath never contains ".." which most filesystems - * (tmpfs, romfs, etc.) cannot resolve. + * (tmpfs, romfs, etc.) cannot resolve. When a jail is installed, + * dst_min keeps ".." from popping above tg_root. */ - ret = _inode_canonicalize(desc->buffer); + dst_min = desc->buffer + 1; +#ifdef CONFIG_FS_CHROOT + if (root != NULL) + { + dst_min = desc->buffer + rootlen; + if (rootlen > 0 && root[rootlen - 1] != '/') + { + dst_min++; + } + } +#endif + + ret = _inode_canonicalize(desc->buffer, dst_min); if (ret < 0) { - return ret; + inode_search_release(desc); } + return ret; +} + +/**************************************************************************** + * Name: inode_search + * + * Description: + * Find the inode associated with 'path' returning the inode references + * and references to its companion nodes. + * + * If a mountpoint is encountered in the search prior to encountering the + * terminal node, the search will terminate at the mountpoint inode. That + * inode and the relative path from the mountpoint, 'relpath' will be + * returned. + * + * inode_search will follow soft links in path leading up to the terminal + * node. Whether or no inode_search() will deference that terminal node + * depends on the 'nofollow' input. + * + * If a soft link is encountered that is not the terminal node in the path, + * that link WILL be deferenced unconditionally. + * + * Assumptions: + * The caller holds the g_inode_sem semaphore + * The descriptor was initialized with inode_search_setup() + * + ****************************************************************************/ + +int inode_search(FAR struct inode_search_s *desc, FAR struct inode **inodep) +{ + FAR const char *name; + FAR struct inode *inode = g_root_inode; + FAR struct inode *left = NULL; + FAR struct inode *above = NULL; + FAR const char *relpath = NULL; + int ret = -ENOENT; + + DEBUGASSERT(desc != NULL && desc->path != NULL); + name = desc->path; - ret = -ENOENT; /* Traverse the pseudo file system node tree until either (1) all nodes * have been examined without finding the matching node, or (2) the @@ -531,6 +665,7 @@ static int _inode_search(FAR struct inode_search_s *desc) if (INODE_IS_SOFTLINK(inode)) { + FAR struct inode *newnode = inode; int status; /* If this intermediate inode in the is a soft link, then @@ -539,7 +674,7 @@ static int _inode_search(FAR struct inode_search_s *desc) * instead. */ - status = _inode_linktarget(inode, desc); + status = _inode_linktarget(&newnode, desc); if (status < 0) { /* Probably means that the target of the symbolic link @@ -551,8 +686,6 @@ static int _inode_search(FAR struct inode_search_s *desc) } else { - FAR struct inode *newnode = desc->node; - if (newnode != inode) { /* The node was a valid symbolic link and we have @@ -642,85 +775,13 @@ static int _inode_search(FAR struct inode_search_s *desc) */ desc->path = name; - desc->node = inode; desc->peer = left; desc->parent = above; desc->relpath = relpath; - return ret; -} - -/**************************************************************************** - * Name: _inode_getcwd - * - * Description: - * Return the current working directory - * - ****************************************************************************/ - -static FAR const char *_inode_getcwd(void) -{ - FAR const char *pwd = ""; - -#ifndef CONFIG_DISABLE_ENVIRON - pwd = getenv("PWD"); - if (pwd == NULL) - { - pwd = CONFIG_LIBC_HOMEDIR; - } -#endif - - return pwd; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: inode_search - * - * Description: - * Find the inode associated with 'path' returning the inode references - * and references to its companion nodes. - * - * If a mountpoint is encountered in the search prior to encountering the - * terminal node, the search will terminate at the mountpoint inode. That - * inode and the relative path from the mountpoint, 'relpath' will be - * returned. - * - * inode_search will follow soft links in path leading up to the terminal - * node. Whether or no inode_search() will deference that terminal node - * depends on the 'nofollow' input. - * - * If a soft link is encountered that is not the terminal node in the path, - * that link WILL be deferenced unconditionally. - * - * Assumptions: - * The caller holds the g_inode_sem semaphore - * - ****************************************************************************/ - -int inode_search(FAR struct inode_search_s *desc) -{ - int ret; - - /* Perform the common _inode_search() logic. This does everything except - * operations special operations that must be performed on the terminal - * node if node is a symbolic link. - */ - - DEBUGASSERT(desc != NULL && desc->path != NULL); - - ret = _inode_search(desc); #ifdef CONFIG_FS_LINKS if (ret >= 0) { - FAR struct inode *inode; - - /* Search completed successfully */ - - inode = desc->node; DEBUGASSERT(inode != NULL); /* Is the terminal node a softlink? Should we follow it? */ @@ -733,7 +794,7 @@ int inode_search(FAR struct inode_search_s *desc) * link target of the final symbolic link in the series. */ - ret = _inode_linktarget(inode, desc); + ret = _inode_linktarget(&inode, desc); if (ret < 0) { /* The most likely cause for failure is that the target of the @@ -749,12 +810,15 @@ int inode_search(FAR struct inode_search_s *desc) inode = inode->i_private; DEBUGASSERT(inode != NULL); - - desc->node = inode; } } #endif + if (inodep != NULL) + { + *inodep = inode; + } + return ret; } diff --git a/fs/inode/inode.h b/fs/inode/inode.h index 79a241e6dcc..eb015c7afb4 100644 --- a/fs/inode/inode.h +++ b/fs/inode/inode.h @@ -39,36 +39,11 @@ #include <nuttx/kmalloc.h> #include <nuttx/sched.h> #include <nuttx/fs/fs.h> -#include <nuttx/lib/lib.h> /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ -#define SETUP_SEARCH(d,p,n) \ - do \ - { \ - (d)->path = (p); \ - (d)->node = NULL; \ - (d)->peer = NULL; \ - (d)->parent = NULL; \ - (d)->relpath = NULL; \ - (d)->buffer = NULL; \ - (d)->nofollow = (n); \ - } \ - while (0) - -#define RELEASE_SEARCH(d) \ - do \ - { \ - if ((d)->buffer != NULL) \ - { \ - lib_put_tempbuffer((d)->buffer); \ - (d)->buffer = NULL; \ - } \ - } \ - while (0) - #if CONFIG_FS_BACKTRACE > 0 # define FS_ADD_BACKTRACE(fd) \ do \ @@ -110,8 +85,6 @@ * * path - INPUT: Path of inode to find * OUTPUT: Residual part of path not traversed - * node - INPUT: (not used) - * OUTPUT: On success, holds the pointer to the inode found. * peer - INPUT: (not used) * OUTPUT: The inode to the "left" of the inode found. * parent - INPUT: (not used) @@ -138,7 +111,6 @@ struct inode_search_s { FAR const char *path; /* Path of inode to find */ - FAR struct inode *node; /* Pointer to the inode found */ FAR struct inode *peer; /* Node to the "left" for the found inode */ FAR struct inode *parent; /* Node "above" the found inode */ FAR const char *relpath; /* Relative path into the mountpoint */ @@ -243,12 +215,41 @@ void inode_runlock(void); * If a soft link is encountered that is not the terminal node in the path, * that link WILL be deferenced unconditionally. * + * Input Parameters: + * desc - Search descriptor initialized with inode_search_setup() + * inode - OUTPUT: The found inode. May be NULL if the caller only + * cares about existence (e.g. inode_reserve). + * * Assumptions: * The caller holds the g_inode_sem semaphore + * The descriptor was initialized with inode_search_setup() + * + ****************************************************************************/ + +int inode_search(FAR struct inode_search_s *desc, FAR struct inode **inode); + +/**************************************************************************** + * Name: inode_search_setup + * + * Description: + * Initialize a search descriptor and make 'path' host-absolute: join + * $PWD if it is relative, prepend the chroot jail if one is installed, + * and canonicalize "." / "..". * ****************************************************************************/ -int inode_search(FAR struct inode_search_s *desc); +int inode_search_setup(FAR struct inode_search_s *desc, + FAR const char *path, bool nofollow); + +/**************************************************************************** + * Name: inode_search_release + * + * Description: + * Release any buffer allocated by inode_search_setup(). + * + ****************************************************************************/ + +void inode_search_release(FAR struct inode_search_s *desc); /**************************************************************************** * Name: inode_find @@ -260,9 +261,13 @@ int inode_search(FAR struct inode_search_s *desc); * difference between inode_find() and inode_search is that inode_find() * will lock the inode tree and increment the reference count on the inode. * + * Input Parameters: + * desc - Search descriptor initialized with inode_search_setup() + * inode - OUTPUT: The found inode. Must not be NULL. + * ****************************************************************************/ -int inode_find(FAR struct inode_search_s *desc); +int inode_find(FAR struct inode_search_s *desc, FAR struct inode **inode); /**************************************************************************** * Name: inode_stat diff --git a/fs/littlefs/lfs_vfs.c b/fs/littlefs/lfs_vfs.c index e1853421c43..8cc3c0585e1 100644 --- a/fs/littlefs/lfs_vfs.c +++ b/fs/littlefs/lfs_vfs.c @@ -37,6 +37,7 @@ #include <nuttx/fs/fs.h> #include <nuttx/fs/ioctl.h> #include <nuttx/kmalloc.h> +#include <nuttx/lib/lib.h> #include <nuttx/mtd/mtd.h> #include <nuttx/mutex.h> @@ -901,10 +902,12 @@ static int littlefs_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case FIOC_FILEPATH: { FAR char *path = (FAR char *)(uintptr_t)arg; + ret = inode_getpath(inode, path, PATH_MAX); if (ret >= 0) { size_t len = strlen(path); + if (path[len - 1] != '/') { path[len++] = '/'; diff --git a/fs/mount/fs_automount.c b/fs/mount/fs_automount.c index 2d5988aeea4..1afc7ac46ab 100644 --- a/fs/mount/fs_automount.c +++ b/fs/mount/fs_automount.c @@ -397,6 +397,7 @@ static int automount_ioctl(FAR struct file *filep, int cmd, static int automount_findinode(FAR const char *path) { struct inode_search_s desc; + FAR struct inode *inode; int ret; /* Make sure that we were given a path */ @@ -409,9 +410,14 @@ static int automount_findinode(FAR const char *path) /* Find the inode */ - SETUP_SEARCH(&desc, path, false); + ret = inode_search_setup(&desc, path, false); + if (ret < 0) + { + inode_runlock(); + return ret; + } - ret = inode_search(&desc); + ret = inode_search(&desc, &inode); /* Did we find it? */ @@ -424,7 +430,7 @@ static int automount_findinode(FAR const char *path) /* Yes.. is it a mount point? */ - else if (INODE_IS_MOUNTPT(desc.node)) + else if (INODE_IS_MOUNTPT(inode)) { /* Yes.. we found a mountpoint at this path */ @@ -440,7 +446,7 @@ static int automount_findinode(FAR const char *path) /* Relinquish our exclusive access to the inode try and return the result */ inode_runlock(); - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return ret; } @@ -807,6 +813,7 @@ FAR void *automount_initialize(FAR const struct automount_lower_s *lower) int ret; #ifdef CONFIG_FS_AUTOMOUNTER_DRIVER FAR char *devpath = lib_get_pathbuffer(); + if (devpath == NULL) { return NULL; @@ -917,6 +924,7 @@ void automount_uninitialize(FAR void *handle) if (priv->registered) { FAR char *devpath = lib_get_pathbuffer(); + if (devpath == NULL) { return; diff --git a/fs/mount/fs_mount.c b/fs/mount/fs_mount.c index 39c87e95cda..75eeb3c6874 100644 --- a/fs/mount/fs_mount.c +++ b/fs/mount/fs_mount.c @@ -372,24 +372,26 @@ int nx_mount(FAR const char *source, FAR const char *target, { ferr("ERROR: Failed to find block driver %s\n", source); - ret = -ENOTBLK; - goto errout; + return -ENOTBLK; } inode_lock(); #ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS /* Check if the inode already exists */ - SETUP_SEARCH(&desc, target, false); + ret = inode_search_setup(&desc, target, false); + if (ret < 0) + { + goto errout_with_lock; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &mountpt_inode); if (ret >= 0) { /* Successfully found. The reference count on the inode has been * incremented. */ - mountpt_inode = desc.node; DEBUGASSERT(mountpt_inode != NULL); /* But is it a directory node (i.e., not a driver or other special @@ -401,7 +403,7 @@ int nx_mount(FAR const char *source, FAR const char *target, ferr("ERROR: target %s exists and is a special node\n", target); ret = -ENOTDIR; inode_release(mountpt_inode); - goto errout_with_lock; + goto errout_with_search; } /* Require search on ancestors and write on the mount target. */ @@ -410,7 +412,7 @@ int nx_mount(FAR const char *source, FAR const char *target, if (ret < 0) { inode_release(mountpt_inode); - goto errout_with_lock; + goto errout_with_search; } } #endif @@ -426,7 +428,7 @@ int nx_mount(FAR const char *source, FAR const char *target, ferr("ERROR: Filesystem does not support bind\n"); ret = -EINVAL; - goto errout_with_lock; + goto errout_with_search; } /* Increment reference count for the reference we pass to the file system */ @@ -468,7 +470,7 @@ int nx_mount(FAR const char *source, FAR const char *target, } #endif - goto errout_with_lock; + goto errout_with_search; } /* Insert a dummy node -- we need to hold the inode semaphore @@ -521,7 +523,7 @@ int nx_mount(FAR const char *source, FAR const char *target, #endif #ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS - RELEASE_SEARCH(&desc); + inode_search_release(&desc); #endif #ifdef CONFIG_FS_NOTIFY notify_create(target); @@ -536,11 +538,13 @@ errout_with_bind: mops->unbind(fshandle, &drvr_inode, 0); } -errout_with_lock: - inode_unlock(); +errout_with_search: #ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS - RELEASE_SEARCH(&desc); + inode_search_release(&desc); + +errout_with_lock: #endif + inode_unlock(); errout_with_inode: #if defined(BDFS_SUPPORT) || defined(MDFS_SUPPORT) @@ -550,7 +554,6 @@ errout_with_inode: } #endif -errout: return ret; #else diff --git a/fs/mount/fs_umount2.c b/fs/mount/fs_umount2.c index a0cced51370..6ac21c7f405 100644 --- a/fs/mount/fs_umount2.c +++ b/fs/mount/fs_umount2.c @@ -72,9 +72,13 @@ int nx_umount2(FAR const char *target, unsigned int flags) /* Find the mountpt */ - SETUP_SEARCH(&desc, target, false); + ret = inode_search_setup(&desc, target, false); + if (ret < 0) + { + return ret; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &mountpt_inode); if (ret < 0) { goto errout_with_search; @@ -82,7 +86,6 @@ int nx_umount2(FAR const char *target, unsigned int flags) /* Get the search results */ - mountpt_inode = desc.node; DEBUGASSERT(mountpt_inode != NULL); /* Verify that the inode is a mountpoint */ @@ -189,7 +192,7 @@ int nx_umount2(FAR const char *target, unsigned int flags) inode_release(blkdrvr_inode); } - RELEASE_SEARCH(&desc); + inode_search_release(&desc); #ifdef CONFIG_FS_NOTIFY notify_unmount(target); #endif @@ -208,7 +211,7 @@ errout_with_mountpt: } errout_with_search: - RELEASE_SEARCH(&desc); + inode_search_release(&desc); errout: return ret; diff --git a/fs/mqueue/mq_open.c b/fs/mqueue/mq_open.c index 798ece2e264..cd6d05983a2 100644 --- a/fs/mqueue/mq_open.c +++ b/fs/mqueue/mq_open.c @@ -174,15 +174,13 @@ static int file_mq_vopen(FAR struct file *mq, FAR const char *mq_name, if (!mq || !mq_name || *mq_name == '\0') { - ret = -EINVAL; - goto errout; + return -EINVAL; } if (sizeof(CONFIG_FS_MQUEUE_VFS_PATH) + 1 + strlen(mq_name) >= MAX_MQUEUE_PATH) { - ret = -ENAMETOOLONG; - goto errout; + return -ENAMETOOLONG; } /* Were we asked to create it? */ @@ -199,8 +197,7 @@ static int file_mq_vopen(FAR struct file *mq, FAR const char *mq_name, { if (attr->mq_maxmsg <= 0 || attr->mq_msgsize <= 0) { - ret = -EINVAL; - goto errout; + return -EINVAL; } } } @@ -235,15 +232,17 @@ static int file_mq_vopen(FAR struct file *mq, FAR const char *mq_name, * have incremented the reference count on the inode. */ - SETUP_SEARCH(&desc, fullpath, false); + ret = inode_search_setup(&desc, fullpath, false); + if (ret < 0) + { + goto errout_with_lock; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &inode); if (ret >= 0) { /* Something exists at this path. Get the search results */ - inode = desc.node; - /* Verify that the inode is a message queue */ if (!INODE_IS_MQUEUE(inode)) @@ -301,7 +300,7 @@ static int file_mq_vopen(FAR struct file *mq, FAR const char *mq_name, /* The mqueue does not exist and O_CREAT is not set */ ret = -ENOENT; - goto errout_with_lock; + goto errout_with_search; } /* Create an inode in the pseudo-filesystem at this path */ @@ -312,7 +311,7 @@ static int file_mq_vopen(FAR struct file *mq, FAR const char *mq_name, if (ret < 0) { - goto errout_with_lock; + goto errout_with_search; } /* Allocate memory for the new message queue. The new inode will @@ -345,7 +344,7 @@ static int file_mq_vopen(FAR struct file *mq, FAR const char *mq_name, } } - RELEASE_SEARCH(&desc); + inode_search_release(&desc); leave_critical_section(flags); #ifdef CONFIG_FS_NOTIFY notify_open(fullpath, oflags); @@ -355,11 +354,11 @@ static int file_mq_vopen(FAR struct file *mq, FAR const char *mq_name, errout_with_inode: inode_release(inode); +errout_with_search: + inode_search_release(&desc); + errout_with_lock: - RELEASE_SEARCH(&desc); leave_critical_section(flags); - -errout: return ret; } diff --git a/fs/mqueue/mq_unlink.c b/fs/mqueue/mq_unlink.c index 508231ee6f4..107683b1a59 100644 --- a/fs/mqueue/mq_unlink.c +++ b/fs/mqueue/mq_unlink.c @@ -113,9 +113,13 @@ int file_mq_unlink(FAR const char *mq_name) /* Get the inode for this message queue. */ - SETUP_SEARCH(&desc, fullpath, false); + ret = inode_search_setup(&desc, fullpath, false); + if (ret < 0) + { + return ret; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &inode); if (ret < 0) { /* There is no inode that includes in this path */ @@ -125,8 +129,6 @@ int file_mq_unlink(FAR const char *mq_name) /* Get the search results */ - inode = desc.node; - /* Verify that what we found is, indeed, a message queue */ if (!INODE_IS_MQUEUE(inode)) @@ -172,7 +174,7 @@ int file_mq_unlink(FAR const char *mq_name) inode_unlock(); mq_inode_release(inode); - RELEASE_SEARCH(&desc); + inode_search_release(&desc); #ifdef CONFIG_FS_NOTIFY notify_unlink(fullpath); #endif @@ -185,7 +187,7 @@ errout_with_inode: inode_release(inode); errout_with_search: - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return ret; } diff --git a/fs/partition/fs_partition.c b/fs/partition/fs_partition.c index 9bb6fab7356..e751d00e336 100644 --- a/fs/partition/fs_partition.c +++ b/fs/partition/fs_partition.c @@ -29,6 +29,8 @@ #include <assert.h> #include <stdio.h> +#include <nuttx/lib/lib.h> + #include "driver/driver.h" #include "partition.h" diff --git a/fs/semaphore/sem_open.c b/fs/semaphore/sem_open.c index 491e34945d2..f39f6f2e5e3 100644 --- a/fs/semaphore/sem_open.c +++ b/fs/semaphore/sem_open.c @@ -111,15 +111,17 @@ int nxsem_open(FAR sem_t **sem, FAR const char *name, int oflags, ...) * will have incremented the reference count on the inode. */ - SETUP_SEARCH(&desc, fullpath, false); + ret = inode_search_setup(&desc, fullpath, false); + if (ret < 0) + { + return ret; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &inode); if (ret >= 0) { /* Something exists at this path. Get the search results */ - inode = desc.node; - /* Verify that the inode is a semaphore */ if (!INODE_IS_NAMEDSEM(inode)) @@ -231,7 +233,7 @@ int nxsem_open(FAR sem_t **sem, FAR const char *name, int oflags, ...) *sem = &nsem->ns_sem; } - RELEASE_SEARCH(&desc); + inode_search_release(&desc); #ifdef CONFIG_FS_NOTIFY notify_open(fullpath, oflags); #endif @@ -241,7 +243,7 @@ errout_with_inode: inode_release(inode); errout_with_search: - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return ret; } diff --git a/fs/semaphore/sem_unlink.c b/fs/semaphore/sem_unlink.c index 9fde96acc95..2aab6528777 100644 --- a/fs/semaphore/sem_unlink.c +++ b/fs/semaphore/sem_unlink.c @@ -78,9 +78,13 @@ int nxsem_unlink(FAR const char *name) /* Get the inode for this semaphore. */ - SETUP_SEARCH(&desc, fullpath, false); + ret = inode_search_setup(&desc, fullpath, false); + if (ret < 0) + { + return ret; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &inode); if (ret < 0) { /* There is no inode that includes in this path */ @@ -90,8 +94,6 @@ int nxsem_unlink(FAR const char *name) /* Get the search results */ - inode = desc.node; - /* Verify that what we found is, indeed, a semaphore */ if (!INODE_IS_NAMEDSEM(inode)) @@ -136,7 +138,7 @@ int nxsem_unlink(FAR const char *name) inode_unlock(); ret = nxsem_close(&inode->u.i_nsem->ns_sem); - RELEASE_SEARCH(&desc); + inode_search_release(&desc); #ifdef CONFIG_FS_NOTIFY notify_unlink(fullpath); #endif @@ -149,6 +151,6 @@ errout_with_inode: inode_release(inode); errout_with_search: - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return ret; } diff --git a/fs/shm/shm_open.c b/fs/shm/shm_open.c index e7db849cb90..c3360265951 100644 --- a/fs/shm/shm_open.c +++ b/fs/shm/shm_open.c @@ -82,23 +82,25 @@ static int file_shm_open(FAR struct file *shm, FAR const char *name, /* Get the inode for this shm object */ - SETUP_SEARCH(&desc, fullpath, false); + ret = inode_search_setup(&desc, fullpath, false); + if (ret < 0) + { + return ret; + } inode_lock(); - ret = inode_find(&desc); + ret = inode_find(&desc, &inode); if (ret >= 0) { /* Something exists at this path. Get the search results */ - inode = desc.node; - /* Verify that the inode is an shm object */ if (!INODE_IS_SHM(inode)) { ret = -EINVAL; inode_release(inode); - goto errout_with_sem; + goto errout_with_lock; } /* It exists and is an shm object. Check if the caller wanted to @@ -109,7 +111,7 @@ static int file_shm_open(FAR struct file *shm, FAR const char *name, { ret = -EEXIST; inode_release(inode); - goto errout_with_sem; + goto errout_with_lock; } #ifdef CONFIG_FS_PERMISSION @@ -117,7 +119,7 @@ static int file_shm_open(FAR struct file *shm, FAR const char *name, if (ret < 0) { inode_release(inode); - goto errout_with_sem; + goto errout_with_lock; } #endif @@ -141,7 +143,7 @@ static int file_shm_open(FAR struct file *shm, FAR const char *name, /* The shm does not exist and O_CREAT is not set */ ret = -ENOENT; - goto errout_with_sem; + goto errout_with_lock; } /* Create an inode in the pseudo-filesystem at this path */ @@ -149,7 +151,7 @@ static int file_shm_open(FAR struct file *shm, FAR const char *name, ret = inode_reserve(fullpath, mode, &inode); if (ret < 0) { - goto errout_with_sem; + goto errout_with_lock; } INODE_SET_SHM(inode); @@ -163,9 +165,9 @@ static int file_shm_open(FAR struct file *shm, FAR const char *name, shm->f_oflags = oflags | O_NOFOLLOW; shm->f_inode = inode; -errout_with_sem: +errout_with_lock: inode_unlock(); - RELEASE_SEARCH(&desc); + inode_search_release(&desc); #ifdef CONFIG_FS_NOTIFY if (ret >= 0) { diff --git a/fs/shm/shm_unlink.c b/fs/shm/shm_unlink.c index bd4850c8294..67960392f48 100644 --- a/fs/shm/shm_unlink.c +++ b/fs/shm/shm_unlink.c @@ -77,21 +77,23 @@ static int file_shm_unlink(FAR const char *name) /* Get the inode for this shm object */ - SETUP_SEARCH(&desc, fullpath, false); + ret = inode_search_setup(&desc, fullpath, false); + if (ret < 0) + { + return ret; + } inode_lock(); - ret = inode_find(&desc); + ret = inode_find(&desc, &inode); if (ret < 0) { /* There is no inode that includes in this path */ - goto errout_with_sem; + goto errout_with_lock; } /* Get the search results */ - inode = desc.node; - /* Verify that what we found is, indeed, an shm inode */ if (!INODE_IS_SHM(inode)) @@ -134,9 +136,9 @@ static int file_shm_unlink(FAR const char *name) errout_with_inode: inode_release(inode); -errout_with_sem: +errout_with_lock: inode_unlock(); - RELEASE_SEARCH(&desc); + inode_search_release(&desc); #ifdef CONFIG_FS_NOTIFY if (ret >= 0) { diff --git a/fs/unionfs/fs_unionfs.c b/fs/unionfs/fs_unionfs.c index 87da2bd577a..06b86cd32a5 100644 --- a/fs/unionfs/fs_unionfs.c +++ b/fs/unionfs/fs_unionfs.c @@ -2538,9 +2538,13 @@ static int unionfs_getmount(FAR const char *path, FAR struct inode **inode) /* Find the mountpt */ - SETUP_SEARCH(&desc, path, false); + ret = inode_search_setup(&desc, path, false); + if (ret < 0) + { + return ret; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &minode); if (ret < 0) { /* Mountpoint inode not found */ @@ -2550,7 +2554,6 @@ static int unionfs_getmount(FAR const char *path, FAR struct inode **inode) /* Get the search results */ - minode = desc.node; DEBUGASSERT(minode != NULL); /* Verify that the inode is a mountpoint. @@ -2571,14 +2574,14 @@ static int unionfs_getmount(FAR const char *path, FAR struct inode **inode) /* Success! */ *inode = minode; - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return OK; errout_with_inode: inode_release(minode); errout_with_search: - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return ret; } diff --git a/fs/vfs/fs_chstat.c b/fs/vfs/fs_chstat.c index a8adcb342a3..6fdc6e31a48 100644 --- a/fs/vfs/fs_chstat.c +++ b/fs/vfs/fs_chstat.c @@ -54,9 +54,13 @@ static int chstat_recursive(FAR const char *path, /* Get an inode for this path */ - SETUP_SEARCH(&desc, path, true); + ret = inode_search_setup(&desc, path, true); + if (ret < 0) + { + return ret; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &inode); if (ret < 0) { /* This name does not refer to an inode in the pseudo file system and @@ -68,7 +72,6 @@ static int chstat_recursive(FAR const char *path, /* Get the search results */ - inode = desc.node; DEBUGASSERT(inode != NULL); ret = inode_checkpathperm(inode, 0, 0); @@ -113,7 +116,7 @@ static int chstat_recursive(FAR const char *path, inode_release(inode); errout_with_search: - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return ret; } diff --git a/fs/vfs/fs_close.c b/fs/vfs/fs_close.c index aa8ddbf5b33..4f87712cab4 100644 --- a/fs/vfs/fs_close.c +++ b/fs/vfs/fs_close.c @@ -34,6 +34,7 @@ #include <nuttx/cancelpt.h> #include <nuttx/fs/fs.h> +#include <nuttx/lib/lib.h> #ifdef CONFIG_FDSAN # include <android/fdsan.h> diff --git a/fs/vfs/fs_link.c b/fs/vfs/fs_link.c index 2b8c652a67a..e31b73d2232 100644 --- a/fs/vfs/fs_link.c +++ b/fs/vfs/fs_link.c @@ -80,36 +80,37 @@ int link(FAR const char *path1, FAR const char *path2) struct inode_search_s desc_path2; FAR struct inode *target = NULL; FAR struct inode *newinode = NULL; - int errcode; int ret; if (path1 == NULL || path2 == NULL) { - errcode = EINVAL; + ret = -EINVAL; goto errout; } if (*path1 == '\0' || *path2 == '\0') { - errcode = ENOENT; + ret = -ENOENT; goto errout; } - SETUP_SEARCH(&desc_path1, path1, false); - ret = inode_find(&desc_path1); + ret = inode_search_setup(&desc_path1, path1, false); if (ret < 0) { - errcode = -ret; - goto errout_with_search_path1; + goto errout; } - target = desc_path1.node; + ret = inode_find(&desc_path1, &target); + if (ret < 0) + { + goto errout_with_search_path1; + } if (INODE_GET_NLINK(target) >= _POSIX_LINK_MAX) { /* Too many links to the target inode */ - errcode = EMLINK; + ret = -EMLINK; goto errout_with_target; } @@ -117,13 +118,15 @@ int link(FAR const char *path1, FAR const char *path2) * 'path2' does not lie on a mounted volume. */ - SETUP_SEARCH(&desc_path2, path2, true); + ret = inode_search_setup(&desc_path2, path2, true); + if (ret < 0) + { + goto errout_with_target; + } - ret = inode_find(&desc_path2); + ret = inode_find(&desc_path2, &newinode); if (ret >= 0) { - newinode = desc_path2.node; - /* Something exists at the path2 where we are trying to create the * link. */ @@ -138,7 +141,7 @@ int link(FAR const char *path1, FAR const char *path2) if (newinode != target) { - errcode = EXDEV; + ret = -EXDEV; goto errout_with_newinode; } @@ -152,7 +155,6 @@ int link(FAR const char *path1, FAR const char *path2) desc_path2.relpath); if (ret < 0) { - errcode = -ret; goto errout_with_newinode; } } @@ -160,7 +162,7 @@ int link(FAR const char *path1, FAR const char *path2) { /* Hard links within this type of fs are not supported */ - errcode = ENOSYS; + ret = -ENOSYS; goto errout_with_newinode; } } @@ -169,7 +171,7 @@ int link(FAR const char *path1, FAR const char *path2) { /* A node already exists in the pseudofs at 'path2' */ - errcode = EEXIST; + ret = -EEXIST; goto errout_with_newinode; } } @@ -187,7 +189,6 @@ int link(FAR const char *path1, FAR const char *path2) if (ret != -ENOENT && ret != -ENOTDIR) { - errcode = -ret; goto errout_with_newinode; } @@ -195,7 +196,7 @@ int link(FAR const char *path1, FAR const char *path2) if (INODE_IS_MOUNTPT(target)) { - errcode = EXDEV; + ret = -EXDEV; goto errout_with_newinode; } @@ -216,15 +217,14 @@ int link(FAR const char *path1, FAR const char *path2) inode_unlock(); if (ret < 0) { - errcode = -ret; goto errout_with_newinode; } } /* Hard link successfully created */ - RELEASE_SEARCH(&desc_path1); - RELEASE_SEARCH(&desc_path2); + inode_search_release(&desc_path1); + inode_search_release(&desc_path2); inode_release(target); #ifdef CONFIG_FS_NOTIFY @@ -234,14 +234,14 @@ int link(FAR const char *path1, FAR const char *path2) errout_with_newinode: inode_release(newinode); - RELEASE_SEARCH(&desc_path2); + inode_search_release(&desc_path2); errout_with_target: inode_release(target); errout_with_search_path1: - RELEASE_SEARCH(&desc_path1); + inode_search_release(&desc_path1); errout: - set_errno(errcode); + set_errno(-ret); return ERROR; } diff --git a/fs/vfs/fs_mkdir.c b/fs/vfs/fs_mkdir.c index 6efc790ed11..8f0d6613f46 100644 --- a/fs/vfs/fs_mkdir.c +++ b/fs/vfs/fs_mkdir.c @@ -64,28 +64,30 @@ int mkdir(const char *pathname, mode_t mode) { struct inode_search_s desc; FAR struct inode *inode; - int errcode; int ret; mode &= ~getumask(); /* Find the inode that includes this path */ - SETUP_SEARCH(&desc, pathname, false); + ret = inode_search_setup(&desc, pathname, false); + if (ret < 0) + { + goto errout; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &inode); if (ret >= 0) { /* An inode was found that includes this path and possibly refers to a * mountpoint. */ - inode = desc.node; DEBUGASSERT(inode != NULL); if (desc.relpath[0] == '\0') { - errcode = EEXIST; + ret = -EEXIST; goto errout_with_inode; } @@ -96,14 +98,13 @@ int mkdir(const char *pathname, mode_t mode) { /* The inode is not a mountpoint */ - errcode = ENXIO; + ret = -ENXIO; goto errout_with_inode; } ret = inode_checkpathperm(inode, 0, 0); if (ret < 0) { - errcode = -ret; goto errout_with_inode; } @@ -116,13 +117,12 @@ int mkdir(const char *pathname, mode_t mode) ret = inode->u.i_mops->mkdir(inode, desc.relpath, mode); if (ret < 0) { - errcode = -ret; goto errout_with_inode; } } else { - errcode = ENOSYS; + ret = -ENOSYS; goto errout_with_inode; } @@ -132,7 +132,7 @@ int mkdir(const char *pathname, mode_t mode) #else /* But mountpoints are not supported in this configuration */ - errcode = EEXIST; + ret = -EEXIST; goto errout_with_inode; #endif } @@ -159,21 +159,20 @@ int mkdir(const char *pathname, mode_t mode) if (ret < 0) { - errcode = -ret; goto errout_with_search; } } #else else { - errcode = ENXIO; + ret = -ENXIO; goto errout_with_search; } #endif /* Directory successfully created */ - RELEASE_SEARCH(&desc); + inode_search_release(&desc); #ifdef CONFIG_FS_NOTIFY notify_mkdir(pathname); #endif @@ -183,8 +182,10 @@ errout_with_inode: inode_release(inode); errout_with_search: - RELEASE_SEARCH(&desc); - set_errno(errcode); + inode_search_release(&desc); + +errout: + set_errno(-ret); return ERROR; } diff --git a/fs/vfs/fs_open.c b/fs/vfs/fs_open.c index 35518d77fbf..d4b13b8d4de 100644 --- a/fs/vfs/fs_open.c +++ b/fs/vfs/fs_open.c @@ -100,15 +100,19 @@ static int file_vopen(FAR struct file *filep, FAR const char *path, /* Get an inode for this file */ - SETUP_SEARCH(&desc, path, (oflags & O_NOFOLLOW) != 0); + ret = inode_search_setup(&desc, path, (oflags & O_NOFOLLOW) != 0); + if (ret < 0) + { + return ret; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &inode); if (ret < 0) { #ifdef CONFIG_PSEUDOFS_FILE if ((oflags & O_CREAT) != 0) { - ret = pseudofile_create(&desc.node, path, mode); + ret = pseudofile_create(&inode, path, mode); } #endif @@ -125,7 +129,6 @@ static int file_vopen(FAR struct file *filep, FAR const char *path, /* Get the search results */ - inode = desc.node; DEBUGASSERT(inode != NULL); #ifdef CONFIG_FS_LINKS @@ -161,7 +164,7 @@ static int file_vopen(FAR struct file *filep, FAR const char *path, /* Release the inode reference */ inode_release(inode); - RELEASE_SEARCH(&desc); + inode_search_release(&desc); /* Get the file structure of the opened character driver proxy */ @@ -264,7 +267,7 @@ static int file_vopen(FAR struct file *filep, FAR const char *path, goto errout_with_inode; } - RELEASE_SEARCH(&desc); + inode_search_release(&desc); #ifdef CONFIG_FS_NOTIFY notify_open(path, filep->f_oflags); #endif @@ -275,7 +278,7 @@ errout_with_inode: inode_release(inode); errout_with_search: - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return ret; } diff --git a/fs/vfs/fs_readlink.c b/fs/vfs/fs_readlink.c index ad301ec46b3..51f09ad18cc 100644 --- a/fs/vfs/fs_readlink.c +++ b/fs/vfs/fs_readlink.c @@ -71,7 +71,6 @@ ssize_t readlink(FAR const char *path, FAR char *buf, size_t bufsize) { struct inode_search_s desc; FAR struct inode *node; - int errcode; int ret; DEBUGASSERT(path != NULL && buf != NULL && bufsize > 0); @@ -80,18 +79,18 @@ ssize_t readlink(FAR const char *path, FAR char *buf, size_t bufsize) * symbolic link node. */ - SETUP_SEARCH(&desc, path, true); + ret = inode_search_setup(&desc, path, true); + if (ret < 0) + { + goto errout; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &node); if (ret < 0) { - errcode = -ret; goto errout_with_search; } - /* Get the search results */ - - node = desc.node; DEBUGASSERT(node != NULL); #ifndef CONFIG_DISABLE_MOUNTPOINT @@ -106,13 +105,12 @@ ssize_t readlink(FAR const char *path, FAR char *buf, size_t bufsize) ret = node->u.i_mops->readlink(node, desc.relpath, buf, bufsize); if (ret < 0) { - errcode = -ret; goto errout_with_inode; } } else { - errcode = ENOSYS; + ret = -ENOSYS; goto errout_with_inode; } } @@ -122,7 +120,6 @@ ssize_t readlink(FAR const char *path, FAR char *buf, size_t bufsize) ret = inode_checkpathperm(node, 0, 0); if (ret < 0) { - errcode = -ret; goto errout_with_inode; } @@ -134,7 +131,7 @@ ssize_t readlink(FAR const char *path, FAR char *buf, size_t bufsize) if (!INODE_IS_SOFTLINK(node)) { - errcode = EINVAL; + ret = -EINVAL; goto errout_with_inode; } @@ -146,15 +143,17 @@ ssize_t readlink(FAR const char *path, FAR char *buf, size_t bufsize) /* Release our reference on the inode and return the length */ inode_release(node); - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return strlen(buf); errout_with_inode: inode_release(node); errout_with_search: - RELEASE_SEARCH(&desc); - set_errno(errcode); + inode_search_release(&desc); + +errout: + set_errno(-ret); return ERROR; } diff --git a/fs/vfs/fs_rename.c b/fs/vfs/fs_rename.c index 571320420c0..7bfb580c2c2 100644 --- a/fs/vfs/fs_rename.c +++ b/fs/vfs/fs_rename.c @@ -71,7 +71,6 @@ static int pseudorename(FAR const char *oldpath, FAR struct inode *oldinode, FAR const char *newpath) { struct inode_search_s newdesc; - struct inode_search_s olddesc; FAR struct inode *newinode; FAR char *subdir = NULL; #ifdef CONFIG_FS_NOTIFY @@ -86,7 +85,11 @@ static int pseudorename(FAR const char *oldpath, FAR struct inode *oldinode, inode_lock(); - SETUP_SEARCH(&newdesc, newpath, true); + ret = inode_search_setup(&newdesc, newpath, true); + if (ret < 0) + { + goto errout_with_lock; + } /* Ancestor X_OK was already checked by rename() via * inode_checkpathperm(oldinode, ...). Still require parent W_OK here @@ -96,19 +99,18 @@ static int pseudorename(FAR const char *oldpath, FAR struct inode *oldinode, ret = inode_checkperm(oldparent, W_OK); if (ret < 0) { - goto errout_with_lock; + goto errout_with_newsearch; } /* According to POSIX, any new inode at this path should be removed * first, provided that it is not a directory. */ - ret = inode_search(&newdesc); + ret = inode_search(&newdesc, &newinode); if (ret >= 0) { /* We found it. Get the search results */ - newinode = newdesc.node; DEBUGASSERT(newinode != NULL); /* If the old and new inodes are the same, then this is an attempt to @@ -118,7 +120,7 @@ static int pseudorename(FAR const char *oldpath, FAR struct inode *oldinode, if (oldinode == newinode) { ret = OK; - goto errout_with_lock; + goto errout_with_newsearch; } #ifndef CONFIG_DISABLE_MOUNTPOINT @@ -127,7 +129,7 @@ static int pseudorename(FAR const char *oldpath, FAR struct inode *oldinode, if (INODE_IS_MOUNTPT(newinode)) { ret = -EXDEV; - goto errout_with_lock; + goto errout_with_newsearch; } #endif @@ -154,7 +156,7 @@ static int pseudorename(FAR const char *oldpath, FAR struct inode *oldinode, { subdir = NULL; ret = -ENOMEM; - goto errout_with_lock; + goto errout_with_newsearch; } newpath = subdir; @@ -174,7 +176,7 @@ static int pseudorename(FAR const char *oldpath, FAR struct inode *oldinode, ret = inode_remove(newpath); if (ret < 0 && ret != -EBUSY) { - goto errout_with_lock; + goto errout_with_newsearch; } #ifdef CONFIG_FS_NOTIFY @@ -191,19 +193,7 @@ static int pseudorename(FAR const char *oldpath, FAR struct inode *oldinode, ret = inode_reserve(newpath, 0777, &newinode); if (ret < 0) { - goto errout_with_lock; - } - - /* Re-resolve the source under the same lock before unlinking it. */ - - SETUP_SEARCH(&olddesc, oldpath, true); - ret = inode_search(&olddesc); - RELEASE_SEARCH(&olddesc); - if (ret < 0 || olddesc.node != oldinode) - { - inode_remove(newpath); - ret = -ENOENT; - goto errout_with_lock; + goto errout_with_newsearch; } /* Copy the inode state from the old inode to the newly allocated inode */ @@ -248,7 +238,7 @@ static int pseudorename(FAR const char *oldpath, FAR struct inode *oldinode, /* Remove the new node we just recreated */ inode_remove(newpath); - goto errout_with_lock; + goto errout_with_newsearch; } /* Remove all of the children from the unlinked inode */ @@ -257,8 +247,10 @@ static int pseudorename(FAR const char *oldpath, FAR struct inode *oldinode, oldinode->i_parent = NULL; ret = OK; +errout_with_newsearch: + inode_search_release(&newdesc); + errout_with_lock: - RELEASE_SEARCH(&newdesc); inode_unlock(); #ifdef CONFIG_FS_NOTIFY @@ -315,8 +307,13 @@ static int mountptrename(FAR const char *oldpath, FAR struct inode *oldinode, * mountpoint */ - SETUP_SEARCH(&newdesc, newpath, true); - ret = inode_find(&newdesc); + ret = inode_search_setup(&newdesc, newpath, true); + if (ret < 0) + { + return ret; + } + + ret = inode_find(&newdesc, &newinode); if (ret < 0) { /* There is no mountpoint that includes in this path */ @@ -326,7 +323,6 @@ static int mountptrename(FAR const char *oldpath, FAR struct inode *oldinode, /* Get the search results */ - newinode = newdesc.node; newrelpath = newdesc.relpath; DEBUGASSERT(newinode != NULL && newrelpath != NULL); @@ -512,7 +508,7 @@ errout_with_newinode: inode_release(newinode); errout_with_newsearch: - RELEASE_SEARCH(&newdesc); + inode_search_release(&newdesc); if (subdir != NULL) { fs_heap_free(subdir); @@ -553,8 +549,13 @@ int rename(FAR const char *oldpath, FAR const char *newpath) /* Get an inode that includes the oldpath */ - SETUP_SEARCH(&olddesc, oldpath, true); - ret = inode_find(&olddesc); + ret = inode_search_setup(&olddesc, oldpath, true); + if (ret < 0) + { + goto errout; + } + + ret = inode_find(&olddesc, &oldinode); if (ret < 0) { /* There is no inode that includes in this path */ @@ -562,9 +563,6 @@ int rename(FAR const char *oldpath, FAR const char *newpath) goto errout_with_oldsearch; } - /* Get the search results */ - - oldinode = olddesc.node; DEBUGASSERT(oldinode != NULL); ret = inode_checkpathperm(oldinode, 0, 0); @@ -594,7 +592,7 @@ int rename(FAR const char *oldpath, FAR const char *newpath) inode_release(oldinode); errout_with_oldsearch: - RELEASE_SEARCH(&olddesc); + inode_search_release(&olddesc); errout: if (ret < 0) diff --git a/fs/vfs/fs_rmdir.c b/fs/vfs/fs_rmdir.c index f2911085d53..bcf4dab1a9f 100644 --- a/fs/vfs/fs_rmdir.c +++ b/fs/vfs/fs_rmdir.c @@ -62,7 +62,6 @@ int rmdir(FAR const char *pathname) { struct inode_search_s desc; FAR struct inode *inode; - int errcode; int ret; /* Get an inode for the directory (or for the mountpoint containing the @@ -70,20 +69,20 @@ int rmdir(FAR const char *pathname) * on the inode if one is found. */ - SETUP_SEARCH(&desc, pathname, true); + ret = inode_search_setup(&desc, pathname, true); + if (ret < 0) + { + goto errout; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &inode); if (ret < 0) { /* There is no inode that includes in this path */ - errcode = -ret; goto errout_with_search; } - /* Get the search results */ - - inode = desc.node; DEBUGASSERT(inode != NULL); #ifndef CONFIG_DISABLE_MOUNTPOINT @@ -94,7 +93,6 @@ int rmdir(FAR const char *pathname) ret = inode_checkpathperm(inode, 0, 0); if (ret < 0) { - errcode = -ret; goto errout_with_inode; } @@ -107,13 +105,12 @@ int rmdir(FAR const char *pathname) ret = inode->u.i_mops->rmdir(inode, desc.relpath); if (ret < 0) { - errcode = -ret; goto errout_with_inode; } } else { - errcode = ENOSYS; + ret = -ENOSYS; goto errout_with_inode; } } @@ -133,7 +130,7 @@ int rmdir(FAR const char *pathname) if (inode->i_child) { - errcode = ENOTEMPTY; + ret = -ENOTEMPTY; goto errout_with_inode; } @@ -149,26 +146,25 @@ int rmdir(FAR const char *pathname) if (ret < 0 && ret != -EBUSY) { - errcode = -ret; goto errout_with_inode; } } else { - errcode = ENOTDIR; + ret = -ENOTDIR; goto errout_with_inode; } #else - { - errcode = ENXIO; - goto errout_with_inode; - } + { + ret = -ENXIO; + goto errout_with_inode; + } #endif /* Successfully removed the directory */ inode_release(inode); - RELEASE_SEARCH(&desc); + inode_search_release(&desc); #ifdef CONFIG_FS_NOTIFY notify_unlink(pathname); #endif @@ -177,8 +173,9 @@ int rmdir(FAR const char *pathname) errout_with_inode: inode_release(inode); errout_with_search: - RELEASE_SEARCH(&desc); - set_errno(errcode); + inode_search_release(&desc); +errout: + set_errno(-ret); return ERROR; } diff --git a/fs/vfs/fs_stat.c b/fs/vfs/fs_stat.c index 9eefb401e5e..f5b7586a341 100644 --- a/fs/vfs/fs_stat.c +++ b/fs/vfs/fs_stat.c @@ -88,9 +88,13 @@ static int stat_recursive(FAR const char *path, /* Get an inode for this path */ - SETUP_SEARCH(&desc, path, true); + ret = inode_search_setup(&desc, path, true); + if (ret < 0) + { + return ret; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &inode); if (ret < 0) { /* This name does not refer to an inode in the pseudo file system and @@ -102,7 +106,6 @@ static int stat_recursive(FAR const char *path, /* Get the search results */ - inode = desc.node; DEBUGASSERT(inode != NULL); ret = inode_checkpathperm(inode, 0, 0); @@ -153,7 +156,7 @@ static int stat_recursive(FAR const char *path, inode_release(inode); errout_with_search: - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return ret; } diff --git a/fs/vfs/fs_statfs.c b/fs/vfs/fs_statfs.c index 70d796c3b5f..212ee783a9a 100644 --- a/fs/vfs/fs_statfs.c +++ b/fs/vfs/fs_statfs.c @@ -93,9 +93,13 @@ int statfs(FAR const char *path, FAR struct statfs *buf) /* Get an inode for this file */ - SETUP_SEARCH(&desc, path, false); + ret = inode_search_setup(&desc, path, false); + if (ret < 0) + { + goto errout; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &inode); if (ret < 0) { /* This name does not refer to a psudeo-inode and there is no @@ -107,7 +111,6 @@ int statfs(FAR const char *path, FAR struct statfs *buf) /* Get the search results */ - inode = desc.node; DEBUGASSERT(inode != NULL); ret = inode_checkpathperm(inode, 0, 0); @@ -154,7 +157,7 @@ int statfs(FAR const char *path, FAR struct statfs *buf) /* Successfully statfs'ed the file */ inode_release(inode); - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return OK; /* Failure conditions always set the errno appropriately */ @@ -163,7 +166,7 @@ errout_with_inode: inode_release(inode); errout_with_search: - RELEASE_SEARCH(&desc); + inode_search_release(&desc); errout: set_errno(-ret); diff --git a/fs/vfs/fs_symlink.c b/fs/vfs/fs_symlink.c index 76cac2bad73..5ced61110e0 100644 --- a/fs/vfs/fs_symlink.c +++ b/fs/vfs/fs_symlink.c @@ -81,12 +81,11 @@ int symlink(FAR const char *path1, FAR const char *path2) { struct inode_search_s desc; FAR struct inode *inode = NULL; - int errcode; int ret; if (path1 == NULL) { - errcode = EINVAL; + ret = -EINVAL; goto errout; } @@ -94,9 +93,13 @@ int symlink(FAR const char *path1, FAR const char *path2) * 'path2' does not lie on a mounted volume. */ - SETUP_SEARCH(&desc, path2, false); + ret = inode_search_setup(&desc, path2, false); + if (ret < 0) + { + goto errout; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &inode); if (ret >= 0) { /* Something exists at the path2 where we are trying to create the @@ -106,16 +109,15 @@ int symlink(FAR const char *path1, FAR const char *path2) #ifndef CONFIG_DISABLE_MOUNTPOINT /* Check if the inode is a mountpoint. */ - DEBUGASSERT(desc.node != NULL); - if (INODE_IS_MOUNTPT(desc.node)) + DEBUGASSERT(inode != NULL); + if (INODE_IS_MOUNTPT(inode)) { - if (desc.node->u.i_mops && desc.node->u.i_mops->symlink) + if (inode->u.i_mops && inode->u.i_mops->symlink) { - ret = desc.node->u.i_mops->symlink(desc.node, path1, - desc.relpath); + ret = inode->u.i_mops->symlink(inode, path1, + desc.relpath); if (ret < 0) { - errcode = -ret; goto errout_with_inode; } } @@ -123,7 +125,7 @@ int symlink(FAR const char *path1, FAR const char *path2) { /* Symbolic links within this type of fs are not supported */ - errcode = ENOSYS; + ret = -ENOSYS; goto errout_with_inode; } } @@ -132,7 +134,7 @@ int symlink(FAR const char *path1, FAR const char *path2) { /* A node already exists in the pseudofs at 'path1' */ - errcode = EEXIST; + ret = -EEXIST; goto errout_with_inode; } } @@ -149,7 +151,7 @@ int symlink(FAR const char *path1, FAR const char *path2) if (newpath2 == NULL) { - errcode = ENOMEM; + ret = -ENOMEM; goto errout_with_search; } @@ -173,14 +175,13 @@ int symlink(FAR const char *path1, FAR const char *path2) if (ret < 0) { fs_heap_free(newpath2); - errcode = -ret; goto errout_with_search; } } /* Symbolic link successfully created */ - RELEASE_SEARCH(&desc); + inode_search_release(&desc); #ifdef CONFIG_FS_NOTIFY notify_create(path2); #endif @@ -190,10 +191,10 @@ errout_with_inode: inode_release(inode); errout_with_search: - RELEASE_SEARCH(&desc); + inode_search_release(&desc); errout: - set_errno(errcode); + set_errno(-ret); return ERROR; } diff --git a/fs/vfs/fs_unlink.c b/fs/vfs/fs_unlink.c index 9d7be5dc545..eb890f43a2c 100644 --- a/fs/vfs/fs_unlink.c +++ b/fs/vfs/fs_unlink.c @@ -68,9 +68,13 @@ int nx_unlink(FAR const char *pathname) * which may be a symbolic link) */ - SETUP_SEARCH(&desc, pathname, true); + ret = inode_search_setup(&desc, pathname, true); + if (ret < 0) + { + return ret; + } - ret = inode_find(&desc); + ret = inode_find(&desc, &inode); if (ret < 0) { /* There is no inode that includes in this path */ @@ -78,9 +82,6 @@ int nx_unlink(FAR const char *pathname) goto errout_with_search; } - /* Get the search results */ - - inode = desc.node; DEBUGASSERT(inode != NULL); #ifndef CONFIG_DISABLE_MOUNTPOINT @@ -193,7 +194,7 @@ int nx_unlink(FAR const char *pathname) /* Successfully unlinked */ inode_release(inode); - RELEASE_SEARCH(&desc); + inode_search_release(&desc); #ifdef CONFIG_FS_NOTIFY notify_unlink(pathname); #endif @@ -205,7 +206,7 @@ errout_with_inode: #endif errout_with_search: - RELEASE_SEARCH(&desc); + inode_search_release(&desc); return ret; }
