Merge branch 'softlink'

This commit is contained in:
Gregory Nutt 2017-02-05 14:57:55 -06:00
commit 8d961ee137
26 changed files with 399 additions and 275 deletions

View File

@ -479,14 +479,14 @@ int task_delete(pid_t pid);
<p>
<b>Description:</b>
This function causes a specified task to cease to exist.
Its stack and TCB will be deallocated.
Its stack and TCB will be deallocated.
This function is the companion to <code>task_create()</code>.
This is the version of the function exposed to the user;
it is simply a wrapper around the internal, <code>task_terminate()</code> function.
</p>
<p>
The logic in this function only deletes non-running tasks.
If the <code>pid</code> parameter refers to to the currently runing task, then processing is redirected to <code>exit()</code>.
If the <code>pid</code> parameter refers to to the currently runing task, then processing is redirected to <code>exit()</code>.
This can only happen if a task calls <code>task_delete()</code> in order to delete itself.
</p>
<p>
@ -6223,7 +6223,7 @@ interface of the same name.
<b>Description:</b>
<p>The <code>pthread_cancel()</code> function will request that thread be canceled.
The target thread's cancelability state, enabled, or disabled, determines when the cancellation takes effect: When the cancellation is acted on, thread will be terminated.
The target thread's cancelability state, enabled, or disabled, determines when the cancellation takes effect: When the cancellation is acted on, thread will be terminated.
When cancelability is disabled, all cancellations are held pending in the target thread until the thread re-enables cancelability.</p>
<p>The target thread's cancelability state determines how the cancellation is acted on:
@ -6592,16 +6592,16 @@ interface of the same name.
</p>
<ul>
<li><code>sched_ss_low_priority</code>
Low scheduling priority for sporadic server.
Low scheduling priority for sporadic server.
</li>
<li><code>sched_ss_repl_period</code>
Replenishment period for sporadic server.
Replenishment period for sporadic server.
</li>
<li><code>sched_ss_init_budget</code>
Initial budget for sporadic server.
Initial budget for sporadic server.
</li>
<li><code>sched_ss_max_repl</code>
Maximum pending replenishments for sporadic server.
Maximum pending replenishments for sporadic server.
</li>
</ul>
<p>
@ -8584,6 +8584,8 @@ int telldir(FAR DIR *dirp);
<ul><pre>
#include &lt;unistd.h&gt;
/* Task Control Interfaces */
pid_t vfork(void);
pid_t getpid(void);
void _exit(int status) noreturn_function;
@ -8591,6 +8593,8 @@ unsigned int sleep(unsigned int seconds);
void usleep(unsigned long usec);
int pause(void);
/* File descriptor operations */
int close(int fd);
int dup(int fd);
int dup2(int fd1, int fd2);
@ -8598,21 +8602,58 @@ int fsync(int fd);
off_t lseek(int fd, off_t offset, int whence);
ssize_t read(int fd, FAR void *buf, size_t nbytes);
ssize_t write(int fd, FAR const void *buf, size_t nbytes);
ssize_t pread(int fd, FAR void *buf, size_t nbytes, off_t offset);
ssize_t pwrite(int fd, FAR const void *buf, size_t nbytes, off_t offset);
/* Check if a file descriptor corresponds to a terminal I/O file */
int isatty(int fd);
/* Memory management */
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_MM_PGALLOC) && \
defined(CONFIG_ARCH_USE_MMU)
FAR void *sbrk(intptr_t incr);
#endif
/* Special devices */
int pipe(int fd[2]);
/* Working directory operations */
int chdir(FAR const char *path);
FAR char *getcwd(FAR char *buf, size_t size);
int unlink(FAR const char *pathname);
/* File path operations */
int access(FAR const char *path, int amode);
int rmdir(FAR const char *pathname);
int unlink(FAR const char *pathname);
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
int link(FAR const char *path1, FAR const char *path2);
ssize_t readlink(FAR const char *path, FAR char *buf, size_t bufsize);
#endif
/* Execution of programs from files */
#ifdef CONFIG_LIBC_EXECFUNCS
int execl(FAR const char *path, ...);
int execv(FAR const char *path, FAR char *const argv[]);
#endif
/* Networking */
#ifdef CONFIG_NET
int gethostname(FAR char *name, size_t size);
int sethostname(FAR const char *name, size_t size);
#endif
/* Other */
int getopt(int argc, FAR char *const argv[], FAR const char *optstring);
</pre></ul>
</a>

View File

@ -43,7 +43,7 @@ config DISABLE_PSEUDOFS_OPERATIONS
config PSEUDOFS_SOFTLINKS
bool "Pseudo-filesystem soft links"
default n
depends on !DISABLE_PSEUDOFS_OPERATIONSi && EXPERIMENTAL
depends on !DISABLE_PSEUDOFS_OPERATIONS
---help---
Enable support for soft links in the pseudeo file system. Soft
links are not supported within mounted volumes by any NuttX file

View File

@ -235,6 +235,8 @@ FAR DIR *opendir(FAR const char *path)
* request for the root inode.
*/
SETUP_SEARCH(&desc, path, false);
inode_semtake();
if (path == NULL || *path == '\0' || strcmp(path, "/") == 0)
{
@ -253,9 +255,6 @@ FAR DIR *opendir(FAR const char *path)
/* Find the node matching the path. */
RESET_SEARCH(&desc);
desc.path = path;
ret = inode_search(&desc);
if (ret >= 0)
{
@ -357,6 +356,7 @@ FAR DIR *opendir(FAR const char *path)
}
}
RELEASE_SEARCH(&desc);
inode_semgive();
return ((FAR DIR *)dir);
@ -366,6 +366,7 @@ errout_with_direntry:
kumm_free(dir);
errout_with_semaphore:
RELEASE_SEARCH(&desc);
inode_semgive();
set_errno(ret);
return NULL;

View File

@ -89,22 +89,20 @@ int find_blockdriver(FAR const char *pathname, int mountflags, FAR struct inode
#ifdef CONFIG_DEBUG_FEATURES
if (!pathname || !ppinode)
{
ret = -EINVAL;
goto errout;
return -EINVAL;
}
#endif
/* Find the inode registered with this pathname */
RESET_SEARCH(&desc);
desc.path = pathname;
SETUP_SEARCH(&desc, pathname, false);
ret = inode_find(&desc);
if (ret < 0)
{
ferr("ERROR: Failed to find %s\n", pathname);
ret = -ENOENT;
goto errout;
goto errout_with_search;
}
/* Get the search results */
@ -132,10 +130,12 @@ int find_blockdriver(FAR const char *pathname, int mountflags, FAR struct inode
}
*ppinode = inode;
RELEASE_SEARCH(&desc);
return OK;
errout_with_inode:
inode_release(inode);
errout:
errout_with_search:
RELEASE_SEARCH(&desc);
return ret;
}

View File

@ -61,25 +61,25 @@ static int fat_attrib(const char *path, fat_attrib_t *retattrib,
fat_attrib_t setbits, fat_attrib_t clearbits)
{
struct fat_mountpt_s *fs;
struct fat_dirinfo_s dirinfo;
struct fat_dirinfo_s dirinfo;
struct inode_search_s desc;
FAR struct inode *inode;
uint8_t *direntry;
uint8_t oldattributes;
uint8_t newattributes;
int ret;
FAR struct inode *inode;
uint8_t *direntry;
uint8_t oldattributes;
uint8_t newattributes;
int status;
int ret;
/* Find the inode for this file */
RESET_SEARCH(&desc);
desc.path = path;
SETUP_SEARCH(&desc, path, false);
ret = inode_find(&desc);
if (ret < 0)
status = inode_find(&desc);
if (status < 0)
{
/* There is no mountpoint that includes in this path */
ret = ENOENT;
ret = -status;
goto errout;
}
@ -165,14 +165,18 @@ static int fat_attrib(const char *path, fat_attrib_t *retattrib,
fat_semgive(fs);
inode_release(inode);
RELEASE_SEARCH(&desc);
return OK;
errout_with_semaphore:
fat_semgive(fs);
errout_with_inode:
inode_release(inode);
errout:
*get_errno_ptr() = ret;
RELEASE_SEARCH(&desc);
set_errno(ret);
return ERROR;
}

View File

@ -83,11 +83,7 @@ FAR struct inode *inode_unlink(FAR const char *path)
/* Find the node to unlink */
RESET_SEARCH(&desc);
desc.path = path;
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
desc.nofollow = true;
#endif
SETUP_SEARCH(&desc, path, true);
ret = inode_search(&desc);
if (ret >= 0)
@ -123,6 +119,7 @@ FAR struct inode *inode_unlink(FAR const char *path)
node->i_peer = NULL;
}
RELEASE_SEARCH(&desc);
return node;
}

View File

@ -183,8 +183,7 @@ int inode_reserve(FAR const char *path, FAR struct inode **inode)
/* Find the location to insert the new subtree */
RESET_SEARCH(&desc);
desc.path = path;
SETUP_SEARCH(&desc, path, false);
ret = inode_search(&desc);
if (ret >= 0)
@ -193,7 +192,8 @@ int inode_reserve(FAR const char *path, FAR struct inode **inode)
* lies within a mountpoint, we don't distinguish here).
*/
return -EEXIST;
ret = -EEXIST;
goto errout_with_search;
}
/* Now we now where to insert the subtree */
@ -236,12 +236,18 @@ int inode_reserve(FAR const char *path, FAR struct inode **inode)
{
inode_insert(node, left, parent);
*inode = node;
return OK;
ret = OK;
break;
}
}
/* We get here on failures to allocate node memory */
return -ENOMEM;
ret = -ENOMEM;
break;
}
errout_with_search:
RELEASE_SEARCH(&desc);
return ret;
}

View File

@ -180,9 +180,8 @@ static int _inode_linktarget(FAR struct inode *node,
{
/* Reset and reinitialize the search descriptor. */
RESET_SEARCH(desc);
desc->path = (FAR const char *)node->u.i_link;
desc->nofollow = true;
RELEASE_SEARCH(desc);
SETUP_SEARCH(desc, (FAR const char *)node->u.i_link, true);
/* Look up inode associated with the target of the symbolic link */
@ -516,6 +515,8 @@ int inode_search(FAR struct inode_search_s *desc)
if (desc->linktgt != NULL && INODE_IS_MOUNTPT(node))
{
FAR char *buffer;
/* There would be no problem in this case if the link was to
* either to the root directory of the MOUNTPOINT or to a
* regular file within the the mounted volume. However,
@ -531,20 +532,28 @@ int inode_search(FAR struct inode_search_s *desc)
if (desc->relpath != NULL && *desc->relpath != '\0')
{
snprintf(desc->fullpath, PATH_MAX, "%s/%s",
desc->linktgt, desc->relpath);
(void)asprintf(&buffer, "%s/%s",
desc->linktgt, desc->relpath);
}
else
{
strncpy(desc->fullpath, desc->linktgt, PATH_MAX);
buffer = strdup(desc->linktgt);
}
/* Reset the search description and perform the search again. */
if (buffer == NULL)
{
ret = -ENOMEM;
}
else
{
/* Reset the search description and perform the search again. */
RESET_SEARCH(desc);
desc->path = desc->fullpath;
RELEASE_SEARCH(desc);
SETUP_SEARCH(desc, buffer, false);
desc->buffer = buffer;
ret = _inode_search(desc);
ret = _inode_search(desc);
}
}
}
#endif

View File

@ -48,6 +48,7 @@
#include <stdbool.h>
#include <dirent.h>
#include <nuttx/kmalloc.h>
#include <nuttx/fs/fs.h>
/****************************************************************************
@ -55,29 +56,43 @@
****************************************************************************/
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
# define RESET_SEARCH(d) \
# define SETUP_SEARCH(d,p,n) \
do \
{ \
(d)->path = NULL; \
(d)->path = (p); \
(d)->node = NULL; \
(d)->peer = NULL; \
(d)->parent = NULL; \
(d)->relpath = NULL; \
(d)->linktgt = NULL; \
(d)->nofollow = false; \
(d)->buffer = NULL; \
(d)->nofollow = (n); \
} \
while (0)
# define RELEASE_SEARCH(d) \
if ((d)->buffer != NULL) \
{ \
kmm_free((d)->buffer); \
(d)->buffer = NULL; \
}
#else
# define RESET_SEARCH(d) \
# define SETUP_SEARCH(d,p,n) \
do \
{ \
(d)->path = NULL; \
(d)->path = (p); \
(d)->node = NULL; \
(d)->peer = NULL; \
(d)->parent = NULL; \
(d)->relpath = NULL; \
} \
while (0)
# define RELEASE_SEARCH(d)
#endif
/****************************************************************************
@ -107,9 +122,10 @@
* terminal is a soft link, then return the inode of
* the link target.
* - OUTPUT: (not used)
* fullpath - INPUT: Not used
* - OUTPUT: May hold an intermediate path which is probably of
* no interest to the caller.
* buffer - INPUT: Not used
* - OUTPUT: May hold an allocated intermediate path which is
* probably of no interest to the caller unless it holds
* the relpath.
*/
struct inode_search_s
@ -121,8 +137,8 @@ struct inode_search_s
FAR const char *relpath; /* Relative path into the mountpoint */
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
FAR const char *linktgt; /* Target of symbolic link if linked to a directory */
FAR char *buffer; /* Path expansion buffer */
bool nofollow; /* true: Don't follow terminal soft link */
char fullpath[PATH_MAX]; /* Path expansion buffer */
#endif
};

View File

@ -137,8 +137,7 @@ static int automount_findinode(FAR const char *path)
/* Find the inode */
RESET_SEARCH(&desc);
desc.path = path;
SETUP_SEARCH(&desc, path, false);
ret = inode_search(&desc);
@ -169,6 +168,7 @@ static int automount_findinode(FAR const char *path)
/* Relinquish our exclusive access to the inode try and return the result */
inode_semgive();
RELEASE_SEARCH(&desc);
return ret;
}

View File

@ -284,8 +284,7 @@ int mount(FAR const char *source, FAR const char *target,
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
/* Check if the inode already exists */
RESET_SEARCH(&desc);
desc.path = target;
SETUP_SEARCH(&desc, target, false);
ret = inode_find(&desc);
if (ret >= 0)
@ -414,6 +413,9 @@ int mount(FAR const char *source, FAR const char *target,
}
#endif
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
RELEASE_SEARCH(&desc);
#endif
return OK;
/* A lot of goto's! But they make the error handling much simpler */
@ -432,10 +434,14 @@ errout_with_mountpt:
#endif
inode_release(mountpt_inode);
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
RELEASE_SEARCH(&desc);
#endif
goto errout;
errout_with_semaphore:
inode_semgive();
#ifdef BDFS_SUPPORT
#ifdef NONBDFS_SUPPORT
if (blkdrvr_inode)
@ -445,6 +451,10 @@ errout_with_semaphore:
}
#endif
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
RELEASE_SEARCH(&desc);
#endif
errout:
set_errno(errcode);
return ERROR;

View File

@ -88,14 +88,13 @@ int umount2(FAR const char *target, unsigned int flags)
/* Find the mountpt */
RESET_SEARCH(&desc);
desc.path = target;
SETUP_SEARCH(&desc, target, false);
ret = inode_find(&desc);
if (ret < 0)
{
errcode = ENOENT;
goto errout;
goto errout_with_search;
}
/* Get the search results */
@ -199,18 +198,24 @@ int umount2(FAR const char *target, unsigned int flags)
inode_release(blkdrvr_inode);
}
RELEASE_SEARCH(&desc);
return OK;
/* A lot of goto's! But they make the error handling much simpler */
errout_with_semaphore:
inode_semgive();
errout_with_mountpt:
inode_release(mountpt_inode);
if (blkdrvr_inode)
{
inode_release(blkdrvr_inode);
}
errout_with_search:
RELEASE_SEARCH(&desc);
errout:
set_errno(errcode);
return ERROR;

View File

@ -133,8 +133,7 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...)
* have incremented the reference count on the inode.
*/
RESET_SEARCH(&desc);
desc.path = fullpath;
SETUP_SEARCH(&desc, fullpath, false);
ret = inode_find(&desc);
if (ret >= 0)
@ -236,16 +235,21 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...)
inode->i_crefs = 1;
}
RELEASE_SEARCH(&desc);
sched_unlock();
return mqdes;
errout_with_msgq:
mq_msgqfree(msgq);
inode->u.i_mqueue = NULL;
errout_with_inode:
inode_release(inode);
errout_with_lock:
RELEASE_SEARCH(&desc);
sched_unlock();
errout:
set_errno(errcode);
return (mqd_t)ERROR;

View File

@ -87,8 +87,7 @@ int mq_unlink(FAR const char *mq_name)
/* Get the inode for this message queue. */
RESET_SEARCH(&desc);
desc.path = fullpath;
SETUP_SEARCH(&desc, fullpath, false);
sched_lock();
ret = inode_find(&desc);
@ -97,7 +96,7 @@ int mq_unlink(FAR const char *mq_name)
/* There is no inode that includes in this path */
errcode = -ret;
goto errout;
goto errout_with_search;
}
/* Get the search results */
@ -149,14 +148,18 @@ int mq_unlink(FAR const char *mq_name)
inode_semgive();
mq_inode_release(inode);
RELEASE_SEARCH(&desc);
sched_unlock();
return OK;
errout_with_semaphore:
inode_semgive();
errout_with_inode:
inode_release(inode);
errout:
errout_with_search:
RELEASE_SEARCH(&desc);
set_errno(errcode);
sched_unlock();
return ERROR;

View File

@ -114,149 +114,148 @@ FAR sem_t *sem_open (FAR const char *name, int oflags, ...)
/* Make sure that a non-NULL name is supplied */
if (name)
DEBUGASSERT(name != NULL);
/* The POSIX specification requires that the "check for the existence
* of a semaphore and the creation of the semaphore if it does not
* exist shall be atomic with respect to other processes executing
* sem_open()..." A simple sched_lock() should be sufficient to meet
* this requirement.
*/
sched_lock();
/* Get the full path to the semaphore */
snprintf(fullpath, MAX_SEMPATH, CONFIG_FS_NAMED_SEMPATH "/%s", name);
/* Get the inode for this semaphore. This should succeed if the
* semaphore has already been created. In this case, inode_find()
* will have incremented the reference count on the inode.
*/
SETUP_SEARCH(&desc, fullpath, false);
ret = inode_find(&desc);
if (ret >= 0)
{
/* The POSIX specification requires that the "check for the existence
* of a semaphore and the creation of the semaphore if it does not
* exist shall be atomic with respect to other processes executing
* sem_open()..." A simple sched_lock() should be sufficient to meet
* this requirement.
*/
/* Something exists at this path. Get the search results */
sched_lock();
inode = desc.node;
relpath = desc.relpath;
DEBUGASSERT(inode != NULL);
/* Get the full path to the semaphore */
/* Verify that the inode is a semaphore */
snprintf(fullpath, MAX_SEMPATH, CONFIG_FS_NAMED_SEMPATH "/%s", name);
/* Get the inode for this semaphore. This should succeed if the
* semaphore has already been created. In this case, inode_find()
* will have incremented the reference count on the inode.
*/
RESET_SEARCH(&desc);
desc.path = fullpath;
ret = inode_find(&desc);
if (ret >= 0)
if (!INODE_IS_NAMEDSEM(inode))
{
/* Something exists at this path. Get the search results */
inode = desc.node;
relpath = desc.relpath;
DEBUGASSERT(inode != NULL);
/* Verify that the inode is a semaphore */
if (!INODE_IS_NAMEDSEM(inode))
{
errcode = ENXIO;
goto errout_with_inode;
}
/* It exists and is a semaphore. Check if the caller wanted to
* create a new semaphore with this name.
*/
if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
{
errcode = EEXIST;
goto errout_with_inode;
}
/* Return a reference to the semaphore, retaining the reference
* count on the inode.
*/
sem = &inode->u.i_nsem->ns_sem;
}
else
{
va_list ap;
/* The semaphore does not exists. Were we asked to create it? */
if ((oflags & O_CREAT) == 0)
{
/* The semaphore does not exist and O_CREAT is not set */
errcode = ENOENT;
goto errout_with_lock;
}
/* Create the semaphore. First we have to extract the additional
* parameters from the variable argument list.
* REVISIT: Mode parameter is not currently used.
*/
va_start(ap, oflags);
mode = va_arg(ap, mode_t);
value = va_arg(ap, unsigned);
va_end(ap);
UNUSED(mode);
/* Check the semaphore value */
if (value > SEM_VALUE_MAX)
{
errcode = EINVAL;
goto errout_with_lock;
}
/* Create an inode in the pseudo-filesystem at this path. The new
* inode will be created with a reference count of zero.
*/
inode_semtake();
ret = inode_reserve(fullpath, &inode);
inode_semgive();
if (ret < 0)
{
errcode = -ret;
goto errout_with_lock;
}
/* Allocate the semaphore structure (using the appropriate allocator
* for the group)
*/
nsem = group_malloc(NULL, sizeof(struct nsem_inode_s));
if (!nsem)
{
errcode = ENOMEM;
goto errout_with_inode;
}
/* Link to the inode */
inode->u.i_nsem = nsem;
nsem->ns_inode = inode;
/* Initialize the inode */
INODE_SET_NAMEDSEM(inode);
inode->i_crefs = 1;
/* Initialize the semaphore */
sem_init(&nsem->ns_sem, 0, value);
/* Return a reference to the semaphore */
sem = &nsem->ns_sem;
errcode = ENXIO;
goto errout_with_inode;
}
sched_unlock();
/* It exists and is a semaphore. Check if the caller wanted to
* create a new semaphore with this name.
*/
if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
{
errcode = EEXIST;
goto errout_with_inode;
}
/* Return a reference to the semaphore, retaining the reference
* count on the inode.
*/
sem = &inode->u.i_nsem->ns_sem;
}
else
{
va_list ap;
/* The semaphore does not exists. Were we asked to create it? */
if ((oflags & O_CREAT) == 0)
{
/* The semaphore does not exist and O_CREAT is not set */
errcode = ENOENT;
goto errout_with_lock;
}
/* Create the semaphore. First we have to extract the additional
* parameters from the variable argument list.
* REVISIT: Mode parameter is not currently used.
*/
va_start(ap, oflags);
mode = va_arg(ap, mode_t);
value = va_arg(ap, unsigned);
va_end(ap);
UNUSED(mode);
/* Check the semaphore value */
if (value > SEM_VALUE_MAX)
{
errcode = EINVAL;
goto errout_with_lock;
}
/* Create an inode in the pseudo-filesystem at this path. The new
* inode will be created with a reference count of zero.
*/
inode_semtake();
ret = inode_reserve(fullpath, &inode);
inode_semgive();
if (ret < 0)
{
errcode = -ret;
goto errout_with_lock;
}
/* Allocate the semaphore structure (using the appropriate allocator
* for the group)
*/
nsem = group_malloc(NULL, sizeof(struct nsem_inode_s));
if (!nsem)
{
errcode = ENOMEM;
goto errout_with_inode;
}
/* Link to the inode */
inode->u.i_nsem = nsem;
nsem->ns_inode = inode;
/* Initialize the inode */
INODE_SET_NAMEDSEM(inode);
inode->i_crefs = 1;
/* Initialize the semaphore */
sem_init(&nsem->ns_sem, 0, value);
/* Return a reference to the semaphore */
sem = &nsem->ns_sem;
}
RELEASE_SEARCH(&desc);
sched_unlock();
return sem;
errout_with_inode:
inode_release(inode);
errout_with_lock:
RELEASE_SEARCH(&desc);
set_errno(errcode);
sched_unlock();
return (FAR sem_t *)ERROR;

View File

@ -91,8 +91,7 @@ int sem_unlink(FAR const char *name)
/* Get the inode for this semaphore. */
RESET_SEARCH(&desc);
desc.path = fullpath;
SETUP_SEARCH(&desc, fullpath, false);
sched_lock();
ret = inode_find(&desc);
@ -101,7 +100,7 @@ int sem_unlink(FAR const char *name)
/* There is no inode that includes in this path */
errcode = -ret;
goto errout;
goto errout_with_search;
}
/* Get the search results */
@ -152,14 +151,18 @@ int sem_unlink(FAR const char *name)
inode_semgive();
ret = sem_close((FAR sem_t *)inode->u.i_nsem);
RELEASE_SEARCH(&desc);
sched_unlock();
return ret;
errout_with_semaphore:
inode_semgive();
errout_with_inode:
inode_release(inode);
errout:
errout_with_search:
RELEASE_SEARCH(&desc);
set_errno(errcode);
sched_unlock();
return ERROR;

View File

@ -2446,15 +2446,14 @@ static int unionfs_getmount(FAR const char *path, FAR struct inode **inode)
/* Find the mountpt */
RESET_SEARCH(&desc);
desc.path = path;
SETUP_SEARCH(&desc, path, false);
ret = inode_find(&desc);
if (ret < 0)
{
/* Mountpoint inode not found */
return ret;
goto errout_with_search;
}
/* Get the search results */
@ -2462,20 +2461,33 @@ static int unionfs_getmount(FAR const char *path, FAR struct inode **inode)
minode = desc.node;
DEBUGASSERT(minode != NULL);
/* Verify that the inode is a mountpoint */
/* Verify that the inode is a mountpoint.
*
* REVISIT: If desc.relpath points to a non-empty string, then the path
* does not really refer to a mountpoint but, rather, to a some entity
* within the mounted volume.
*/
if (!INODE_IS_MOUNTPT(minode))
{
/* Inode was found, but is it is a mounpoint */
/* Inode was found, but is it is not a mounpoint */
inode_release(minode);
return -EINVAL;
ret = -EINVAL;
goto errout_with_inode;
}
/* Success! */
*inode = minode;
RELEASE_SEARCH(&desc);
return OK;
errout_with_inode:
inode_release(minode);
errout_with_search:
RELEASE_SEARCH(&desc);
return ret;
}
/****************************************************************************

View File

@ -107,8 +107,7 @@ int link(FAR const char *path1, FAR const char *path2)
* does not lie on a mounted volume.
*/
RESET_SEARCH(&desc);
desc.path = path2;
SETUP_SEARCH(&desc, path2, false);
ret = inode_find(&desc);
if (ret >= 0)
@ -149,7 +148,7 @@ int link(FAR const char *path1, FAR const char *path2)
if (newpath2 == NULL)
{
errcode = ENOMEM;
goto errout;
goto errout_with_search;
}
/* Create an inode in the pseudo-filesystem at this path.
@ -165,7 +164,7 @@ int link(FAR const char *path1, FAR const char *path2)
{
kmm_free(newpath2);
errcode = -ret;
goto errout;
goto errout_with_search;
}
/* Initialize the inode */
@ -177,10 +176,15 @@ int link(FAR const char *path1, FAR const char *path2)
/* Symbolic link successfully created */
RELEASE_SEARCH(&desc);
return OK;
errout_with_inode:
inode_release(inode);
errout_with_search:
RELEASE_SEARCH(&desc);
errout:
set_errno(errcode);
return ERROR;

View File

@ -86,13 +86,12 @@ int mkdir(const char *pathname, mode_t mode)
{
struct inode_search_s desc;
FAR struct inode *inode;
int errcode;
int ret;
int errcode;
int ret;
/* Find the inode that includes this path */
RESET_SEARCH(&desc);
desc.path = pathname;
SETUP_SEARCH(&desc, pathname, false);
ret = inode_find(&desc);
if (ret >= 0)
@ -164,24 +163,27 @@ int mkdir(const char *pathname, mode_t mode)
if (ret < 0)
{
errcode = -ret;
goto errout;
goto errout_with_search;
}
}
#else
else
{
errcode = ENXIO;
goto errout;
goto errout_with_search;
}
#endif
/* Directory successfully created */
RELEASE_SEARCH(&desc);
return OK;
errout_with_inode:
inode_release(inode);
errout:
errout_with_search:
RELEASE_SEARCH(&desc);
set_errno(errcode);
return ERROR;
}

View File

@ -121,8 +121,7 @@ int open(const char *path, int oflags, ...)
/* Get an inode for this file */
RESET_SEARCH(&desc);
desc.path = path;
SETUP_SEARCH(&desc, path, false);
ret = inode_find(&desc);
if (ret < 0)
@ -133,7 +132,7 @@ int open(const char *path, int oflags, ...)
*/
ret = -ret;
goto errout;
goto errout_with_search;
}
/* Get the search results */
@ -164,11 +163,12 @@ int open(const char *path, int oflags, ...)
if (fd < 0)
{
ret = fd;
goto errout;
goto errout_with_search;
}
/* Return the file descriptor */
RELEASE_SEARCH(&desc);
leave_cancellation_point();
return fd;
}
@ -215,8 +215,7 @@ int open(const char *path, int oflags, ...)
{
/* The errno value has already been set */
leave_cancellation_point();
return ERROR;
goto errout;
}
/* Perform the driver open operation. NOTE that the open method may be
@ -276,15 +275,21 @@ int open(const char *path, int oflags, ...)
}
#endif
RELEASE_SEARCH(&desc);
leave_cancellation_point();
return fd;
errout_with_fd:
files_release(fd);
errout_with_inode:
inode_release(inode);
errout:
errout_with_search:
RELEASE_SEARCH(&desc);
set_errno(ret);
errout:
leave_cancellation_point();
return ERROR;
}

View File

@ -93,17 +93,13 @@ ssize_t readlink(FAR const char *path, FAR char *buf, size_t bufsize)
* symbolic link node.
*/
RESET_SEARCH(&desc);
desc.path = path;
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
desc.nofollow = true;
#endif
SETUP_SEARCH(&desc, path, true);
ret = inode_find(&desc);
if (ret < 0)
{
errcode = -ret;
goto errout;
goto errout_with_search;
}
/* Get the search results */
@ -131,11 +127,14 @@ ssize_t readlink(FAR const char *path, FAR char *buf, size_t bufsize)
/* Release our reference on the inode and return the length */
inode_release(node);
RELEASE_SEARCH(&desc);
return strlen(buf);
errout_with_inode:
inode_release(node);
errout:
errout_with_search:
RELEASE_SEARCH(&desc);
set_errno(errcode);
return ERROR;
}

View File

@ -83,7 +83,9 @@
int rename(FAR const char *oldpath, FAR const char *newpath)
{
struct inode_search_s olddesc;
#ifndef CONFIG_DISABLE_MOUNTPOINT
struct inode_search_s newdesc;
#endif
FAR struct inode *oldinode;
FAR struct inode *newinode;
int errcode;
@ -101,11 +103,7 @@ int rename(FAR const char *oldpath, FAR const char *newpath)
/* Get an inode that includes the oldpath */
RESET_SEARCH(&olddesc);
olddesc.path = oldpath;
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
olddesc.nofollow = true;
#endif
SETUP_SEARCH(&olddesc, oldpath, true);
ret = inode_find(&olddesc);
if (ret < 0)
@ -113,7 +111,7 @@ int rename(FAR const char *oldpath, FAR const char *newpath)
/* There is no inode that includes in this path */
errcode = -ret;
goto errout;
goto errout_with_oldsearch;
}
/* Get the search results */
@ -130,11 +128,7 @@ int rename(FAR const char *oldpath, FAR const char *newpath)
* mountpoint
*/
RESET_SEARCH(&newdesc);
newdesc.path = newpath;
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
newdesc.nofollow = true;
#endif
SETUP_SEARCH(&newdesc, newpath, true);
ret = inode_find(&newdesc);
if (ret < 0)
@ -142,7 +136,7 @@ int rename(FAR const char *oldpath, FAR const char *newpath)
/* There is no mountpoint that includes in this path */
errcode = -ret;
goto errout_with_oldinode;
goto errout_with_newsearch;
}
/* Get the search results */
@ -181,9 +175,10 @@ int rename(FAR const char *oldpath, FAR const char *newpath)
/* Successfully renamed */
inode_release(newinode);
RELEASE_SEARCH(&newdesc);
}
else
#endif
#endif /* CONFIG_DISABLE_MOUNTPOINT */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
{
/* Create a new, empty inode at the destination location.
@ -246,22 +241,29 @@ int rename(FAR const char *oldpath, FAR const char *newpath)
#else
{
errcode = ENXIO;
goto errout;
goto errout_with_oldsearch;
}
#endif
/* Successfully renamed */
inode_release(oldinode);
RELEASE_SEARCH(&olddesc);
return OK;
#ifndef CONFIG_DISABLE_MOUNTPOINT
errout_with_newinode:
inode_release(newinode);
errout_with_newsearch:
RELEASE_SEARCH(&newdesc);
#endif
errout_with_oldinode:
inode_release(oldinode);
errout:
errout_with_oldsearch:
RELEASE_SEARCH(&olddesc);
set_errno(errcode);
return ERROR;
}

View File

@ -93,11 +93,7 @@ int rmdir(FAR const char *pathname)
* on the inode if one is found.
*/
RESET_SEARCH(&desc);
desc.path = pathname;
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
desc.nofollow = true;
#endif
SETUP_SEARCH(&desc, pathname, true);
ret = inode_find(&desc);
if (ret < 0)
@ -105,7 +101,7 @@ int rmdir(FAR const char *pathname)
/* There is no inode that includes in this path */
errcode = -ret;
goto errout;
goto errout_with_search;
}
/* Get the search results */
@ -188,11 +184,13 @@ int rmdir(FAR const char *pathname)
/* Successfully removed the directory */
inode_release(inode);
RELEASE_SEARCH(&desc);
return OK;
errout_with_inode:
inode_release(inode);
errout:
errout_with_search:
RELEASE_SEARCH(&desc);
set_errno(errcode);
return ERROR;
}

View File

@ -234,11 +234,7 @@ int stat(FAR const char *path, FAR struct stat *buf)
/* Get an inode for this file */
RESET_SEARCH(&desc);
desc.path = path;
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
desc.nofollow = true;
#endif
SETUP_SEARCH(&desc, path, true);
ret = inode_find(&desc);
if (ret < 0)
@ -248,7 +244,7 @@ int stat(FAR const char *path, FAR struct stat *buf)
*/
ret = -ret;
goto errout;
goto errout_with_search;
}
/* Get the search results */
@ -293,12 +289,17 @@ int stat(FAR const char *path, FAR struct stat *buf)
/* Successfully stat'ed the file */
inode_release(inode);
RELEASE_SEARCH(&desc);
return OK;
/* Failure conditions always set the errno appropriately */
errout_with_inode:
inode_release(inode);
errout_with_search:
RELEASE_SEARCH(&desc);
errout:
set_errno(ret);
return ERROR;

View File

@ -105,8 +105,7 @@ int statfs(FAR const char *path, FAR struct statfs *buf)
/* Get an inode for this file */
RESET_SEARCH(&desc);
desc.path = path;
SETUP_SEARCH(&desc, path, false);
ret = inode_find(&desc);
if (ret < 0)
@ -116,7 +115,7 @@ int statfs(FAR const char *path, FAR struct statfs *buf)
*/
ret = -ret;
goto errout;
goto errout_with_search;
}
/* Get the search results */
@ -161,12 +160,17 @@ int statfs(FAR const char *path, FAR struct statfs *buf)
/* Successfully statfs'ed the file */
inode_release(inode);
RELEASE_SEARCH(&desc);
return OK;
/* Failure conditions always set the errno appropriately */
errout_with_inode:
inode_release(inode);
errout_with_search:
RELEASE_SEARCH(&desc);
errout:
set_errno(ret);
return ERROR;

View File

@ -92,11 +92,7 @@ int unlink(FAR const char *pathname)
* which may be a symbolic link)
*/
RESET_SEARCH(&desc);
desc.path = pathname;
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
desc.nofollow = true;
#endif
SETUP_SEARCH(&desc, pathname, true);
ret = inode_find(&desc);
if (ret < 0)
@ -104,7 +100,7 @@ int unlink(FAR const char *pathname)
/* There is no inode that includes in this path */
errcode = -ret;
goto errout;
goto errout_with_search;
}
/* Get the search results */
@ -233,11 +229,14 @@ int unlink(FAR const char *pathname)
/* Successfully unlinked */
inode_release(inode);
RELEASE_SEARCH(&desc);
return OK;
errout_with_inode:
inode_release(inode);
errout:
errout_with_search:
RELEASE_SEARCH(&desc);
set_errno(errcode);
return ERROR;
}