Loading...
// SPDX-License-Identifier: GPL-2.0 /* * VFS root directory driver * * Provides the directory driver for the VFS rootfs. The root directory * (path "") lists all mount-point directories as entries. Mount-point * directories themselves have no entries since access crosses into the * mounted filesystem. * * Copyright 2026 Simon Glass <sjg@chromium.org> */ #include <dir.h> #include <dm.h> #include <fs.h> #include <vfs.h> #include <fs_common.h> static int vfs_rootfs_dir_open(struct udevice *dev, struct fs_dir_stream *strm) { strm->offset = 0; return 0; } /** * vfs_rootfs_dir_read() - Read the next directory entry * * For the root directory (path ""), iterates through sibling DIR devices * that have non-empty paths, returning each as a directory entry. For * mount-point directories, returns -ENOENT immediately since their * contents come from the mounted filesystem. */ static int vfs_rootfs_dir_read(struct udevice *dev, struct fs_dir_stream *strm, struct fs_dirent *dent) { struct dir_uc_priv *dir_priv = dev_get_uclass_priv(dev); struct udevice *parent, *child; int idx = 0; /* Only the root dir has entries to list */ if (*dir_priv->path) return -ENOENT; /* Walk children of the FS device, skipping to the current offset */ parent = dev_get_parent(dev); device_foreach_child(child, parent) { struct dir_uc_priv *uc_priv; if (device_get_uclass_id(child) != UCLASS_DIR) continue; uc_priv = dev_get_uclass_priv(child); if (!uc_priv->path || !*uc_priv->path) continue; if (idx++ < strm->offset) continue; strlcpy(dent->name, uc_priv->path, sizeof(dent->name)); dent->type = FS_DT_DIR; dent->size = 0; strm->offset++; return 0; } return -ENOENT; } static int vfs_rootfs_dir_close(struct udevice *dev, struct fs_dir_stream *strm) { return 0; } static struct dir_ops vfs_rootfs_dir_ops = { .open = vfs_rootfs_dir_open, .read = vfs_rootfs_dir_read, .close = vfs_rootfs_dir_close, }; static int vfs_rootfs_dir_remove(struct udevice *dev) { if (vfs_is_mount_point(dev)) return log_msg_ret("drm", -EBUSY); return 0; } U_BOOT_DRIVER(vfs_rootfs_dir) = { .name = "vfs_rootfs_dir", .id = UCLASS_DIR, .ops = &vfs_rootfs_dir_ops, .remove = vfs_rootfs_dir_remove, }; |