fs: add support for mount point listing on vfs root
This will list all mount points in response to opendir("/"). This isn't perfect; mount points in subdirectories will show up as their full path in this listing. But it's better than just returning -EINVAL. Signed-off-by: Jim Paris <jim@jtan.com>
This commit is contained in:
parent
1630292e5f
commit
fae62fc4fc
|
@ -213,11 +213,23 @@ int fs_opendir(struct fs_dir_t *zdp, const char *abs_path)
|
|||
int rc = -EINVAL;
|
||||
|
||||
if ((abs_path == NULL) ||
|
||||
(strlen(abs_path) <= 1) || (abs_path[0] != '/')) {
|
||||
(strlen(abs_path) < 1) || (abs_path[0] != '/')) {
|
||||
LOG_ERR("invalid file name!!");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (strcmp(abs_path, "/") == 0) {
|
||||
/* Open VFS root dir, marked by zdp->mp == NULL */
|
||||
k_mutex_lock(&mutex, K_FOREVER);
|
||||
|
||||
zdp->mp = NULL;
|
||||
zdp->dirp = sys_dlist_peek_head(&fs_mnt_list);
|
||||
|
||||
k_mutex_unlock(&mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = fs_get_mnt_point(&mp, abs_path, NULL);
|
||||
if (rc < 0) {
|
||||
LOG_ERR("%s:mount point not found!!", __func__);
|
||||
|
@ -238,21 +250,76 @@ int fs_opendir(struct fs_dir_t *zdp, const char *abs_path)
|
|||
|
||||
int fs_readdir(struct fs_dir_t *zdp, struct fs_dirent *entry)
|
||||
{
|
||||
int rc = -EINVAL;
|
||||
if (zdp->mp) {
|
||||
/* Delegate to mounted filesystem */
|
||||
int rc = -EINVAL;
|
||||
|
||||
if (zdp->mp->fs->readdir != NULL) {
|
||||
rc = zdp->mp->fs->readdir(zdp, entry);
|
||||
if (rc < 0) {
|
||||
LOG_ERR("directory read error (%d)", rc);
|
||||
if (zdp->mp->fs->readdir != NULL) {
|
||||
rc = zdp->mp->fs->readdir(zdp, entry);
|
||||
if (rc < 0) {
|
||||
LOG_ERR("directory read error (%d)", rc);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* VFS root dir */
|
||||
if (zdp->dirp == NULL) {
|
||||
/* No more entries */
|
||||
entry->name[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find the current and next entries in the mount point dlist */
|
||||
sys_dnode_t *node, *next = NULL;
|
||||
bool found = false;
|
||||
|
||||
k_mutex_lock(&mutex, K_FOREVER);
|
||||
|
||||
SYS_DLIST_FOR_EACH_NODE(&fs_mnt_list, node) {
|
||||
if (node == zdp->dirp) {
|
||||
found = true;
|
||||
|
||||
/* Pull info from current entry */
|
||||
struct fs_mount_t *mnt;
|
||||
|
||||
mnt = CONTAINER_OF(node, struct fs_mount_t, node);
|
||||
|
||||
entry->type = FS_DIR_ENTRY_DIR;
|
||||
strncpy(entry->name, mnt->mnt_point + 1,
|
||||
sizeof(entry->name) - 1);
|
||||
entry->name[sizeof(entry->name) - 1] = 0;
|
||||
entry->size = 0;
|
||||
|
||||
/* Save pointer to the next one, for later */
|
||||
next = sys_dlist_peek_next(&fs_mnt_list, node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
|
||||
k_mutex_unlock(&mutex);
|
||||
|
||||
if (!found) {
|
||||
/* Current entry must have been removed before this
|
||||
* call to readdir -- return an error
|
||||
*/
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
zdp->dirp = next;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fs_closedir(struct fs_dir_t *zdp)
|
||||
{
|
||||
int rc = -EINVAL;
|
||||
|
||||
if (zdp->mp == NULL) {
|
||||
/* VFS root dir */
|
||||
zdp->dirp = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (zdp->mp->fs->closedir != NULL) {
|
||||
rc = zdp->mp->fs->closedir(zdp);
|
||||
if (rc < 0) {
|
||||
|
|
Loading…
Reference in a new issue