FS: Remove inode_search_nofollow(). That logic is no handled with a new field in the input argument structure.

This commit is contained in:
Gregory Nutt 2017-02-04 12:51:14 -06:00
parent 0c9935f8ac
commit 4c68324d82
5 changed files with 96 additions and 110 deletions

View File

@ -267,9 +267,9 @@ FAR DIR *opendir(FAR const char *path)
/* Did we get an inode? */ /* Did we get an inode? */
if (!inode) if (inode == NULL)
{ {
/* 'path' does not exist. */ /* Inode for 'path' does not exist. */
ret = ENOTDIR; ret = ENOTDIR;
goto errout_with_semaphore; goto errout_with_semaphore;
@ -336,7 +336,7 @@ FAR DIR *opendir(FAR const char *path)
*/ */
FAR struct inode *child = inode->i_child; FAR struct inode *child = inode->i_child;
if (child) if (child != NULL)
{ {
/* It looks we have a valid pseudo-filesystem directory node. */ /* It looks we have a valid pseudo-filesystem directory node. */

View File

@ -52,15 +52,14 @@
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: inode_find and indode_find_nofollow * Name: inode_find
* *
* Description: * Description:
* This is called from the open() logic to get a reference to the inode * This is called from the open() logic to get a reference to the inode
* associated with a path. * associated with a path. This is accomplished by calling inode_search().
* * The primary difference between inode_find() and inode_search is (1) in
* Both versions will follow soft links in path leading up to the terminal * the form of the input paramters and return value and (2) inode_find()
* node. inode_find() will deference that terminal node, * will lock the inode tree and increment the reference count on the inode.
* indode_find_nofollow no follow will not.
* *
****************************************************************************/ ****************************************************************************/
@ -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)); memset(&desc, 0, sizeof(struct inode_search_s));
desc.path = path; desc.path = path;
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
desc.nofollow = nofollow;
#endif
inode_semtake(); inode_semtake();
ret = nofollow ? inode_search_nofollow(&desc) : inode_search(&desc); ret = inode_search(&desc);
if (ret >= 0) if (ret >= 0)
{ {
/* Found it */ /* Found it */

View File

@ -85,9 +85,12 @@ FAR struct inode *inode_unlink(FAR const char *path)
/* Find the node to unlink */ /* Find the node to unlink */
memset(&desc, 0, sizeof(struct inode_search_s)); 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) if (ret >= 0)
{ {
node = desc.node; node = desc.node;

View File

@ -39,8 +39,8 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <limits.h>
#include <string.h> #include <string.h>
#include <limits.h>
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
@ -153,26 +153,29 @@ static int inode_linktarget(FAR struct inode *node,
FAR struct inode_search_s *desc) FAR struct inode_search_s *desc)
{ {
unsigned int count = 0; unsigned int count = 0;
bool save;
int ret = -ENOENT; int ret = -ENOENT;
DEBUGASSERT(desc != NULL && node != NULL); DEBUGASSERT(desc != NULL && node != NULL);
/* An infinite loop is avoided only by the loop count. /* An infinite loop is avoided only by the loop count.
* *
* REVISIT: The ELOOP error should be reported to the application in that * REVISIT: The ELOOP error should be reported to the application in that
* case but there is no simple mechanism to do that. * case but there is no simple mechanism to do that.
*/ */
save = desc->nofollow;
while (INODE_IS_SOFTLINK(node)) 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)); 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) if (ret < 0)
{ {
break; break;
@ -191,6 +194,7 @@ static int inode_linktarget(FAR struct inode *node,
node = desc->node; node = desc->node;
} }
desc->nofollow = save;
return ret; return ret;
} }
#endif #endif
@ -200,29 +204,30 @@ static int inode_linktarget(FAR struct inode *node,
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: inode_search and inode_search_nofollow * Name: inode_search
* *
* Description: * Description:
* Find the inode associated with 'path' returning the inode references * Find the inode associated with 'path' returning the inode references
* and references to its companion nodes. * and references to its companion nodes.
* *
* Both versions will follow soft links in path leading up to the terminal * If a mountpoint is encountered in the search prior to encountering the
* node. inode_search() will deference that terminal node, * terminal node, the search will terminate at the mountpoint inode. That
* inode_search_nofollow will not. * 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, * 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: * Assumptions:
* The caller holds the g_inode_sem semaphore * 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) int inode_search(FAR struct inode_search_s *desc)
#endif
{ {
FAR const char *name; FAR const char *name;
FAR struct inode *node = g_root_inode; FAR struct inode *node = g_root_inode;
@ -300,15 +305,34 @@ int inode_search(FAR struct inode_search_s *desc)
*/ */
relpath = name; relpath = name;
ret = OK;
#ifdef CONFIG_PSEUDOFS_SOFTLINKS #ifdef CONFIG_PSEUDOFS_SOFTLINKS
/* NOTE that if the terminal inode is a soft link, it is not /* Is the terminal node a softlink? Should we follow it? */
* deferenced in this case. The raw inode is returned.
* if (!desc->nofollow && INODE_IS_SOFTLINK(node))
* In that case a wrapper function will perform that operation. {
*/ 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 #endif
ret = OK;
break; break;
} }
else else
@ -408,51 +432,6 @@ int inode_search(FAR struct inode_search_s *desc)
return ret; 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 * Name: inode_nextname
* *

View File

@ -55,17 +55,21 @@
****************************************************************************/ ****************************************************************************/
/* This is the type of the argument to inode_search(). /* This is the type of the argument to inode_search().
* *
* path - INPUT: Path of inode to find * path - INPUT: Path of inode to find
* OUTPUT: Residual part of path not traversed * OUTPUT: Residual part of path not traversed
* node - INPUT: (not used) * node - INPUT: (not used)
* OUTPUT: On success, holds the pointer to the inode found. * OUTPUT: On success, holds the pointer to the inode found.
* peer - INPUT: (not used) * peer - INPUT: (not used)
* OUTPUT: The inode to the "left" of the inode found. * OUTPUT: The inode to the "left" of the inode found.
* parent - INPUT: (not used) * parent - INPUT: (not used)
* OUTPUT: The inode to the "above" of the inode found. * OUTPUT: The inode to the "above" of the inode found.
* relpath - INPUT: (not used) * relpath - INPUT: (not used)
* OUTPUT: If the returned inode is a mountpoint, this is the * OUTPUT: If the returned inode is a mountpoint, this is the
* relative path from the mountpoint. * 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 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 *peer; /* Node to the "left" for the found inode */
FAR struct inode *parent; /* Node "above" the found inode */ FAR struct inode *parent; /* Node "above" the found inode */
FAR const char *relpath; /* Relative path into the mountpoint */ 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- /* Callback used by foreach_inode to traverse all inodes in the pseudo-
@ -136,18 +143,23 @@ void inode_semtake(void);
void inode_semgive(void); void inode_semgive(void);
/**************************************************************************** /****************************************************************************
* Name: inode_search and inode_search_nofollow * Name: inode_search
* *
* Description: * Description:
* Find the inode associated with 'path' returning the inode references * Find the inode associated with 'path' returning the inode references
* and references to its companion nodes. * and references to its companion nodes.
* *
* Both versions will follow soft links in path leading up to the terminal * If a mountpoint is encountered in the search prior to encountering the
* node. inode_search() will deference that terminal node, * terminal node, the search will terminate at the mountpoint inode. That
* inode_search_nofollow will not. * 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, * 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: * Assumptions:
* The caller holds the g_inode_sem semaphore * 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); 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 * Name: inode_free
* *
@ -239,18 +245,14 @@ FAR struct inode *inode_unlink(FAR const char *path);
int inode_remove(FAR const char *path); int inode_remove(FAR const char *path);
/**************************************************************************** /****************************************************************************
* Name: inode_find and indode_find_nofollow * Name: inode_find
* *
* Description: * Description:
* This is called from the open() logic to get a reference to the inode * This is called from the open() logic to get a reference to the inode
* associated with a path. * associated with a path. This is accomplished by calling inode_search().
* * The primary difference between inode_find() and inode_search is (1) in
* Both versions will follow soft links in path leading up to the terminal * the form of the input paramters and return value and (2) inode_find()
* node. inode_find() will deference that terminal node, * will lock the inode tree and increment the reference count on the inode.
* 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.
* *
****************************************************************************/ ****************************************************************************/