Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | /* SPDX-License-Identifier: GPL-2.0 */ /* * Virtual Filesystem layer for U-Boot * * Provides a unified path namespace with mount points, inspired by the * Linux VFS but heavily cut down for U-Boot's needs. * * Copyright 2026 Simon Glass <sjg@chromium.org> */ #ifndef __VFS_H #define __VFS_H #include <dir.h> struct blk_desc; struct cmd_tbl; struct disk_partition; struct fs_dirent; struct fs_statfs; struct udevice; /** * struct vfsmount - A mount point in the VFS * * This is the UCLASS_MOUNT per-device uclass-private data. All mount * devices are children of the VFS root FS device. Each links a mount-point * directory to a UCLASS_FS device. * * @dir: UCLASS_DIR device that is the mount point * @target: UCLASS_FS device that is mounted here */ struct vfsmount { struct udevice *dir; struct udevice *target; }; /** * vfs_init() - Initialise the VFS * * Creates the VFS root directory device. Normally called automatically * via EVT_LAST_STAGE_INIT during boot. May also be called directly in * tests after a DM tree reset. * * Return: 0 if OK, -ve on error */ int vfs_init(void); /** * vfs_chdir() - Change the current working directory * * @path: New directory (absolute or relative to current cwd) * Return: 0 if OK, -ve on error */ int vfs_chdir(const char *path); /** * vfs_getcwd() - Get the current working directory * * Return: pointer to the cwd string (static buffer, do not free) */ const char *vfs_getcwd(void); /** * vfs_path_resolve() - Resolve a path against a given working directory * * If @path starts with '/', it is used as an absolute path. Otherwise it * is joined with @cwd. In both cases, '.' and '..' components are resolved. * * @cwd: Current working directory (must be absolute) * @path: Input path (absolute or relative), or NULL/empty for cwd * @buf: Buffer to write the resolved absolute path * @size: Size of @buf * Return: pointer to @buf */ const char *vfs_path_resolve(const char *cwd, const char *path, char *buf, int size); /** * vfs_root() - Get the VFS root FS device * * Return: VFS root FS device, or NULL if not initialised */ struct udevice *vfs_root(void); /** * vfs_resolve() - Resolve a path to a directory * * Walks the path, following mount points along the way. For each * component, looks up the directory in the current filesystem. If the * directory does not exist (e.g. in the VFS rootfs), it is created. * * For "/host", looks up (or creates) "host" in the VFS rootfs. * For "/mnt/data", follows the mount at /mnt, then looks up "data" * in the mounted filesystem. * * @vfs: VFS root FS device * @path: Absolute path (must start with '/') * @dirp: Returns the UCLASS_DIR device for the final component * Return: 0 if OK, -ve on error */ int vfs_resolve(struct udevice *vfs, const char *path, struct udevice **dirp); /** * vfs_mount() - Mount a filesystem at a directory * * Creates a UCLASS_MOUNT device linking @dir to @fsdev. * * @vfs: VFS root FS device * @dir: UCLASS_DIR device for the mount point * @fsdev: UCLASS_FS device to mount * Return: 0 if OK, -ve on error */ int vfs_mount(struct udevice *vfs, struct udevice *dir, struct udevice *fsdev); /** * vfs_umount() - Unmount a filesystem * * @mnt_dev: UCLASS_MOUNT device to unmount * Return: 0 if OK, -ve on error */ int vfs_umount(struct udevice *mnt_dev); /** * vfs_umount_path() - Unmount the filesystem at a path * * @vfs: VFS root FS device * @path: Mount point to remove * Return: 0 if OK, -ENOENT if not mounted, other -ve on error */ int vfs_umount_path(struct udevice *vfs, const char *path); /** * vfs_umount_all() - Unmount all filesystems * * Unmounts all mounted filesystems. Returns an error if any unmount fails. * * Return: 0 if OK, -ve on error */ int vfs_umount_all(void); /** * vfs_find_mount() - Find the mount covering a path * * Walks the mount tree from the VFS root, following mount points for * each path component. Returns the deepest mount and the remaining * subpath. * * @vfs: VFS root FS device * @path: Absolute path to resolve * @mntp: Returns the UCLASS_MOUNT device * @subpathp: Returns pointer into @path for the remaining path within the * mounted filesystem * Return: 0 if OK (with @mntp set to NULL if path is the VFS root), * -ENOENT if no mount covers this path */ int vfs_find_mount(struct udevice *vfs, const char *path, struct udevice **mntp, const char **subpathp); /** * vfs_is_mount_point() - Check whether a directory is a mount point * * @dir: UCLASS_DIR device to check * Return: true if this directory has an active mount, false otherwise */ bool vfs_is_mount_point(struct udevice *dir); /** * vfs_print_mounts() - Print all current mounts */ void vfs_print_mounts(void); /** * vfs_ls() - List directory contents * * Resolves the path through the mount table and lists directory entries * using dir_open(), dir_read() and dir_close(). * * @path: Absolute path to list, or "/" for root * Return: 0 if OK, -ve on error */ int vfs_ls(const char *path); /** * vfs_open_file() - Open a file by absolute VFS path * * Resolves the path through the mount tree, splits into directory and leaf, * then opens the file. * * @path: Absolute VFS path to the file * @oflags: Open flags (DIR_O_RDONLY, DIR_O_WRONLY, DIR_O_RDWR) * @filp: Returns the UCLASS_FILE device * Return: 0 if OK, -ve on error */ int vfs_open_file(const char *path, enum dir_open_flags_t oflags, struct udevice **filp); /** * vfs_stat() - Get information about a file or directory * * Looks up the named entry in its parent directory and fills in a * struct fs_dirent with type, size and timestamps. Handles both files * and directories. Calls vfs_init() if needed. * * @path: Absolute or relative VFS path * @dent: Returns the directory entry information * Return: 0 if OK, -ve on error */ int vfs_stat(const char *path, struct fs_dirent *dent); /** * vfs_mkdir() - Create a directory by absolute or relative VFS path * * @path: Path of the directory to create * Return: 0 if OK, -ve on error */ int vfs_mkdir(const char *path); /** * vfs_unlink() - Delete a file by absolute or relative VFS path * * @path: Path of the file to delete * Return: 0 if OK, -ve on error */ int vfs_unlink(const char *path); /** * vfs_rename() - Rename or move a file or directory * * Both paths must be on the same mounted filesystem. * * @old_path: Current absolute or relative VFS path * @new_path: New absolute or relative VFS path * Return: 0 if OK, -EXDEV if paths are on different mounts, other -ve on error */ /** * vfs_ln() - Create a symbolic link * * @path: Absolute or relative VFS path for the new symlink * @target: Target path the symlink points to * Return: 0 if OK, -ve on error */ int vfs_ln(const char *path, const char *target); int vfs_rename(const char *old_path, const char *new_path); /** * vfs_readlink() - Read a symbolic link target * * @path: Absolute or relative VFS path to the symlink * @buf: Buffer to receive the target path * @size: Size of buffer * Return: length of target, or -ve on error */ int vfs_readlink(const char *path, char *buf, int size); /** * vfs_statfs() - Get filesystem statistics for a mount point * * @path: Absolute or relative VFS path (any path within the mount) * @stats: Returns filesystem statistics * Return: 0 if OK, -ve on error */ int vfs_statfs(const char *path, struct fs_statfs *stats); /** * fs_mount_blkdev_auto() - Auto-detect and mount a filesystem from a block * device * * Tries each UCLASS_FS driver with a "_fs" suffix in turn until one * succeeds. * * @desc: Block device descriptor * @part: Partition information * @mountpoint: Absolute path to mount at * Return: 0 if OK, -ENODEV if no FS type matched, other -ve on error */ int fs_mount_blkdev_auto(struct blk_desc *desc, int part_num, struct disk_partition *part, const char *mountpoint); /** * fs_mount_blkdev() - Create and mount a FS device from a block device * * Uses a naming convention to find the right driver: filesystem type "ext4" * maps to driver "ext4_fs". The block device and partition info are stored * in the generic struct fs_plat so that any block-backed FS driver can * read them. * * @type: Filesystem type name (e.g. "ext4") * @desc: Block device descriptor * @part: Partition information * @mountpoint: Absolute path to mount at * Return: 0 if OK, -ve on error */ int fs_mount_blkdev(const char *type, struct blk_desc *desc, int part_num, struct disk_partition *part, const char *mountpoint); /** * vfs_print_mounts() - Print all current mounts */ void vfs_print_mounts(void); /** * vfs_print_df() - Print filesystem usage for all mounts * * Iterates all mounts and prints statfs info for those that support it. * Mounts that do not support statfs are listed with dashes. */ void vfs_print_df(void); /** * do_cp() - Copy a file within the VFS * * Implements the 'fs cp' subcommand. Defined in cmd/fs.c, declared here * so that cmd/vfs.c can reference it. */ int do_cp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); #ifdef CONFIG_AUTO_COMPLETE /** * vfs_complete() - Complete a partial VFS path * * Suitable for use as (or called from) a U_BOOT_CMD complete callback. * Fills @cmdv with matching directory entries. * * @buf: Scratch buffer (must be at least FILE_MAX_PATH_LEN bytes) * @path: Partial path to complete (absolute or relative) * @maxv: Maximum number of entries in @cmdv * @cmdv: Output array of matching names (NULL-terminated) * Return: number of matches */ int vfs_complete(char *buf, const char *path, int maxv, char *cmdv[]); /** * vfs_cmd_complete() - Complete callback for commands taking a VFS path * * Completes the last argument as a VFS path. Can be passed directly to * U_BOOT_CMD_COMPLETE. */ int vfs_cmd_complete(int argc, char *const argv[], char last_char, int maxv, char *cmdv[]); #endif #endif |