Skip to content

Commit

Permalink
fs: add support for mount point listing on vfs root
Browse files Browse the repository at this point in the history
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 26, 2019
1 parent 1630292 commit fae62fc
Showing 1 changed file with 74 additions and 7 deletions.
81 changes: 74 additions & 7 deletions subsys/fs/fs.c
Expand Up @@ -213,11 +213,23 @@ int fs_opendir(struct fs_dir_t *zdp, const char *abs_path)
int rc = -EINVAL; int rc = -EINVAL;


if ((abs_path == NULL) || if ((abs_path == NULL) ||
(strlen(abs_path) <= 1) || (abs_path[0] != '/')) { (strlen(abs_path) < 1) || (abs_path[0] != '/')) {
LOG_ERR("invalid file name!!"); LOG_ERR("invalid file name!!");
return -EINVAL; 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); rc = fs_get_mnt_point(&mp, abs_path, NULL);
if (rc < 0) { if (rc < 0) {
LOG_ERR("%s:mount point not found!!", __func__); LOG_ERR("%s:mount point not found!!", __func__);
Expand All @@ -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 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) { /* VFS root dir */
rc = zdp->mp->fs->readdir(zdp, entry); if (zdp->dirp == NULL) {
if (rc < 0) { /* No more entries */
LOG_ERR("directory read error (%d)", rc); 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 fs_closedir(struct fs_dir_t *zdp)
{ {
int rc = -EINVAL; int rc = -EINVAL;


if (zdp->mp == NULL) {
/* VFS root dir */
zdp->dirp = NULL;
return 0;
}

if (zdp->mp->fs->closedir != NULL) { if (zdp->mp->fs->closedir != NULL) {
rc = zdp->mp->fs->closedir(zdp); rc = zdp->mp->fs->closedir(zdp);
if (rc < 0) { if (rc < 0) {
Expand Down

0 comments on commit fae62fc

Please sign in to comment.