diff --git a/fs/dirent/fs_opendir.c b/fs/dirent/fs_opendir.c index 91a49ba9375..62b39d44102 100644 --- a/fs/dirent/fs_opendir.c +++ b/fs/dirent/fs_opendir.c @@ -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; diff --git a/fs/driver/fs_findblockdriver.c b/fs/driver/fs_findblockdriver.c index 5376c7b5a1a..0615a474b23 100644 --- a/fs/driver/fs_findblockdriver.c +++ b/fs/driver/fs_findblockdriver.c @@ -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; } diff --git a/fs/fat/fs_fat32attrib.c b/fs/fat/fs_fat32attrib.c index 3dc4712d0e7..0dd9b60a2ed 100644 --- a/fs/fat/fs_fat32attrib.c +++ b/fs/fat/fs_fat32attrib.c @@ -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; } diff --git a/fs/inode/fs_inoderemove.c b/fs/inode/fs_inoderemove.c index 49d7f84750b..7da8235964e 100644 --- a/fs/inode/fs_inoderemove.c +++ b/fs/inode/fs_inoderemove.c @@ -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; } diff --git a/fs/inode/fs_inodereserve.c b/fs/inode/fs_inodereserve.c index ecd3a564154..1c08b055676 100644 --- a/fs/inode/fs_inodereserve.c +++ b/fs/inode/fs_inodereserve.c @@ -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; } diff --git a/fs/inode/fs_inodesearch.c b/fs/inode/fs_inodesearch.c index b92d30963e6..0fb22b41646 100644 --- a/fs/inode/fs_inodesearch.c +++ b/fs/inode/fs_inodesearch.c @@ -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 */ @@ -541,9 +540,8 @@ int inode_search(FAR struct inode_search_s *desc) /* Reset the search description and perform the search again. */ - RESET_SEARCH(desc); - desc->path = desc->fullpath; - + RELEASE_SEARCH(desc); + SETUP_SEARCH(desc, desc->fullpath, false); ret = _inode_search(desc); } } diff --git a/fs/inode/inode.h b/fs/inode/inode.h index 9d4e966e212..7dbd90e1268 100644 --- a/fs/inode/inode.h +++ b/fs/inode/inode.h @@ -55,23 +55,23 @@ ****************************************************************************/ #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)->nofollow = (n); \ } \ while (0) #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; \ @@ -80,6 +80,8 @@ while (0) #endif +#define RELEASE_SEARCH(d) + /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/fs/mount/fs_automount.c b/fs/mount/fs_automount.c index 55484dc6ed6..e73ce50e244 100644 --- a/fs/mount/fs_automount.c +++ b/fs/mount/fs_automount.c @@ -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; } diff --git a/fs/mount/fs_mount.c b/fs/mount/fs_mount.c index b00cce8dd2a..2fc9d7376fd 100644 --- a/fs/mount/fs_mount.c +++ b/fs/mount/fs_mount.c @@ -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; diff --git a/fs/mount/fs_umount2.c b/fs/mount/fs_umount2.c index 138bb8e6423..e342ae2e16d 100644 --- a/fs/mount/fs_umount2.c +++ b/fs/mount/fs_umount2.c @@ -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; diff --git a/fs/mqueue/mq_open.c b/fs/mqueue/mq_open.c index e80f64d9523..85474e0f3fe 100644 --- a/fs/mqueue/mq_open.c +++ b/fs/mqueue/mq_open.c @@ -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; diff --git a/fs/mqueue/mq_unlink.c b/fs/mqueue/mq_unlink.c index 09ab08d7ada..9705a0ef8ba 100644 --- a/fs/mqueue/mq_unlink.c +++ b/fs/mqueue/mq_unlink.c @@ -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; diff --git a/fs/semaphore/sem_open.c b/fs/semaphore/sem_open.c index 3f8934b43ed..42d6f964706 100644 --- a/fs/semaphore/sem_open.c +++ b/fs/semaphore/sem_open.c @@ -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; diff --git a/fs/semaphore/sem_unlink.c b/fs/semaphore/sem_unlink.c index 33675487b0b..ca73a800418 100644 --- a/fs/semaphore/sem_unlink.c +++ b/fs/semaphore/sem_unlink.c @@ -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; diff --git a/fs/unionfs/fs_unionfs.c b/fs/unionfs/fs_unionfs.c index fb037889771..7746efd47c7 100644 --- a/fs/unionfs/fs_unionfs.c +++ b/fs/unionfs/fs_unionfs.c @@ -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; } /**************************************************************************** diff --git a/fs/vfs/fs_link.c b/fs/vfs/fs_link.c index 2bad20a224d..e9155cf84af 100644 --- a/fs/vfs/fs_link.c +++ b/fs/vfs/fs_link.c @@ -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; diff --git a/fs/vfs/fs_mkdir.c b/fs/vfs/fs_mkdir.c index 8b40384c47a..e310b358595 100644 --- a/fs/vfs/fs_mkdir.c +++ b/fs/vfs/fs_mkdir.c @@ -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; } diff --git a/fs/vfs/fs_open.c b/fs/vfs/fs_open.c index 2c048b2beba..19bf437323b 100644 --- a/fs/vfs/fs_open.c +++ b/fs/vfs/fs_open.c @@ -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; } diff --git a/fs/vfs/fs_readlink.c b/fs/vfs/fs_readlink.c index d4c3a195c3b..77b4afa9a1a 100644 --- a/fs/vfs/fs_readlink.c +++ b/fs/vfs/fs_readlink.c @@ -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; } diff --git a/fs/vfs/fs_rename.c b/fs/vfs/fs_rename.c index 965b4a370a3..12f3c334cc3 100644 --- a/fs/vfs/fs_rename.c +++ b/fs/vfs/fs_rename.c @@ -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; } diff --git a/fs/vfs/fs_rmdir.c b/fs/vfs/fs_rmdir.c index 3cb3d7ba61a..d75c83a7e19 100644 --- a/fs/vfs/fs_rmdir.c +++ b/fs/vfs/fs_rmdir.c @@ -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; } diff --git a/fs/vfs/fs_stat.c b/fs/vfs/fs_stat.c index e988fac25ca..9e9679249b5 100644 --- a/fs/vfs/fs_stat.c +++ b/fs/vfs/fs_stat.c @@ -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; diff --git a/fs/vfs/fs_statfs.c b/fs/vfs/fs_statfs.c index d51fdf0eea4..ff2380fedd6 100644 --- a/fs/vfs/fs_statfs.c +++ b/fs/vfs/fs_statfs.c @@ -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; diff --git a/fs/vfs/fs_unlink.c b/fs/vfs/fs_unlink.c index 84d5b7953ef..c5f958de57c 100644 --- a/fs/vfs/fs_unlink.c +++ b/fs/vfs/fs_unlink.c @@ -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; }