Skip to content
Permalink
Browse files

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>
  • Loading branch information...
jimparis authored and carlescufi committed Jul 24, 2019
1 parent 1630292 commit fae62fc4fccf0ac9e147829b15f43b233bc389fb
Showing with 74 additions and 7 deletions.
  1. +74 −7 subsys/fs/fs.c
@@ -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);
}
}
return rc;
}

if (zdp->mp->fs->readdir != NULL) {
rc = zdp->mp->fs->readdir(zdp, entry);
if (rc < 0) {
LOG_ERR("directory read error (%d)", 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) {

0 comments on commit fae62fc

Please sign in to comment.
You can’t perform that action at this time.