1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-25 14:33:52 +01:00

sys/shell/vfs: Use vfs_iter_mount_dirs instead of vfs_iter_mounts

This solves highly theoretical race conditions of file systems being
unmounted in an application while a shell `df` runs, fixes the previous
weird behavior that `/mountpoint/non-existant-path` could be df'd and
would even report that non-existant path as a file name, but more
practically ensures that an example of vfs_iter_mount_dirs is around.
This commit is contained in:
chrysn 2022-02-16 17:00:20 +01:00
parent f0e80ee10c
commit b9b0ca8972
2 changed files with 20 additions and 9 deletions

View File

@ -998,8 +998,6 @@ int vfs_normalize_path(char *buf, const char *path, size_t buflen);
*
* Set @p cur to @c NULL to start from the beginning
*
* @see @c sc_vfs.c (@c df command) for a usage example
*
* @param[in] cur current iterator value
*
* @return Pointer to next mounted file system in list after @p cur
@ -1029,6 +1027,8 @@ const vfs_mount_t *vfs_iterate_mounts(const vfs_mount_t *cur);
* @ref vfs_dir_ops; any file system that does not support that will
* prematurely terminate the mount point enumeration.
*
* @see @c sc_vfs.c (@c df command) for a usage example
*
* @param[inout] dir The root directory of the discovered mount point
*
* @return @c true if another file system is mounted; @p dir then contains an open directory.

View File

@ -102,11 +102,11 @@ static int _errno_string(int err, char *buf, size_t buflen)
}
#undef _case_snprintf_errno_name
static void _print_df(const char *path)
static void _print_df(vfs_DIR *dir)
{
struct statvfs buf;
int res = vfs_statvfs(path, &buf);
printf("%-16s ", path);
int res = vfs_dstatvfs(dir, &buf);
printf("%-16s ", dir->mp->mount_point);
if (res < 0) {
char err[16];
_errno_string(res, err, sizeof(err));
@ -123,13 +123,24 @@ static int _df_handler(int argc, char **argv)
puts("Mountpoint Total Used Available Capacity");
if (argc > 1) {
const char *path = argv[1];
_print_df(path);
/* Opening a directory just to statfs is somewhat odd, but it is the
* easiest to support with a single _print_df function */
vfs_DIR dir;
int res = vfs_opendir(&dir, path);
if (res == 0) {
_print_df(&dir);
vfs_closedir(&dir);
} else {
char err[16];
_errno_string(res, err, sizeof(err));
printf("Failed to open `%s`: %s\n", path, err);
}
}
else {
/* Iterate through all mount points */
const vfs_mount_t *it = NULL;
while ((it = vfs_iterate_mounts(it)) != NULL) {
_print_df(it->mount_point);
vfs_DIR it = { 0 };
while (vfs_iterate_mount_dirs(&it)) {
_print_df(&it);
}
}
return 0;