Merge branch 'softlink'

This commit is contained in:
Gregory Nutt
2017-02-05 14:57:55 -06:00
26 changed files with 399 additions and 275 deletions
+49 -8
View File
@@ -479,14 +479,14 @@ int task_delete(pid_t pid);
<p> <p>
<b>Description:</b> <b>Description:</b>
This function causes a specified task to cease to exist. 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 function is the companion to <code>task_create()</code>.
This is the version of the function exposed to the user; This is the version of the function exposed to the user;
it is simply a wrapper around the internal, <code>task_terminate()</code> function. it is simply a wrapper around the internal, <code>task_terminate()</code> function.
</p> </p>
<p> <p>
The logic in this function only deletes non-running tasks. 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. This can only happen if a task calls <code>task_delete()</code> in order to delete itself.
</p> </p>
<p> <p>
@@ -6223,7 +6223,7 @@ interface of the same name.
<b>Description:</b> <b>Description:</b>
<p>The <code>pthread_cancel()</code> function will request that thread be canceled. <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> 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: <p>The target thread's cancelability state determines how the cancellation is acted on:
@@ -6592,16 +6592,16 @@ interface of the same name.
</p> </p>
<ul> <ul>
<li><code>sched_ss_low_priority</code> <li><code>sched_ss_low_priority</code>
Low scheduling priority for sporadic server. Low scheduling priority for sporadic server.
</li> </li>
<li><code>sched_ss_repl_period</code> <li><code>sched_ss_repl_period</code>
Replenishment period for sporadic server. Replenishment period for sporadic server.
</li> </li>
<li><code>sched_ss_init_budget</code> <li><code>sched_ss_init_budget</code>
Initial budget for sporadic server. Initial budget for sporadic server.
</li> </li>
<li><code>sched_ss_max_repl</code> <li><code>sched_ss_max_repl</code>
Maximum pending replenishments for sporadic server. Maximum pending replenishments for sporadic server.
</li> </li>
</ul> </ul>
<p> <p>
@@ -8584,6 +8584,8 @@ int telldir(FAR DIR *dirp);
<ul><pre> <ul><pre>
#include &lt;unistd.h&gt; #include &lt;unistd.h&gt;
/* Task Control Interfaces */
pid_t vfork(void); pid_t vfork(void);
pid_t getpid(void); pid_t getpid(void);
void _exit(int status) noreturn_function; void _exit(int status) noreturn_function;
@@ -8591,6 +8593,8 @@ unsigned int sleep(unsigned int seconds);
void usleep(unsigned long usec); void usleep(unsigned long usec);
int pause(void); int pause(void);
/* File descriptor operations */
int close(int fd); int close(int fd);
int dup(int fd); int dup(int fd);
int dup2(int fd1, int fd2); int dup2(int fd1, int fd2);
@@ -8598,21 +8602,58 @@ int fsync(int fd);
off_t lseek(int fd, off_t offset, int whence); off_t lseek(int fd, off_t offset, int whence);
ssize_t read(int fd, FAR void *buf, size_t nbytes); 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 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]); int pipe(int fd[2]);
/* Working directory operations */
int chdir(FAR const char *path); int chdir(FAR const char *path);
FAR char *getcwd(FAR char *buf, size_t size); 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 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 #ifdef CONFIG_LIBC_EXECFUNCS
int execl(FAR const char *path, ...); int execl(FAR const char *path, ...);
int execv(FAR const char *path, FAR char *const argv[]); int execv(FAR const char *path, FAR char *const argv[]);
#endif #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); int getopt(int argc, FAR char *const argv[], FAR const char *optstring);
</pre></ul> </pre></ul>
</a> </a>
+1 -1
View File
@@ -43,7 +43,7 @@ config DISABLE_PSEUDOFS_OPERATIONS
config PSEUDOFS_SOFTLINKS config PSEUDOFS_SOFTLINKS
bool "Pseudo-filesystem soft links" bool "Pseudo-filesystem soft links"
default n default n
depends on !DISABLE_PSEUDOFS_OPERATIONSi && EXPERIMENTAL depends on !DISABLE_PSEUDOFS_OPERATIONS
---help--- ---help---
Enable support for soft links in the pseudeo file system. Soft Enable support for soft links in the pseudeo file system. Soft
links are not supported within mounted volumes by any NuttX file links are not supported within mounted volumes by any NuttX file
+4 -3
View File
@@ -235,6 +235,8 @@ FAR DIR *opendir(FAR const char *path)
* request for the root inode. * request for the root inode.
*/ */
SETUP_SEARCH(&desc, path, false);
inode_semtake(); inode_semtake();
if (path == NULL || *path == '\0' || strcmp(path, "/") == 0) 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. */ /* Find the node matching the path. */
RESET_SEARCH(&desc);
desc.path = path;
ret = inode_search(&desc); ret = inode_search(&desc);
if (ret >= 0) if (ret >= 0)
{ {
@@ -357,6 +356,7 @@ FAR DIR *opendir(FAR const char *path)
} }
} }
RELEASE_SEARCH(&desc);
inode_semgive(); inode_semgive();
return ((FAR DIR *)dir); return ((FAR DIR *)dir);
@@ -366,6 +366,7 @@ errout_with_direntry:
kumm_free(dir); kumm_free(dir);
errout_with_semaphore: errout_with_semaphore:
RELEASE_SEARCH(&desc);
inode_semgive(); inode_semgive();
set_errno(ret); set_errno(ret);
return NULL; return NULL;
+6 -6
View File
@@ -89,22 +89,20 @@ int find_blockdriver(FAR const char *pathname, int mountflags, FAR struct inode
#ifdef CONFIG_DEBUG_FEATURES #ifdef CONFIG_DEBUG_FEATURES
if (!pathname || !ppinode) if (!pathname || !ppinode)
{ {
ret = -EINVAL; return -EINVAL;
goto errout;
} }
#endif #endif
/* Find the inode registered with this pathname */ /* Find the inode registered with this pathname */
RESET_SEARCH(&desc); SETUP_SEARCH(&desc, pathname, false);
desc.path = pathname;
ret = inode_find(&desc); ret = inode_find(&desc);
if (ret < 0) if (ret < 0)
{ {
ferr("ERROR: Failed to find %s\n", pathname); ferr("ERROR: Failed to find %s\n", pathname);
ret = -ENOENT; ret = -ENOENT;
goto errout; goto errout_with_search;
} }
/* Get the search results */ /* Get the search results */
@@ -132,10 +130,12 @@ int find_blockdriver(FAR const char *pathname, int mountflags, FAR struct inode
} }
*ppinode = inode; *ppinode = inode;
RELEASE_SEARCH(&desc);
return OK; return OK;
errout_with_inode: errout_with_inode:
inode_release(inode); inode_release(inode);
errout: errout_with_search:
RELEASE_SEARCH(&desc);
return ret; return ret;
} }
+16 -12
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) fat_attrib_t setbits, fat_attrib_t clearbits)
{ {
struct fat_mountpt_s *fs; struct fat_mountpt_s *fs;
struct fat_dirinfo_s dirinfo; struct fat_dirinfo_s dirinfo;
struct inode_search_s desc; struct inode_search_s desc;
FAR struct inode *inode; FAR struct inode *inode;
uint8_t *direntry; uint8_t *direntry;
uint8_t oldattributes; uint8_t oldattributes;
uint8_t newattributes; uint8_t newattributes;
int ret; int status;
int ret;
/* Find the inode for this file */ /* Find the inode for this file */
RESET_SEARCH(&desc); SETUP_SEARCH(&desc, path, false);
desc.path = path;
ret = inode_find(&desc); status = inode_find(&desc);
if (ret < 0) if (status < 0)
{ {
/* There is no mountpoint that includes in this path */ /* There is no mountpoint that includes in this path */
ret = ENOENT; ret = -status;
goto errout; goto errout;
} }
@@ -165,14 +165,18 @@ static int fat_attrib(const char *path, fat_attrib_t *retattrib,
fat_semgive(fs); fat_semgive(fs);
inode_release(inode); inode_release(inode);
RELEASE_SEARCH(&desc);
return OK; return OK;
errout_with_semaphore: errout_with_semaphore:
fat_semgive(fs); fat_semgive(fs);
errout_with_inode: errout_with_inode:
inode_release(inode); inode_release(inode);
errout: errout:
*get_errno_ptr() = ret; RELEASE_SEARCH(&desc);
set_errno(ret);
return ERROR; return ERROR;
} }
+2 -5
View File
@@ -83,11 +83,7 @@ FAR struct inode *inode_unlink(FAR const char *path)
/* Find the node to unlink */ /* Find the node to unlink */
RESET_SEARCH(&desc); SETUP_SEARCH(&desc, path, true);
desc.path = path;
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
desc.nofollow = true;
#endif
ret = inode_search(&desc); ret = inode_search(&desc);
if (ret >= 0) if (ret >= 0)
@@ -123,6 +119,7 @@ FAR struct inode *inode_unlink(FAR const char *path)
node->i_peer = NULL; node->i_peer = NULL;
} }
RELEASE_SEARCH(&desc);
return node; return node;
} }
+11 -5
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 */ /* Find the location to insert the new subtree */
RESET_SEARCH(&desc); SETUP_SEARCH(&desc, path, false);
desc.path = path;
ret = inode_search(&desc); ret = inode_search(&desc);
if (ret >= 0) 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). * 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 */ /* 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_insert(node, left, parent);
*inode = node; *inode = node;
return OK; ret = OK;
break;
} }
} }
/* We get here on failures to allocate node memory */ /* We get here on failures to allocate node memory */
return -ENOMEM; ret = -ENOMEM;
break;
} }
errout_with_search:
RELEASE_SEARCH(&desc);
return ret;
} }
+19 -10
View File
@@ -180,9 +180,8 @@ static int _inode_linktarget(FAR struct inode *node,
{ {
/* Reset and reinitialize the search descriptor. */ /* Reset and reinitialize the search descriptor. */
RESET_SEARCH(desc); RELEASE_SEARCH(desc);
desc->path = (FAR const char *)node->u.i_link; SETUP_SEARCH(desc, (FAR const char *)node->u.i_link, true);
desc->nofollow = true;
/* Look up inode associated with the target of the symbolic link */ /* 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)) if (desc->linktgt != NULL && INODE_IS_MOUNTPT(node))
{ {
FAR char *buffer;
/* There would be no problem in this case if the link was to /* There would be no problem in this case if the link was to
* either to the root directory of the MOUNTPOINT or to a * either to the root directory of the MOUNTPOINT or to a
* regular file within the the mounted volume. However, * 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') if (desc->relpath != NULL && *desc->relpath != '\0')
{ {
snprintf(desc->fullpath, PATH_MAX, "%s/%s", (void)asprintf(&buffer, "%s/%s",
desc->linktgt, desc->relpath); desc->linktgt, desc->relpath);
} }
else 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); RELEASE_SEARCH(desc);
desc->path = desc->fullpath; SETUP_SEARCH(desc, buffer, false);
desc->buffer = buffer;
ret = _inode_search(desc); ret = _inode_search(desc);
}
} }
} }
#endif #endif
+25 -9
View File
@@ -48,6 +48,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <dirent.h> #include <dirent.h>
#include <nuttx/kmalloc.h>
#include <nuttx/fs/fs.h> #include <nuttx/fs/fs.h>
/**************************************************************************** /****************************************************************************
@@ -55,29 +56,43 @@
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_PSEUDOFS_SOFTLINKS #ifdef CONFIG_PSEUDOFS_SOFTLINKS
# define RESET_SEARCH(d) \
# define SETUP_SEARCH(d,p,n) \
do \ do \
{ \ { \
(d)->path = NULL; \ (d)->path = (p); \
(d)->node = NULL; \ (d)->node = NULL; \
(d)->peer = NULL; \ (d)->peer = NULL; \
(d)->parent = NULL; \ (d)->parent = NULL; \
(d)->relpath = NULL; \ (d)->relpath = NULL; \
(d)->linktgt = NULL; \ (d)->linktgt = NULL; \
(d)->nofollow = false; \ (d)->buffer = NULL; \
(d)->nofollow = (n); \
} \ } \
while (0) while (0)
# define RELEASE_SEARCH(d) \
if ((d)->buffer != NULL) \
{ \
kmm_free((d)->buffer); \
(d)->buffer = NULL; \
}
#else #else
# define RESET_SEARCH(d) \
# define SETUP_SEARCH(d,p,n) \
do \ do \
{ \ { \
(d)->path = NULL; \ (d)->path = (p); \
(d)->node = NULL; \ (d)->node = NULL; \
(d)->peer = NULL; \ (d)->peer = NULL; \
(d)->parent = NULL; \ (d)->parent = NULL; \
(d)->relpath = NULL; \ (d)->relpath = NULL; \
} \ } \
while (0) while (0)
# define RELEASE_SEARCH(d)
#endif #endif
/**************************************************************************** /****************************************************************************
@@ -107,9 +122,10 @@
* terminal is a soft link, then return the inode of * terminal is a soft link, then return the inode of
* the link target. * the link target.
* - OUTPUT: (not used) * - OUTPUT: (not used)
* fullpath - INPUT: Not used * buffer - INPUT: Not used
* - OUTPUT: May hold an intermediate path which is probably of * - OUTPUT: May hold an allocated intermediate path which is
* no interest to the caller. * probably of no interest to the caller unless it holds
* the relpath.
*/ */
struct inode_search_s struct inode_search_s
@@ -121,8 +137,8 @@ struct inode_search_s
FAR const char *relpath; /* Relative path into the mountpoint */ FAR const char *relpath; /* Relative path into the mountpoint */
#ifdef CONFIG_PSEUDOFS_SOFTLINKS #ifdef CONFIG_PSEUDOFS_SOFTLINKS
FAR const char *linktgt; /* Target of symbolic link if linked to a directory */ 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 */ bool nofollow; /* true: Don't follow terminal soft link */
char fullpath[PATH_MAX]; /* Path expansion buffer */
#endif #endif
}; };
+2 -2
View File
@@ -137,8 +137,7 @@ static int automount_findinode(FAR const char *path)
/* Find the inode */ /* Find the inode */
RESET_SEARCH(&desc); SETUP_SEARCH(&desc, path, false);
desc.path = path;
ret = inode_search(&desc); 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 */ /* Relinquish our exclusive access to the inode try and return the result */
inode_semgive(); inode_semgive();
RELEASE_SEARCH(&desc);
return ret; return ret;
} }
+12 -2
View File
@@ -284,8 +284,7 @@ int mount(FAR const char *source, FAR const char *target,
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS #ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
/* Check if the inode already exists */ /* Check if the inode already exists */
RESET_SEARCH(&desc); SETUP_SEARCH(&desc, target, false);
desc.path = target;
ret = inode_find(&desc); ret = inode_find(&desc);
if (ret >= 0) if (ret >= 0)
@@ -414,6 +413,9 @@ int mount(FAR const char *source, FAR const char *target,
} }
#endif #endif
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
RELEASE_SEARCH(&desc);
#endif
return OK; return OK;
/* A lot of goto's! But they make the error handling much simpler */ /* A lot of goto's! But they make the error handling much simpler */
@@ -432,10 +434,14 @@ errout_with_mountpt:
#endif #endif
inode_release(mountpt_inode); inode_release(mountpt_inode);
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
RELEASE_SEARCH(&desc);
#endif
goto errout; goto errout;
errout_with_semaphore: errout_with_semaphore:
inode_semgive(); inode_semgive();
#ifdef BDFS_SUPPORT #ifdef BDFS_SUPPORT
#ifdef NONBDFS_SUPPORT #ifdef NONBDFS_SUPPORT
if (blkdrvr_inode) if (blkdrvr_inode)
@@ -445,6 +451,10 @@ errout_with_semaphore:
} }
#endif #endif
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
RELEASE_SEARCH(&desc);
#endif
errout: errout:
set_errno(errcode); set_errno(errcode);
return ERROR; return ERROR;
+8 -3
View File
@@ -88,14 +88,13 @@ int umount2(FAR const char *target, unsigned int flags)
/* Find the mountpt */ /* Find the mountpt */
RESET_SEARCH(&desc); SETUP_SEARCH(&desc, target, false);
desc.path = target;
ret = inode_find(&desc); ret = inode_find(&desc);
if (ret < 0) if (ret < 0)
{ {
errcode = ENOENT; errcode = ENOENT;
goto errout; goto errout_with_search;
} }
/* Get the search results */ /* Get the search results */
@@ -199,18 +198,24 @@ int umount2(FAR const char *target, unsigned int flags)
inode_release(blkdrvr_inode); inode_release(blkdrvr_inode);
} }
RELEASE_SEARCH(&desc);
return OK; return OK;
/* A lot of goto's! But they make the error handling much simpler */ /* A lot of goto's! But they make the error handling much simpler */
errout_with_semaphore: errout_with_semaphore:
inode_semgive(); inode_semgive();
errout_with_mountpt: errout_with_mountpt:
inode_release(mountpt_inode); inode_release(mountpt_inode);
if (blkdrvr_inode) if (blkdrvr_inode)
{ {
inode_release(blkdrvr_inode); inode_release(blkdrvr_inode);
} }
errout_with_search:
RELEASE_SEARCH(&desc);
errout: errout:
set_errno(errcode); set_errno(errcode);
return ERROR; return ERROR;
+6 -2
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. * have incremented the reference count on the inode.
*/ */
RESET_SEARCH(&desc); SETUP_SEARCH(&desc, fullpath, false);
desc.path = fullpath;
ret = inode_find(&desc); ret = inode_find(&desc);
if (ret >= 0) if (ret >= 0)
@@ -236,16 +235,21 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...)
inode->i_crefs = 1; inode->i_crefs = 1;
} }
RELEASE_SEARCH(&desc);
sched_unlock(); sched_unlock();
return mqdes; return mqdes;
errout_with_msgq: errout_with_msgq:
mq_msgqfree(msgq); mq_msgqfree(msgq);
inode->u.i_mqueue = NULL; inode->u.i_mqueue = NULL;
errout_with_inode: errout_with_inode:
inode_release(inode); inode_release(inode);
errout_with_lock: errout_with_lock:
RELEASE_SEARCH(&desc);
sched_unlock(); sched_unlock();
errout: errout:
set_errno(errcode); set_errno(errcode);
return (mqd_t)ERROR; return (mqd_t)ERROR;
+7 -4
View File
@@ -87,8 +87,7 @@ int mq_unlink(FAR const char *mq_name)
/* Get the inode for this message queue. */ /* Get the inode for this message queue. */
RESET_SEARCH(&desc); SETUP_SEARCH(&desc, fullpath, false);
desc.path = fullpath;
sched_lock(); sched_lock();
ret = inode_find(&desc); 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 */ /* There is no inode that includes in this path */
errcode = -ret; errcode = -ret;
goto errout; goto errout_with_search;
} }
/* Get the search results */ /* Get the search results */
@@ -149,14 +148,18 @@ int mq_unlink(FAR const char *mq_name)
inode_semgive(); inode_semgive();
mq_inode_release(inode); mq_inode_release(inode);
RELEASE_SEARCH(&desc);
sched_unlock(); sched_unlock();
return OK; return OK;
errout_with_semaphore: errout_with_semaphore:
inode_semgive(); inode_semgive();
errout_with_inode: errout_with_inode:
inode_release(inode); inode_release(inode);
errout:
errout_with_search:
RELEASE_SEARCH(&desc);
set_errno(errcode); set_errno(errcode);
sched_unlock(); sched_unlock();
return ERROR; return ERROR;
+128 -129
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 */ /* 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 /* Something exists at this path. Get the search results */
* 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(); 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); if (!INODE_IS_NAMEDSEM(inode))
/* 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)
{ {
/* Something exists at this path. Get the search results */ errcode = ENXIO;
goto errout_with_inode;
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;
} }
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; return sem;
errout_with_inode: errout_with_inode:
inode_release(inode); inode_release(inode);
errout_with_lock: errout_with_lock:
RELEASE_SEARCH(&desc);
set_errno(errcode); set_errno(errcode);
sched_unlock(); sched_unlock();
return (FAR sem_t *)ERROR; return (FAR sem_t *)ERROR;
+7 -4
View File
@@ -91,8 +91,7 @@ int sem_unlink(FAR const char *name)
/* Get the inode for this semaphore. */ /* Get the inode for this semaphore. */
RESET_SEARCH(&desc); SETUP_SEARCH(&desc, fullpath, false);
desc.path = fullpath;
sched_lock(); sched_lock();
ret = inode_find(&desc); ret = inode_find(&desc);
@@ -101,7 +100,7 @@ int sem_unlink(FAR const char *name)
/* There is no inode that includes in this path */ /* There is no inode that includes in this path */
errcode = -ret; errcode = -ret;
goto errout; goto errout_with_search;
} }
/* Get the search results */ /* Get the search results */
@@ -152,14 +151,18 @@ int sem_unlink(FAR const char *name)
inode_semgive(); inode_semgive();
ret = sem_close((FAR sem_t *)inode->u.i_nsem); ret = sem_close((FAR sem_t *)inode->u.i_nsem);
RELEASE_SEARCH(&desc);
sched_unlock(); sched_unlock();
return ret; return ret;
errout_with_semaphore: errout_with_semaphore:
inode_semgive(); inode_semgive();
errout_with_inode: errout_with_inode:
inode_release(inode); inode_release(inode);
errout:
errout_with_search:
RELEASE_SEARCH(&desc);
set_errno(errcode); set_errno(errcode);
sched_unlock(); sched_unlock();
return ERROR; return ERROR;
+19 -7
View File
@@ -2446,15 +2446,14 @@ static int unionfs_getmount(FAR const char *path, FAR struct inode **inode)
/* Find the mountpt */ /* Find the mountpt */
RESET_SEARCH(&desc); SETUP_SEARCH(&desc, path, false);
desc.path = path;
ret = inode_find(&desc); ret = inode_find(&desc);
if (ret < 0) if (ret < 0)
{ {
/* Mountpoint inode not found */ /* Mountpoint inode not found */
return ret; goto errout_with_search;
} }
/* Get the search results */ /* Get the search results */
@@ -2462,20 +2461,33 @@ static int unionfs_getmount(FAR const char *path, FAR struct inode **inode)
minode = desc.node; minode = desc.node;
DEBUGASSERT(minode != NULL); 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)) 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); ret = -EINVAL;
return -EINVAL; goto errout_with_inode;
} }
/* Success! */ /* Success! */
*inode = minode; *inode = minode;
RELEASE_SEARCH(&desc);
return OK; return OK;
errout_with_inode:
inode_release(minode);
errout_with_search:
RELEASE_SEARCH(&desc);
return ret;
} }
/**************************************************************************** /****************************************************************************
+8 -4
View File
@@ -107,8 +107,7 @@ int link(FAR const char *path1, FAR const char *path2)
* does not lie on a mounted volume. * does not lie on a mounted volume.
*/ */
RESET_SEARCH(&desc); SETUP_SEARCH(&desc, path2, false);
desc.path = path2;
ret = inode_find(&desc); ret = inode_find(&desc);
if (ret >= 0) if (ret >= 0)
@@ -149,7 +148,7 @@ int link(FAR const char *path1, FAR const char *path2)
if (newpath2 == NULL) if (newpath2 == NULL)
{ {
errcode = ENOMEM; errcode = ENOMEM;
goto errout; goto errout_with_search;
} }
/* Create an inode in the pseudo-filesystem at this path. /* 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); kmm_free(newpath2);
errcode = -ret; errcode = -ret;
goto errout; goto errout_with_search;
} }
/* Initialize the inode */ /* Initialize the inode */
@@ -177,10 +176,15 @@ int link(FAR const char *path1, FAR const char *path2)
/* Symbolic link successfully created */ /* Symbolic link successfully created */
RELEASE_SEARCH(&desc);
return OK; return OK;
errout_with_inode: errout_with_inode:
inode_release(inode); inode_release(inode);
errout_with_search:
RELEASE_SEARCH(&desc);
errout: errout:
set_errno(errcode); set_errno(errcode);
return ERROR; return ERROR;
+9 -7
View File
@@ -86,13 +86,12 @@ int mkdir(const char *pathname, mode_t mode)
{ {
struct inode_search_s desc; struct inode_search_s desc;
FAR struct inode *inode; FAR struct inode *inode;
int errcode; int errcode;
int ret; int ret;
/* Find the inode that includes this path */ /* Find the inode that includes this path */
RESET_SEARCH(&desc); SETUP_SEARCH(&desc, pathname, false);
desc.path = pathname;
ret = inode_find(&desc); ret = inode_find(&desc);
if (ret >= 0) if (ret >= 0)
@@ -164,24 +163,27 @@ int mkdir(const char *pathname, mode_t mode)
if (ret < 0) if (ret < 0)
{ {
errcode = -ret; errcode = -ret;
goto errout; goto errout_with_search;
} }
} }
#else #else
else else
{ {
errcode = ENXIO; errcode = ENXIO;
goto errout; goto errout_with_search;
} }
#endif #endif
/* Directory successfully created */ /* Directory successfully created */
RELEASE_SEARCH(&desc);
return OK; return OK;
errout_with_inode: errout_with_inode:
inode_release(inode); inode_release(inode);
errout:
errout_with_search:
RELEASE_SEARCH(&desc);
set_errno(errcode); set_errno(errcode);
return ERROR; return ERROR;
} }
+12 -7
View File
@@ -121,8 +121,7 @@ int open(const char *path, int oflags, ...)
/* Get an inode for this file */ /* Get an inode for this file */
RESET_SEARCH(&desc); SETUP_SEARCH(&desc, path, false);
desc.path = path;
ret = inode_find(&desc); ret = inode_find(&desc);
if (ret < 0) if (ret < 0)
@@ -133,7 +132,7 @@ int open(const char *path, int oflags, ...)
*/ */
ret = -ret; ret = -ret;
goto errout; goto errout_with_search;
} }
/* Get the search results */ /* Get the search results */
@@ -164,11 +163,12 @@ int open(const char *path, int oflags, ...)
if (fd < 0) if (fd < 0)
{ {
ret = fd; ret = fd;
goto errout; goto errout_with_search;
} }
/* Return the file descriptor */ /* Return the file descriptor */
RELEASE_SEARCH(&desc);
leave_cancellation_point(); leave_cancellation_point();
return fd; return fd;
} }
@@ -215,8 +215,7 @@ int open(const char *path, int oflags, ...)
{ {
/* The errno value has already been set */ /* The errno value has already been set */
leave_cancellation_point(); goto errout;
return ERROR;
} }
/* Perform the driver open operation. NOTE that the open method may be /* Perform the driver open operation. NOTE that the open method may be
@@ -276,15 +275,21 @@ int open(const char *path, int oflags, ...)
} }
#endif #endif
RELEASE_SEARCH(&desc);
leave_cancellation_point(); leave_cancellation_point();
return fd; return fd;
errout_with_fd: errout_with_fd:
files_release(fd); files_release(fd);
errout_with_inode: errout_with_inode:
inode_release(inode); inode_release(inode);
errout:
errout_with_search:
RELEASE_SEARCH(&desc);
set_errno(ret); set_errno(ret);
errout:
leave_cancellation_point(); leave_cancellation_point();
return ERROR; return ERROR;
} }
+6 -7
View File
@@ -93,17 +93,13 @@ ssize_t readlink(FAR const char *path, FAR char *buf, size_t bufsize)
* symbolic link node. * symbolic link node.
*/ */
RESET_SEARCH(&desc); SETUP_SEARCH(&desc, path, true);
desc.path = path;
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
desc.nofollow = true;
#endif
ret = inode_find(&desc); ret = inode_find(&desc);
if (ret < 0) if (ret < 0)
{ {
errcode = -ret; errcode = -ret;
goto errout; goto errout_with_search;
} }
/* Get the search results */ /* 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 */ /* Release our reference on the inode and return the length */
inode_release(node); inode_release(node);
RELEASE_SEARCH(&desc);
return strlen(buf); return strlen(buf);
errout_with_inode: errout_with_inode:
inode_release(node); inode_release(node);
errout:
errout_with_search:
RELEASE_SEARCH(&desc);
set_errno(errcode); set_errno(errcode);
return ERROR; return ERROR;
} }
+17 -15
View File
@@ -83,7 +83,9 @@
int rename(FAR const char *oldpath, FAR const char *newpath) int rename(FAR const char *oldpath, FAR const char *newpath)
{ {
struct inode_search_s olddesc; struct inode_search_s olddesc;
#ifndef CONFIG_DISABLE_MOUNTPOINT
struct inode_search_s newdesc; struct inode_search_s newdesc;
#endif
FAR struct inode *oldinode; FAR struct inode *oldinode;
FAR struct inode *newinode; FAR struct inode *newinode;
int errcode; int errcode;
@@ -101,11 +103,7 @@ int rename(FAR const char *oldpath, FAR const char *newpath)
/* Get an inode that includes the oldpath */ /* Get an inode that includes the oldpath */
RESET_SEARCH(&olddesc); SETUP_SEARCH(&olddesc, oldpath, true);
olddesc.path = oldpath;
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
olddesc.nofollow = true;
#endif
ret = inode_find(&olddesc); ret = inode_find(&olddesc);
if (ret < 0) 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 */ /* There is no inode that includes in this path */
errcode = -ret; errcode = -ret;
goto errout; goto errout_with_oldsearch;
} }
/* Get the search results */ /* Get the search results */
@@ -130,11 +128,7 @@ int rename(FAR const char *oldpath, FAR const char *newpath)
* mountpoint * mountpoint
*/ */
RESET_SEARCH(&newdesc); SETUP_SEARCH(&newdesc, newpath, true);
newdesc.path = newpath;
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
newdesc.nofollow = true;
#endif
ret = inode_find(&newdesc); ret = inode_find(&newdesc);
if (ret < 0) 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 */ /* There is no mountpoint that includes in this path */
errcode = -ret; errcode = -ret;
goto errout_with_oldinode; goto errout_with_newsearch;
} }
/* Get the search results */ /* Get the search results */
@@ -181,9 +175,10 @@ int rename(FAR const char *oldpath, FAR const char *newpath)
/* Successfully renamed */ /* Successfully renamed */
inode_release(newinode); inode_release(newinode);
RELEASE_SEARCH(&newdesc);
} }
else else
#endif #endif /* CONFIG_DISABLE_MOUNTPOINT */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS #ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
{ {
/* Create a new, empty inode at the destination location. /* Create a new, empty inode at the destination location.
@@ -246,22 +241,29 @@ int rename(FAR const char *oldpath, FAR const char *newpath)
#else #else
{ {
errcode = ENXIO; errcode = ENXIO;
goto errout; goto errout_with_oldsearch;
} }
#endif #endif
/* Successfully renamed */ /* Successfully renamed */
inode_release(oldinode); inode_release(oldinode);
RELEASE_SEARCH(&olddesc);
return OK; return OK;
#ifndef CONFIG_DISABLE_MOUNTPOINT #ifndef CONFIG_DISABLE_MOUNTPOINT
errout_with_newinode: errout_with_newinode:
inode_release(newinode); inode_release(newinode);
errout_with_newsearch:
RELEASE_SEARCH(&newdesc);
#endif #endif
errout_with_oldinode: errout_with_oldinode:
inode_release(oldinode); inode_release(oldinode);
errout:
errout_with_oldsearch:
RELEASE_SEARCH(&olddesc);
set_errno(errcode); set_errno(errcode);
return ERROR; return ERROR;
} }
+5 -7
View File
@@ -93,11 +93,7 @@ int rmdir(FAR const char *pathname)
* on the inode if one is found. * on the inode if one is found.
*/ */
RESET_SEARCH(&desc); SETUP_SEARCH(&desc, pathname, true);
desc.path = pathname;
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
desc.nofollow = true;
#endif
ret = inode_find(&desc); ret = inode_find(&desc);
if (ret < 0) if (ret < 0)
@@ -105,7 +101,7 @@ int rmdir(FAR const char *pathname)
/* There is no inode that includes in this path */ /* There is no inode that includes in this path */
errcode = -ret; errcode = -ret;
goto errout; goto errout_with_search;
} }
/* Get the search results */ /* Get the search results */
@@ -188,11 +184,13 @@ int rmdir(FAR const char *pathname)
/* Successfully removed the directory */ /* Successfully removed the directory */
inode_release(inode); inode_release(inode);
RELEASE_SEARCH(&desc);
return OK; return OK;
errout_with_inode: errout_with_inode:
inode_release(inode); inode_release(inode);
errout: errout_with_search:
RELEASE_SEARCH(&desc);
set_errno(errcode); set_errno(errcode);
return ERROR; return ERROR;
} }
+7 -6
View File
@@ -234,11 +234,7 @@ int stat(FAR const char *path, FAR struct stat *buf)
/* Get an inode for this file */ /* Get an inode for this file */
RESET_SEARCH(&desc); SETUP_SEARCH(&desc, path, true);
desc.path = path;
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
desc.nofollow = true;
#endif
ret = inode_find(&desc); ret = inode_find(&desc);
if (ret < 0) if (ret < 0)
@@ -248,7 +244,7 @@ int stat(FAR const char *path, FAR struct stat *buf)
*/ */
ret = -ret; ret = -ret;
goto errout; goto errout_with_search;
} }
/* Get the search results */ /* Get the search results */
@@ -293,12 +289,17 @@ int stat(FAR const char *path, FAR struct stat *buf)
/* Successfully stat'ed the file */ /* Successfully stat'ed the file */
inode_release(inode); inode_release(inode);
RELEASE_SEARCH(&desc);
return OK; return OK;
/* Failure conditions always set the errno appropriately */ /* Failure conditions always set the errno appropriately */
errout_with_inode: errout_with_inode:
inode_release(inode); inode_release(inode);
errout_with_search:
RELEASE_SEARCH(&desc);
errout: errout:
set_errno(ret); set_errno(ret);
return ERROR; return ERROR;
+7 -3
View File
@@ -105,8 +105,7 @@ int statfs(FAR const char *path, FAR struct statfs *buf)
/* Get an inode for this file */ /* Get an inode for this file */
RESET_SEARCH(&desc); SETUP_SEARCH(&desc, path, false);
desc.path = path;
ret = inode_find(&desc); ret = inode_find(&desc);
if (ret < 0) if (ret < 0)
@@ -116,7 +115,7 @@ int statfs(FAR const char *path, FAR struct statfs *buf)
*/ */
ret = -ret; ret = -ret;
goto errout; goto errout_with_search;
} }
/* Get the search results */ /* Get the search results */
@@ -161,12 +160,17 @@ int statfs(FAR const char *path, FAR struct statfs *buf)
/* Successfully statfs'ed the file */ /* Successfully statfs'ed the file */
inode_release(inode); inode_release(inode);
RELEASE_SEARCH(&desc);
return OK; return OK;
/* Failure conditions always set the errno appropriately */ /* Failure conditions always set the errno appropriately */
errout_with_inode: errout_with_inode:
inode_release(inode); inode_release(inode);
errout_with_search:
RELEASE_SEARCH(&desc);
errout: errout:
set_errno(ret); set_errno(ret);
return ERROR; return ERROR;
+6 -7
View File
@@ -92,11 +92,7 @@ int unlink(FAR const char *pathname)
* which may be a symbolic link) * which may be a symbolic link)
*/ */
RESET_SEARCH(&desc); SETUP_SEARCH(&desc, pathname, true);
desc.path = pathname;
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
desc.nofollow = true;
#endif
ret = inode_find(&desc); ret = inode_find(&desc);
if (ret < 0) if (ret < 0)
@@ -104,7 +100,7 @@ int unlink(FAR const char *pathname)
/* There is no inode that includes in this path */ /* There is no inode that includes in this path */
errcode = -ret; errcode = -ret;
goto errout; goto errout_with_search;
} }
/* Get the search results */ /* Get the search results */
@@ -233,11 +229,14 @@ int unlink(FAR const char *pathname)
/* Successfully unlinked */ /* Successfully unlinked */
inode_release(inode); inode_release(inode);
RELEASE_SEARCH(&desc);
return OK; return OK;
errout_with_inode: errout_with_inode:
inode_release(inode); inode_release(inode);
errout:
errout_with_search:
RELEASE_SEARCH(&desc);
set_errno(errcode); set_errno(errcode);
return ERROR; return ERROR;
} }