From 4c68324d823dcf24a3f1e0dea191e97587cb811f Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 4 Feb 2017 12:51:14 -0600 Subject: [PATCH] FS: Remove inode_search_nofollow(). That logic is no handled with a new field in the input argument structure. --- fs/dirent/fs_opendir.c | 6 +-- fs/inode/fs_inodefind.c | 18 ++++--- fs/inode/fs_inoderemove.c | 7 ++- fs/inode/fs_inodesearch.c | 111 ++++++++++++++++---------------------- fs/inode/inode.h | 64 +++++++++++----------- 5 files changed, 96 insertions(+), 110 deletions(-) diff --git a/fs/dirent/fs_opendir.c b/fs/dirent/fs_opendir.c index c883290ddee..b577abeb033 100644 --- a/fs/dirent/fs_opendir.c +++ b/fs/dirent/fs_opendir.c @@ -267,9 +267,9 @@ FAR DIR *opendir(FAR const char *path) /* Did we get an inode? */ - if (!inode) + if (inode == NULL) { - /* 'path' does not exist. */ + /* Inode for 'path' does not exist. */ ret = ENOTDIR; goto errout_with_semaphore; @@ -336,7 +336,7 @@ FAR DIR *opendir(FAR const char *path) */ FAR struct inode *child = inode->i_child; - if (child) + if (child != NULL) { /* It looks we have a valid pseudo-filesystem directory node. */ diff --git a/fs/inode/fs_inodefind.c b/fs/inode/fs_inodefind.c index c4ba53182f7..0fd1caf7900 100644 --- a/fs/inode/fs_inodefind.c +++ b/fs/inode/fs_inodefind.c @@ -52,15 +52,14 @@ ****************************************************************************/ /**************************************************************************** - * Name: inode_find and indode_find_nofollow + * Name: inode_find * * Description: * This is called from the open() logic to get a reference to the inode - * associated with a path. - * - * Both versions will follow soft links in path leading up to the terminal - * node. inode_find() will deference that terminal node, - * indode_find_nofollow no follow will not. + * associated with a path. This is accomplished by calling inode_search(). + * The primary difference between inode_find() and inode_search is (1) in + * the form of the input paramters and return value and (2) inode_find() + * will lock the inode tree and increment the reference count on the inode. * ****************************************************************************/ @@ -81,10 +80,13 @@ FAR struct inode *inode_find(FAR const char *path, FAR const char **relpath, */ memset(&desc, 0, sizeof(struct inode_search_s)); - desc.path = path; + desc.path = path; +#ifdef CONFIG_PSEUDOFS_SOFTLINKS + desc.nofollow = nofollow; +#endif inode_semtake(); - ret = nofollow ? inode_search_nofollow(&desc) : inode_search(&desc); + ret = inode_search(&desc); if (ret >= 0) { /* Found it */ diff --git a/fs/inode/fs_inoderemove.c b/fs/inode/fs_inoderemove.c index cdaeab6e83d..477b7514b0e 100644 --- a/fs/inode/fs_inoderemove.c +++ b/fs/inode/fs_inoderemove.c @@ -85,9 +85,12 @@ FAR struct inode *inode_unlink(FAR const char *path) /* Find the node to unlink */ memset(&desc, 0, sizeof(struct inode_search_s)); - desc.path = path; + desc.path = path; +#ifdef CONFIG_PSEUDOFS_SOFTLINKS + desc.nofollow = true; +#endif - ret = inode_search_nofollow(&desc); + ret = inode_search(&desc); if (ret >= 0) { node = desc.node; diff --git a/fs/inode/fs_inodesearch.c b/fs/inode/fs_inodesearch.c index a65c9988257..cdc8a18722a 100644 --- a/fs/inode/fs_inodesearch.c +++ b/fs/inode/fs_inodesearch.c @@ -39,8 +39,8 @@ #include -#include #include +#include #include #include @@ -153,26 +153,29 @@ static int inode_linktarget(FAR struct inode *node, FAR struct inode_search_s *desc) { unsigned int count = 0; + bool save; int ret = -ENOENT; DEBUGASSERT(desc != NULL && node != NULL); /* An infinite loop is avoided only by the loop count. - * + * * REVISIT: The ELOOP error should be reported to the application in that * case but there is no simple mechanism to do that. */ + save = desc->nofollow; while (INODE_IS_SOFTLINK(node)) { - /* Now, look-up the inode associated with the target path */ + /* Reset and reinitialize the search descriptor. */ memset(desc, 0, sizeof(struct inode_search_s)); - desc->path = (FAR const char *)node->u.i_link; + desc->path = (FAR const char *)node->u.i_link; + desc->nofollow = true; - /* Look up the target of the symbolic link */ + /* Look up inode associated with the target of the symbolic link */ - ret = inode_search_nofollow(desc); + ret = inode_search(desc); if (ret < 0) { break; @@ -191,6 +194,7 @@ static int inode_linktarget(FAR struct inode *node, node = desc->node; } + desc->nofollow = save; return ret; } #endif @@ -200,29 +204,30 @@ static int inode_linktarget(FAR struct inode *node, ****************************************************************************/ /**************************************************************************** - * Name: inode_search and inode_search_nofollow + * Name: inode_search * * Description: * Find the inode associated with 'path' returning the inode references * and references to its companion nodes. * - * Both versions will follow soft links in path leading up to the terminal - * node. inode_search() will deference that terminal node, - * inode_search_nofollow will not. + * 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 that WILL be deferenced and the mountpoint inode will be returned. + * that link WILL be deferenced unconditionally. * * Assumptions: * The caller holds the g_inode_sem semaphore * ****************************************************************************/ -#ifdef CONFIG_PSEUDOFS_SOFTLINKS -int inode_search_nofollow(FAR struct inode_search_s *desc) -#else int inode_search(FAR struct inode_search_s *desc) -#endif { FAR const char *name; FAR struct inode *node = g_root_inode; @@ -300,15 +305,34 @@ int inode_search(FAR struct inode_search_s *desc) */ relpath = name; + ret = OK; #ifdef CONFIG_PSEUDOFS_SOFTLINKS - /* NOTE that if the terminal inode is a soft link, it is not - * deferenced in this case. The raw inode is returned. - * - * In that case a wrapper function will perform that operation. - */ + /* Is the terminal node a softlink? Should we follow it? */ + + if (!desc->nofollow && INODE_IS_SOFTLINK(node)) + { + int status; + + /* The terminating inode is a valid soft link: Return the + * inode, corresponding to link target. + */ + + status = inode_linktarget(node, desc); + if (status < 0) + { + ret = status; + } + else + { + /* Return, skipping setting of 'desc' return values + * at the normal exit point. + */ + + return OK; + } + } #endif - ret = OK; break; } else @@ -408,51 +432,6 @@ int inode_search(FAR struct inode_search_s *desc) return ret; } -#ifdef CONFIG_PSEUDOFS_SOFTLINKS -int inode_search(FAR struct inode_search_s *desc) -{ - int ret; - - /* Lookup the terminal inode */ - - ret = inode_search_nofollow(desc); - - /* Did we find it? inode_search_nofollow() will terminate in one of - * three ways: - * - * 1. With an error (node == NULL) - * 2. With node referring to the terminal inode which may be a symbolic - * link, or - * 3. with node referring to an intermediate MOUNTPOINT inode with the - * residual path in relpath. - * - * REVISIT: The relpath is incorrect in the final case. It will be relative - * to symbolic link, not to the root of the mount. - */ - - if (ret >= 0) - { - /* Sucessfully found inode */ - - FAR struct inode *node = desc->node; - DEBUGASSERT(node != NULL); - - /* Is the terminal node a softlink? */ - - if (INODE_IS_SOFTLINK(node)) - { - /* The terminating inode is a valid soft link: Return the inode, - * corresponding to link target. - */ - - ret = inode_linktarget(node, desc); - } - } - - return ret; -} -#endif - /**************************************************************************** * Name: inode_nextname * diff --git a/fs/inode/inode.h b/fs/inode/inode.h index ea15b6631ae..b88ae487aac 100644 --- a/fs/inode/inode.h +++ b/fs/inode/inode.h @@ -55,17 +55,21 @@ ****************************************************************************/ /* This is the type of the argument to inode_search(). * - * 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) - * OUTPUT: The inode to the "above" of the inode found. - * relpath - INPUT: (not used) - * OUTPUT: If the returned inode is a mountpoint, this is the - * relative path from the mountpoint. + * 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) + * OUTPUT: The inode to the "above" of the inode found. + * relpath - INPUT: (not used) + * OUTPUT: If the returned inode is a mountpoint, this is the + * relative path from the mountpoint. + * nofollow - INPUT: true: terminal node is returned; false: if the + * terminal is a soft link, then return the inode of + * the link target. + * - OUTPUT: (not used) */ struct inode_search_s @@ -75,6 +79,9 @@ struct inode_search_s 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 */ +#ifdef CONFIG_PSEUDOFS_SOFTLINKS + bool nofollow; /* true: Don't follow terminal soft link */ +#endif }; /* Callback used by foreach_inode to traverse all inodes in the pseudo- @@ -136,18 +143,23 @@ void inode_semtake(void); void inode_semgive(void); /**************************************************************************** - * Name: inode_search and inode_search_nofollow + * Name: inode_search * * Description: * Find the inode associated with 'path' returning the inode references * and references to its companion nodes. * - * Both versions will follow soft links in path leading up to the terminal - * node. inode_search() will deference that terminal node, - * inode_search_nofollow will not. + * 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 that WILL be deferenced and the mountpoint inode will be returned. + * that link WILL be deferenced unconditionally. * * Assumptions: * The caller holds the g_inode_sem semaphore @@ -156,12 +168,6 @@ void inode_semgive(void); int inode_search(FAR struct inode_search_s *desc); -#ifdef CONFIG_PSEUDOFS_SOFTLINKS -int inode_search_nofollow(FAR struct inode_search_s *desc); -#else -# define inode_search_nofollow(d) inode_search(d) -#endif - /**************************************************************************** * Name: inode_free * @@ -239,18 +245,14 @@ FAR struct inode *inode_unlink(FAR const char *path); int inode_remove(FAR const char *path); /**************************************************************************** - * Name: inode_find and indode_find_nofollow + * Name: inode_find * * Description: * This is called from the open() logic to get a reference to the inode - * associated with a path. - * - * Both versions will follow soft links in path leading up to the terminal - * node. inode_find() will deference that terminal node, - * indode_find_nofollow no follow will not. - * - * If a soft link is encounter that is not the terminal node in the path, - * that that WILL be deferenced and the mountpoint inode will be returned. + * associated with a path. This is accomplished by calling inode_search(). + * The primary difference between inode_find() and inode_search is (1) in + * the form of the input paramters and return value and (2) inode_find() + * will lock the inode tree and increment the reference count on the inode. * ****************************************************************************/