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? */
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. */

View File

@ -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 */

View File

@ -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;

View File

@ -39,8 +39,8 @@
#include <nuttx/config.h>
#include <limits.h>
#include <string.h>
#include <limits.h>
#include <assert.h>
#include <errno.h>
@ -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
*

View File

@ -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.
*
****************************************************************************/