Soft Links: Fix several issues in initial testing
This commit is contained in:
parent
b39d962021
commit
d833144869
@ -186,6 +186,7 @@ static inline FAR struct inode *
|
|||||||
_inode_dereference(FAR struct inode *node, FAR struct inode **peer,
|
_inode_dereference(FAR struct inode *node, FAR struct inode **peer,
|
||||||
FAR struct inode **parent, FAR const char **relpath)
|
FAR struct inode **parent, FAR const char **relpath)
|
||||||
{
|
{
|
||||||
|
FAR const char *copy;
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
|
|
||||||
/* An infinite loop is avoided only by the loop count.
|
/* An infinite loop is avoided only by the loop count.
|
||||||
@ -196,9 +197,14 @@ _inode_dereference(FAR struct inode *node, FAR struct inode **peer,
|
|||||||
|
|
||||||
while (node != NULL && INODE_IS_SOFTLINK(node))
|
while (node != NULL && INODE_IS_SOFTLINK(node))
|
||||||
{
|
{
|
||||||
node = inode_search_nofollow((FAR const char **)&node->u.i_link,
|
/* Careful: inode_search_nofollow overwrites the input string pointer */
|
||||||
peer, parent, relpath);
|
|
||||||
if (++count > SYMLOOP_MAX)
|
copy = (FAR const char *)node->u.i_link;
|
||||||
|
|
||||||
|
/* Now, look-up the inode associated with the target path */
|
||||||
|
|
||||||
|
node = inode_search_nofollow(©, peer, parent, relpath);
|
||||||
|
if (node == NULL && ++count > SYMLOOP_MAX)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -348,6 +354,20 @@ FAR struct inode *inode_search(FAR const char **path,
|
|||||||
FAR struct inode *node = g_root_inode;
|
FAR struct inode *node = g_root_inode;
|
||||||
FAR struct inode *left = NULL;
|
FAR struct inode *left = NULL;
|
||||||
FAR struct inode *above = NULL;
|
FAR struct inode *above = NULL;
|
||||||
|
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
|
||||||
|
FAR struct inode *newnode;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
|
||||||
|
/* Handle the case were the root node is a symbolic link */
|
||||||
|
|
||||||
|
#warning Missing logic
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Traverse the pseudo file system node tree until either (1) all nodes
|
||||||
|
* have been examined without finding the matching node, or (2) the
|
||||||
|
* matching node is found.
|
||||||
|
*/
|
||||||
|
|
||||||
while (node != NULL)
|
while (node != NULL)
|
||||||
{
|
{
|
||||||
@ -383,13 +403,32 @@ FAR struct inode *inode_search(FAR const char **path,
|
|||||||
FAR const char *nextname = inode_nextname(name);
|
FAR const char *nextname = inode_nextname(name);
|
||||||
if (*nextname != '\0')
|
if (*nextname != '\0')
|
||||||
{
|
{
|
||||||
node = _inode_dereference(node, NULL, &above, relpath);
|
newnode = _inode_dereference(node, NULL, &above, relpath);
|
||||||
if (node == NULL)
|
if (newnode == NULL)
|
||||||
{
|
{
|
||||||
|
/* Probably means that the node is a symbolic link, but
|
||||||
|
* that the target of the symbolic link does not exist.
|
||||||
|
*/
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if (newnode != node)
|
||||||
|
{
|
||||||
|
/* The node was a valid symbolic link and we have jumped to a
|
||||||
|
* different, spot in the the pseudo file system tree. Reset
|
||||||
|
* everything and continue looking at the next level "down"
|
||||||
|
* from that new spot in the tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
above = newnode;
|
||||||
|
left = NULL;
|
||||||
|
node = newnode->i_child;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/* Continue looking to the left */
|
||||||
|
|
||||||
left = node;
|
left = node;
|
||||||
node = node->i_peer;
|
node = node->i_peer;
|
||||||
}
|
}
|
||||||
@ -429,7 +468,7 @@ FAR struct inode *inode_search(FAR const char **path,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* More to go.. */
|
/* More nodes to be examined in the path... */
|
||||||
|
|
||||||
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
|
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
|
||||||
/* If this intermediate inode in the is a soft link, then (1)
|
/* If this intermediate inode in the is a soft link, then (1)
|
||||||
@ -438,13 +477,46 @@ FAR struct inode *inode_search(FAR const char **path,
|
|||||||
* continue searching with that inode instead.
|
* continue searching with that inode instead.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
node = _inode_dereference(node, NULL, NULL, relpath);
|
newnode = _inode_dereference(node, NULL, NULL, relpath);
|
||||||
if (node == NULL)
|
if (newnode == NULL)
|
||||||
{
|
{
|
||||||
|
/* Probably means that the node is a symbolic link, but
|
||||||
|
* that the target of the symbolic link does not exist.
|
||||||
|
*/
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
else if (newnode != node)
|
||||||
|
{
|
||||||
|
/* The node was a valid symbolic link and we have jumped to a
|
||||||
|
* different, spot in the the pseudo file system tree. Reset
|
||||||
|
* everything and continue looking to the right (if possible)
|
||||||
|
* otherwise at the next level "down" from that new spot in
|
||||||
|
* the tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (newnode->i_peer != NULL)
|
||||||
|
{
|
||||||
|
above = NULL; /* REVISIT: This can't be right */
|
||||||
|
left = newnode;
|
||||||
|
node = newnode->i_peer;
|
||||||
|
|
||||||
|
/* Did the symbolic link take us to a mountpoint? */
|
||||||
|
|
||||||
|
if (INODE_IS_MOUNTPT(newnode))
|
||||||
|
{
|
||||||
|
/* Yes.. return the mountpoint information */
|
||||||
|
|
||||||
|
if (relpath)
|
||||||
|
{
|
||||||
|
*relpath = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/* Keep looking at the next level "down" */
|
/* Keep looking at the next level "down" */
|
||||||
|
|
||||||
above = node;
|
above = node;
|
||||||
|
@ -58,6 +58,11 @@
|
|||||||
* path refers to. This is normally done in preparation to removing or
|
* path refers to. This is normally done in preparation to removing or
|
||||||
* moving an inode.
|
* moving an inode.
|
||||||
*
|
*
|
||||||
|
* In symbolic links in the pseduo file system are enabled, then this
|
||||||
|
* logic will follow the symbolic links up until the terminal node. Then
|
||||||
|
* that link in removed. So if this the terminal node is a symbolic link,
|
||||||
|
* the symbolic link node will be removed, not the target of the link.
|
||||||
|
*
|
||||||
* Assumptions/Limitations:
|
* Assumptions/Limitations:
|
||||||
* The caller must hold the inode semaphore
|
* The caller must hold the inode semaphore
|
||||||
*
|
*
|
||||||
@ -79,7 +84,7 @@ FAR struct inode *inode_unlink(FAR const char *path)
|
|||||||
|
|
||||||
/* Find the node to unlink */
|
/* Find the node to unlink */
|
||||||
|
|
||||||
node = inode_search(&name, &peer, &parent, (const char **)NULL);
|
node = inode_search_nofollow(&name, &peer, &parent, (const char **)NULL);
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
/* If peer is non-null, then remove the node from the right of
|
/* If peer is non-null, then remove the node from the right of
|
||||||
|
Loading…
Reference in New Issue
Block a user