diff --git a/fs/dirent/fs_opendir.c b/fs/dirent/fs_opendir.c index 5731ba632b2..c883290ddee 100644 --- a/fs/dirent/fs_opendir.c +++ b/fs/dirent/fs_opendir.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/dirent/fs_opendir.c * - * Copyright (C) 2007-2009, 2011, 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011, 2013-2014, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -226,7 +226,8 @@ FAR DIR *opendir(FAR const char *path) { FAR struct inode *inode = NULL; FAR struct fs_dirent_s *dir; - FAR const char *relpath; + struct inode_search_s desc; + FAR const char *relpath = NULL; bool isroot = false; int ret; @@ -239,7 +240,6 @@ FAR DIR *opendir(FAR const char *path) { inode = g_root_inode; isroot = true; - relpath = NULL; } else { @@ -253,15 +253,23 @@ FAR DIR *opendir(FAR const char *path) /* Find the node matching the path. */ - inode = inode_search(&path, (FAR struct inode**)NULL, - (FAR struct inode**)NULL, &relpath); + memset(&desc, 0, sizeof(struct inode_search_s)); + desc.path = path; + + ret = inode_search(&desc); + if (ret >= 0) + { + inode = desc.node; + DEBUGASSERT(inode != NULL); + relpath = desc.relpath; + } } /* Did we get an inode? */ if (!inode) { - /* 'path' is not a does not exist. */ + /* 'path' does not exist. */ ret = ENOTDIR; goto errout_with_semaphore; @@ -305,9 +313,9 @@ FAR DIR *opendir(FAR const char *path) */ #ifndef CONFIG_DISABLE_MOUNTPOINT - else if (INODE_IS_MOUNTPT(inode)) - { - /* Yes, the node is a file system mountpoint */ + else if (INODE_IS_MOUNTPT(inode)) + { + /* Yes, the node is a file system mountpoint */ dir->fd_root = inode; /* Save the inode where we start */ diff --git a/fs/inode/fs_inodefind.c b/fs/inode/fs_inodefind.c index b5339c9b863..8a101c0bebf 100644 --- a/fs/inode/fs_inodefind.c +++ b/fs/inode/fs_inodefind.c @@ -39,7 +39,10 @@ #include +#include +#include #include + #include #include "inode/inode.h" @@ -63,7 +66,9 @@ FAR struct inode *inode_find(FAR const char *path, FAR const char **relpath) { - FAR struct inode *node; + struct inode_search_s desc; + FAR struct inode *node = NULL; + int ret; if (path == NULL || *path != '/') { @@ -74,12 +79,28 @@ FAR struct inode *inode_find(FAR const char *path, FAR const char **relpath) * references on the node. */ + memset(&desc, 0, sizeof(struct inode_search_s)); + desc.path = path; + inode_semtake(); - node = inode_search(&path, (FAR struct inode**)NULL, - (FAR struct inode**)NULL, relpath); - if (node) + ret = inode_search(&desc); + if (ret >= 0) { + /* Found it */ + + node = desc.node; + DEBUGASSERT(node != NULL); + + /* Increment the reference count on the inode */ + node->i_crefs++; + + /* Return any remaining relative path fragment */ + + if (relpath != NULL) + { + *relpath = desc.relpath; + } } inode_semgive(); @@ -90,7 +111,9 @@ FAR struct inode *inode_find(FAR const char *path, FAR const char **relpath) FAR struct inode *inode_find_nofollow(FAR const char *path, FAR const char **relpath) { - FAR struct inode *node; + struct inode_search_s desc; + FAR struct inode *node = NULL; + int ret; if (path == NULL || *path != '/') { @@ -101,12 +124,28 @@ FAR struct inode *inode_find_nofollow(FAR const char *path, * references on the node. */ + memset(&desc, 0, sizeof(struct inode_search_s)); + desc.path = path; + inode_semtake(); - node = inode_search_nofollow(&path, (FAR struct inode**)NULL, - (FAR struct inode**)NULL, relpath); - if (node) + ret = inode_search_nofollow(&desc); + if (ret >= 0) { + /* Found it */ + + node = desc.node; + DEBUGASSERT(node != NULL); + + /* Increment the reference count on the inode */ + node->i_crefs++; + + /* Return any remaining relative path fragment */ + + if (relpath != NULL) + { + *relpath = desc.relpath; + } } inode_semgive(); diff --git a/fs/inode/fs_inoderemove.c b/fs/inode/fs_inoderemove.c index 6df048dbbe0..cdaeab6e83d 100644 --- a/fs/inode/fs_inoderemove.c +++ b/fs/inode/fs_inoderemove.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/inode/fs_inoderemove.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -39,6 +39,7 @@ #include +#include #include #include @@ -70,10 +71,9 @@ FAR struct inode *inode_unlink(FAR const char *path) { - const char *name = path; + struct inode_search_s desc; FAR struct inode *node; - FAR struct inode *peer; - FAR struct inode *parent; + int ret; /* Verify parameters. Ignore null paths and relative paths */ @@ -84,25 +84,31 @@ FAR struct inode *inode_unlink(FAR const char *path) /* Find the node to unlink */ - node = inode_search_nofollow(&name, &peer, &parent, (const char **)NULL); - if (node) + memset(&desc, 0, sizeof(struct inode_search_s)); + desc.path = path; + + ret = inode_search_nofollow(&desc); + if (ret >= 0) { + node = desc.node; + DEBUGASSERT(node != NULL); + /* If peer is non-null, then remove the node from the right of * of that peer node. */ - if (peer) + if (desc.peer != NULL) { - peer->i_peer = node->i_peer; + desc.peer->i_peer = node->i_peer; } /* If parent is non-null, then remove the node from head of * of the list of children. */ - else if (parent) + else if (desc.parent) { - parent->i_child = node->i_peer; + desc.parent->i_child = node->i_peer; } /* Otherwise, we must be removing the root inode. */ diff --git a/fs/inode/fs_inodereserve.c b/fs/inode/fs_inodereserve.c index d790689de97..0f25e4c8558 100644 --- a/fs/inode/fs_inodereserve.c +++ b/fs/inode/fs_inodereserve.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/inode/fs_registerreserve.c * - * Copyright (C) 2007-2009, 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2012, 2015, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -39,6 +39,7 @@ #include +#include #include #include @@ -163,33 +164,45 @@ static void inode_insert(FAR struct inode *node, int inode_reserve(FAR const char *path, FAR struct inode **inode) { - FAR const char *name = path; + struct inode_search_s desc; FAR struct inode *left; FAR struct inode *parent; + FAR const char *name; + int ret; /* Assume failure */ - DEBUGASSERT(path && inode); + DEBUGASSERT(path != NULL && inode != NULL); *inode = NULL; /* Handle paths that are interpreted as the root directory */ - if (path[0] == '\0' || path[0] != '/' || path[1] == '\0') + if (path[0] == '\0' || path[0] != '/') { return -EINVAL; } /* Find the location to insert the new subtree */ - if (inode_search(&name, &left, &parent, (FAR const char **)NULL) != NULL) + memset(&desc, 0, sizeof(struct inode_search_s)); + desc.path = path; + + ret = inode_search(&desc); + if (ret >= 0) { - /* It is an error if the node already exists in the tree */ + /* It is an error if the node already exists in the tree (or if it + * lies within a mountpoint, we don't distinguish here). + */ return -EEXIST; } /* Now we now where to insert the subtree */ + name = desc.path; + left = desc.peer; + parent = desc.parent; + for (; ; ) { FAR struct inode *node; @@ -199,19 +212,19 @@ int inode_reserve(FAR const char *path, FAR struct inode **inode) * by looking at the next name. */ - FAR const char *next_name = inode_nextname(name); - if (*next_name) + FAR const char *nextname = inode_nextname(name); + if (*nextname != '\0') { /* Insert an operationless node */ node = inode_alloc(name); - if (node) + if (node != NULL) { inode_insert(node, left, parent); /* Set up for the next time through the loop */ - name = next_name; + name = nextname; left = NULL; parent = node; continue; @@ -220,7 +233,7 @@ int inode_reserve(FAR const char *path, FAR struct inode **inode) else { node = inode_alloc(name); - if (node) + if (node != NULL) { inode_insert(node, left, parent); *inode = node; diff --git a/fs/inode/fs_inodesearch.c b/fs/inode/fs_inodesearch.c index f756f4247b4..a65c9988257 100644 --- a/fs/inode/fs_inodesearch.c +++ b/fs/inode/fs_inodesearch.c @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -134,6 +135,66 @@ static int _inode_compare(FAR const char *fname, } } +/**************************************************************************** + * Name: inode_linktarget + * + * Description: + * If the inode is a soft link, then (1) get the name of the full path of + * the soft link, (2) recursively look-up the inode referenced by the soft + * link, and (3) return the inode referenced by the soft link. + * + * Assumptions: + * The caller holds the g_inode_sem semaphore + * + ****************************************************************************/ + +#ifdef CONFIG_PSEUDOFS_SOFTLINKS +static int inode_linktarget(FAR struct inode *node, + FAR struct inode_search_s *desc) +{ + unsigned int count = 0; + 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. + */ + + while (INODE_IS_SOFTLINK(node)) + { + /* Now, look-up the inode associated with the target path */ + + memset(desc, 0, sizeof(struct inode_search_s)); + desc->path = (FAR const char *)node->u.i_link; + + /* Look up the target of the symbolic link */ + + ret = inode_search_nofollow(desc); + if (ret < 0) + { + break; + } + + /* Limit the number of symbolic links that we pass through */ + + if (++count > SYMLOOP_MAX) + { + ret = -ELOOP; + break; + } + + /* Set up for the next time through the loop */ + + node = desc->node; + } + + return ret; +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -158,25 +219,32 @@ static int _inode_compare(FAR const char *fname, ****************************************************************************/ #ifdef CONFIG_PSEUDOFS_SOFTLINKS - -FAR struct inode *inode_search_nofollow(FAR const char **path, - FAR struct inode **peer, - FAR struct inode **parent, - FAR const char **relpath) +int inode_search_nofollow(FAR struct inode_search_s *desc) #else -FAR struct inode *inode_search(FAR const char **path, - FAR struct inode **peer, - FAR struct inode **parent, - FAR const char **relpath) +int inode_search(FAR struct inode_search_s *desc) #endif { - FAR const char *name = *path + 1; /* Skip over leading '/' */ - FAR struct inode *node = g_root_inode; - FAR struct inode *left = NULL; - FAR struct inode *above = NULL; -#ifdef CONFIG_PSEUDOFS_SOFTLINKS - FAR struct inode *newnode; -#endif + FAR const char *name; + FAR struct inode *node = g_root_inode; + FAR struct inode *left = NULL; + FAR struct inode *above = NULL; + FAR const char *relpath = NULL; + int ret = -ENOENT; + + /* Get the search path, skipping over the leading '/'. The leading '/' is + * mandatory because only absolte paths are expected in this context. + */ + + DEBUGASSERT(desc != NULL && desc->path != NULL); + name = desc->path; + + DEBUGASSERT(*name == '/'); + if (*name != '/') + { + return -EINVAL; + } + + name++; /* Skip over the leading '/' */ /* Traverse the pseudo file system node tree until either (1) all nodes * have been examined without finding the matching node, or (2) the @@ -231,10 +299,7 @@ FAR struct inode *inode_search(FAR const char **path, * and will handle the remaining part of the pathname */ - if (relpath) - { - *relpath = name; - } + relpath = name; #ifdef CONFIG_PSEUDOFS_SOFTLINKS /* NOTE that if the terminal inode is a soft link, it is not @@ -243,6 +308,7 @@ FAR struct inode *inode_search(FAR const char **path, * In that case a wrapper function will perform that operation. */ #endif + ret = OK; break; } else @@ -250,49 +316,64 @@ FAR struct inode *inode_search(FAR const char **path, /* More nodes to be examined in the path "below" this one. */ #ifdef CONFIG_PSEUDOFS_SOFTLINKS - /* If this intermediate inode in the is a soft link, then (1) - * get the name of the full path of the soft link, (2) recursively - * look-up the inode referenced by the sof link, and (3) - * continue searching with that inode instead. + /* Was the node a soft link? If so, then we need need to + * continue below the target of the link, not the link itself. */ - newnode = inode_linktarget(node, NULL, NULL, relpath); - if (newnode == NULL) + if (INODE_IS_SOFTLINK(node)) { - /* Probably means that the node is a symbolic link, but - * that the target of the symbolic link does not exist. + int status; + + /* If this intermediate inode in the is a soft link, then + * (1) get the name of the full path of the soft link, (2) + * recursively look-up the inode referenced by the soft + * link, and (3) continue searching with that inode instead. */ - 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. - * - * Continue from this new inode. - */ - - node = newnode; - - /* Check if this took us to a mountpoint. */ - - if (INODE_IS_MOUNTPT(newnode)) + status = inode_linktarget(node, desc); + if (status < 0) { - /* Yes.. return the mountpoint information. - * REVISIT: The relpath is incorrect in this case. It is - * relative to symbolic link, not to the root of the mount. + /* Probably means that the the target of the symbolic + * link does not exist. */ - if (relpath) - { - *relpath = name; - } - - above = NULL; - left = NULL; + ret = status; break; } + else + { + FAR struct inode *newnode = desc->node; + + 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. + * + * Continue from this new inode. + */ + + node = newnode; + + /* Check if this took us to a mountpoint. */ + + if (INODE_IS_MOUNTPT(node)) + { + /* Yes.. return the mountpoint information. + * REVISIT: The relpath is incorrect in this case. + * It is relative to symbolic link, not to the + * root of the mount. + */ + + relpath = name; + above = NULL; + left = NULL; + + ret = OK; + break; + } + } + } } #endif /* Keep looking at the next level "down" */ @@ -319,29 +400,22 @@ FAR struct inode *inode_search(FAR const char **path, * (4) When the node matching the full path is found */ - if (peer) - { - *peer = left; - } - - if (parent) - { - *parent = above; - } - - *path = name; - return node; + desc->path = name; + desc->node = node; + desc->peer = left; + desc->parent = above; + desc->relpath = relpath; + return ret; } #ifdef CONFIG_PSEUDOFS_SOFTLINKS -FAR struct inode *inode_search(FAR const char **path, - FAR struct inode **peer, - FAR struct inode **parent, - FAR const char **relpath) +int inode_search(FAR struct inode_search_s *desc) { + int ret; + /* Lookup the terminal inode */ - FAR struct inode *node = inode_search_nofollow(path, peer, parent, relpath); + ret = inode_search_nofollow(desc); /* Did we find it? inode_search_nofollow() will terminate in one of * three ways: @@ -356,63 +430,26 @@ FAR struct inode *inode_search(FAR const char **path, * to symbolic link, not to the root of the mount. */ - if (node != NULL && INODE_IS_SOFTLINK(node)) + if (ret >= 0) { - /* The terminating inode is a valid soft link: Return the inode, - * corresponding to link target. - */ + /* Sucessfully found inode */ - return inode_linktarget(node, peer, parent, relpath); - } + FAR struct inode *node = desc->node; + DEBUGASSERT(node != NULL); - return node; -} -#endif + /* Is the terminal node a softlink? */ -/**************************************************************************** - * Name: inode_linktarget - * - * Description: - * If the inode is a soft link, then (1) get the name of the full path of - * the soft link, (2) recursively look-up the inode referenced by the soft - * link, and (3) return the inode referenced by the soft link. - * - * Assumptions: - * The caller holds the g_inode_sem semaphore - * - ****************************************************************************/ - -#ifdef CONFIG_PSEUDOFS_SOFTLINKS -FAR struct inode *inode_linktarget(FAR struct inode *node, - FAR struct inode **peer, - FAR struct inode **parent, - FAR const char **relpath) -{ - FAR const char *copy; - unsigned int count = 0; - - /* 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. - */ - - while (node != NULL && INODE_IS_SOFTLINK(node)) - { - /* Careful: inode_search_nofollow overwrites the input string pointer */ - - 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) + if (INODE_IS_SOFTLINK(node)) { - return NULL; + /* The terminating inode is a valid soft link: Return the inode, + * corresponding to link target. + */ + + ret = inode_linktarget(node, desc); } } - return node; + return ret; } #endif diff --git a/fs/inode/inode.h b/fs/inode/inode.h index 2139b5976b5..b14210046ad 100644 --- a/fs/inode/inode.h +++ b/fs/inode/inode.h @@ -52,6 +52,29 @@ /**************************************************************************** * Public Types ****************************************************************************/ +/* 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. + */ + +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 */ +}; /* Callback used by foreach_inode to traverse all inodes in the pseudo- * file system. @@ -130,38 +153,12 @@ void inode_semgive(void); * ****************************************************************************/ -FAR struct inode *inode_search(FAR const char **path, - FAR struct inode **peer, - FAR struct inode **parent, - FAR const char **relpath); +int inode_search(FAR struct inode_search_s *desc); #ifdef CONFIG_PSEUDOFS_SOFTLINKS -FAR struct inode *inode_search_nofollow(FAR const char **path, - FAR struct inode **peer, - FAR struct inode **parent, - FAR const char **relpath); +int inode_search_nofollow(FAR struct inode_search_s *desc); #else -# define inode_search_nofollow(p,l,a,r) inode_search(p,l,a,r) -#endif - -/**************************************************************************** - * Name: inode_linktarget - * - * Description: - * If the inode is a soft link, then (1) get the name of the full path of - * the soft link, (2) recursively look-up the inode referenced by the soft - * link, and (3) return the inode referenced by the soft link. - * - * Assumptions: - * The caller holds the g_inode_sem semaphore - * - ****************************************************************************/ - -#ifdef CONFIG_PSEUDOFS_SOFTLINKS -FAR struct inode *inode_linktarget(FAR struct inode *node, - FAR struct inode **peer, - FAR struct inode **parent, - FAR const char **relpath); +# define inode_search_nofollow(d) inode_search(d) #endif /**************************************************************************** diff --git a/fs/mount/fs_automount.c b/fs/mount/fs_automount.c index 47bc9c01182..4b21e6a9d65 100644 --- a/fs/mount/fs_automount.c +++ b/fs/mount/fs_automount.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/mount/fs_automount.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -124,9 +124,7 @@ static int automount_interrupt(FAR const struct automount_lower_s *lower, static int automount_findinode(FAR const char *path) { - FAR struct inode *node; - FAR const char *srchpath; - FAR const char *relpath; + struct inode_search_s desc; int ret; /* Make sure that we were given an absolute path */ @@ -139,12 +137,14 @@ static int automount_findinode(FAR const char *path) /* Find the inode */ - srchpath = path; - node = inode_search(&srchpath, (FAR struct inode**)NULL, - (FAR struct inode**)NULL, &relpath); + memset(&desc, 0, sizeof(struct inode_search_s)); + desc.path = path; + + ret = inode_search(&desc); + /* Did we find it? */ - if (!node) + if (ret < 0) { /* No.. Not found */ @@ -153,7 +153,7 @@ static int automount_findinode(FAR const char *path) /* Yes.. is it a mount point? */ - else if (INODE_IS_MOUNTPT(node)) + else if (INODE_IS_MOUNTPT(desc.node)) { /* Yes.. we found a mountpoint at this path */ @@ -161,7 +161,7 @@ static int automount_findinode(FAR const char *path) } else { - /* No.. then somethin is in the way */ + /* No.. then something is in the way */ ret = -ENOTDIR; } diff --git a/fs/vfs/fs_stat.c b/fs/vfs/fs_stat.c index c1f2122df67..af9b8574ad6 100644 --- a/fs/vfs/fs_stat.c +++ b/fs/vfs/fs_stat.c @@ -83,11 +83,6 @@ static inline int statpseudo(FAR struct inode *inode, FAR struct stat *buf) } else #endif - { - } - } - else if (inode->u.i_ops != NULL) - { #ifdef CONFIG_PSEUDOFS_SOFTLINKS /* Handle softlinks differently. Just call stat() recursively on the * target of the softlink. @@ -124,39 +119,42 @@ static inline int statpseudo(FAR struct inode *inode, FAR struct stat *buf) } else #endif + { + } + } + else if (inode->u.i_ops != NULL) + { + /* Determine read/write privileges based on the existence of read + * and write methods. + */ + + if (inode->u.i_ops->read) { - /* Determine read/write privileges based on the existence of read - * and write methods. - */ + buf->st_mode = S_IROTH | S_IRGRP | S_IRUSR; + } - if (inode->u.i_ops->read) - { - buf->st_mode = S_IROTH | S_IRGRP | S_IRUSR; - } + if (inode->u.i_ops->write) + { + buf->st_mode |= S_IWOTH | S_IWGRP | S_IWUSR; + } - if (inode->u.i_ops->write) - { - buf->st_mode |= S_IWOTH | S_IWGRP | S_IWUSR; - } + /* Determine the type of the inode */ - /* Determine the type of the inode */ + if (INODE_IS_MOUNTPT(inode)) + { + buf->st_mode |= S_IFDIR; + } + else if (INODE_IS_BLOCK(inode)) + { + /* What is if also has child inodes? */ - if (INODE_IS_MOUNTPT(inode)) - { - buf->st_mode |= S_IFDIR; - } - else if (INODE_IS_BLOCK(inode)) - { - /* What is if also has child inodes? */ + buf->st_mode |= S_IFBLK; + } + else /* if (INODE_IS_DRIVER(inode)) */ + { + /* What is it if it also has child inodes? */ - buf->st_mode |= S_IFBLK; - } - else /* if (INODE_IS_DRIVER(inode)) */ - { - /* What is it if it also has child inodes? */ - - buf->st_mode |= S_IFCHR; - } + buf->st_mode |= S_IFCHR; } } else diff --git a/fs/vfs/fs_unlink.c b/fs/vfs/fs_unlink.c index ea754fed5c6..29afe30e17d 100644 --- a/fs/vfs/fs_unlink.c +++ b/fs/vfs/fs_unlink.c @@ -130,7 +130,13 @@ int unlink(FAR const char *pathname) * or a soft link, then rm should remove the node. */ +#ifdef CONFIG_PSEUDOFS_SOFTLINKS + /* A soft link is the only "specal" file that we can remove via unlink(). */ + + if (!INODE_IS_SPECIAL(inode) || INODE_IS_SOFTLINK(inode)) +#else if (!INODE_IS_SPECIAL(inode)) +#endif { /* If this is a pseudo-file node (i.e., it has no operations) * then unlink should remove the node. diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h index 955d1b2c111..fb6bec49523 100644 --- a/include/nuttx/fs/fs.h +++ b/include/nuttx/fs/fs.h @@ -76,11 +76,11 @@ #define FSNODEFLAG_TYPE_DRIVER 0x00000000 /* Character driver */ #define FSNODEFLAG_TYPE_BLOCK 0x00000001 /* Block driver */ #define FSNODEFLAG_TYPE_MOUNTPT 0x00000002 /* Mount point */ -#define FSNODEFLAG_TYPE_SOFTLINK 0x00000003 /* Soft link */ #define FSNODEFLAG_TYPE_SPECIAL 0x00000004 /* Special OS type */ #define FSNODEFLAG_TYPE_NAMEDSEM 0x00000004 /* Named semaphore */ #define FSNODEFLAG_TYPE_MQUEUE 0x00000005 /* Message Queue */ #define FSNODEFLAG_TYPE_SHM 0x00000006 /* Shared memory region */ +#define FSNODEFLAG_TYPE_SOFTLINK 0x00000007 /* Soft link */ #define FSNODEFLAG_DELETED 0x00000008 /* Unlinked */ #define INODE_IS_TYPE(i,t) \ @@ -91,10 +91,10 @@ #define INODE_IS_DRIVER(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_DRIVER) #define INODE_IS_BLOCK(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_BLOCK) #define INODE_IS_MOUNTPT(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_MOUNTPT) -#define INODE_IS_SOFTLINK(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_SOFTLINK) #define INODE_IS_NAMEDSEM(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_NAMEDSEM) #define INODE_IS_MQUEUE(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_MQUEUE) #define INODE_IS_SHM(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_SHM) +#define INODE_IS_SOFTLINK(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_SOFTLINK) #define INODE_GET_TYPE(i) ((i)->i_flags & FSNODEFLAG_TYPE_MASK) #define INODE_SET_TYPE(i,t) \ @@ -107,10 +107,10 @@ #define INODE_SET_DRIVER(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_DRIVER) #define INODE_SET_BLOCK(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_BLOCK) #define INODE_SET_MOUNTPT(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_MOUNTPT) -#define INODE_SET_SOFTLINK(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_SOFTLINK) #define INODE_SET_NAMEDSEM(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_NAMEDSEM) #define INODE_SET_MQUEUE(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_MQUEUE) #define INODE_SET_SHM(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_SHM) +#define INODE_SET_SOFTLINK(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_SOFTLINK) /* Mountpoint fd_flags values */