Skip to content

Commit fae62fc

Browse files
jimpariscarlescufi
authored andcommitted
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>
1 parent 1630292 commit fae62fc

File tree

1 file changed

+74
-7
lines changed

1 file changed

+74
-7
lines changed

subsys/fs/fs.c

Lines changed: 74 additions & 7 deletions
Original file line numberOriginal file lineDiff line numberDiff line change
@@ -213,11 +213,23 @@ int fs_opendir(struct fs_dir_t *zdp, const char *abs_path)
213
int rc = -EINVAL;
213
int rc = -EINVAL;
214

214

215
if ((abs_path == NULL) ||
215
if ((abs_path == NULL) ||
216-
(strlen(abs_path) <= 1) || (abs_path[0] != '/')) {
216+
(strlen(abs_path) < 1) || (abs_path[0] != '/')) {
217
LOG_ERR("invalid file name!!");
217
LOG_ERR("invalid file name!!");
218
return -EINVAL;
218
return -EINVAL;
219
}
219
}
220

220

221+
if (strcmp(abs_path, "/") == 0) {
222+
/* Open VFS root dir, marked by zdp->mp == NULL */
223+
k_mutex_lock(&mutex, K_FOREVER);
224+
225+
zdp->mp = NULL;
226+
zdp->dirp = sys_dlist_peek_head(&fs_mnt_list);
227+
228+
k_mutex_unlock(&mutex);
229+
230+
return 0;
231+
}
232+
221
rc = fs_get_mnt_point(&mp, abs_path, NULL);
233
rc = fs_get_mnt_point(&mp, abs_path, NULL);
222
if (rc < 0) {
234
if (rc < 0) {
223
LOG_ERR("%s:mount point not found!!", __func__);
235
LOG_ERR("%s:mount point not found!!", __func__);
@@ -238,21 +250,76 @@ int fs_opendir(struct fs_dir_t *zdp, const char *abs_path)
238

250

239
int fs_readdir(struct fs_dir_t *zdp, struct fs_dirent *entry)
251
int fs_readdir(struct fs_dir_t *zdp, struct fs_dirent *entry)
240
{
252
{
241-
int rc = -EINVAL;
253+
if (zdp->mp) {
254+
/* Delegate to mounted filesystem */
255+
int rc = -EINVAL;
256+
257+
if (zdp->mp->fs->readdir != NULL) {
258+
rc = zdp->mp->fs->readdir(zdp, entry);
259+
if (rc < 0) {
260+
LOG_ERR("directory read error (%d)", rc);
261+
}
262+
}
263+
return rc;
264+
}
242

265

243-
if (zdp->mp->fs->readdir != NULL) {
266+
/* VFS root dir */
244-
rc = zdp->mp->fs->readdir(zdp, entry);
267+
if (zdp->dirp == NULL) {
245-
if (rc < 0) {
268+
/* No more entries */
246-
LOG_ERR("directory read error (%d)", rc);
269+
entry->name[0] = 0;
270+
return 0;
271+
}
272+
273+
/* Find the current and next entries in the mount point dlist */
274+
sys_dnode_t *node, *next = NULL;
275+
bool found = false;
276+
277+
k_mutex_lock(&mutex, K_FOREVER);
278+
279+
SYS_DLIST_FOR_EACH_NODE(&fs_mnt_list, node) {
280+
if (node == zdp->dirp) {
281+
found = true;
282+
283+
/* Pull info from current entry */
284+
struct fs_mount_t *mnt;
285+
286+
mnt = CONTAINER_OF(node, struct fs_mount_t, node);
287+
288+
entry->type = FS_DIR_ENTRY_DIR;
289+
strncpy(entry->name, mnt->mnt_point + 1,
290+
sizeof(entry->name) - 1);
291+
entry->name[sizeof(entry->name) - 1] = 0;
292+
entry->size = 0;
293+
294+
/* Save pointer to the next one, for later */
295+
next = sys_dlist_peek_next(&fs_mnt_list, node);
296+
break;
247
}
297
}
248
}
298
}
249-
return rc;
299+
300+
k_mutex_unlock(&mutex);
301+
302+
if (!found) {
303+
/* Current entry must have been removed before this
304+
* call to readdir -- return an error
305+
*/
306+
return -ENOENT;
307+
}
308+
309+
zdp->dirp = next;
310+
return 0;
250
}
311
}
251

312

252
int fs_closedir(struct fs_dir_t *zdp)
313
int fs_closedir(struct fs_dir_t *zdp)
253
{
314
{
254
int rc = -EINVAL;
315
int rc = -EINVAL;
255

316

317+
if (zdp->mp == NULL) {
318+
/* VFS root dir */
319+
zdp->dirp = NULL;
320+
return 0;
321+
}
322+
256
if (zdp->mp->fs->closedir != NULL) {
323
if (zdp->mp->fs->closedir != NULL) {
257
rc = zdp->mp->fs->closedir(zdp);
324
rc = zdp->mp->fs->closedir(zdp);
258
if (rc < 0) {
325
if (rc < 0) {

0 commit comments

Comments
 (0)