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 | /* SPDX-License-Identifier: GPL-2.0 */ /* * U-Boot Filesystem layer * * Models a filesystem which can be mounted and unmounted. It also allows a * directory to be looked up. * * Copyright 2025 Simon Glass <sjg@chromium.org> */ #ifndef __FS_H #define __FS_H #include <fs_common.h> #include <part.h> struct fs_statfs; struct udevice; enum { /* Maximum length of the filesystem name */ FS_MAX_NAME_LEN = 128, }; /** * struct fs_plat - Filesystem information * * For block-device-backed filesystems, @desc and @part identify the * underlying storage. Non-block filesystems (hostfs, rootfs) leave * @desc as NULL. * * @name: Name of the filesystem, or empty if not available * @desc: Block device descriptor, or NULL if not block-backed * @part_num: Partition number (valid only when @desc is non-NULL) * @part: Partition information (valid only when @desc is non-NULL) */ struct fs_plat { char name[FS_MAX_NAME_LEN]; struct blk_desc *desc; int part_num; struct disk_partition part; }; /** * struct fs_priv - Private information for the FS devices * * @mounted: true if mounted */ struct fs_priv { bool mounted; }; struct fs_ops { /** * mount() - Mount the filesystem * * @dev: Filesystem device * Return 0 if OK, -EISCONN if already mounted, other -ve on error */ int (*mount)(struct udevice *dev); /** * unmount() - Unmount the filesystem * * @dev: Filesystem device * Return 0 if OK, -ENOTCONN if not mounted, other -ve on error */ int (*unmount)(struct udevice *dev); /** * lookup_dir() - Look up a directory on a filesystem * * This should not set up the uclass-private data; this is done by * fs_lookup_dir() * * @dev: Filesystem device * @path: Path to look up, "" for the root * @dirp: Returns associated directory device, creating if necessary * Return 0 if OK, -ENOENT, other -ve on error */ int (*lookup_dir)(struct udevice *dev, const char *path, struct udevice **dirp); /** * rename() - Rename or move a file or directory * * @dev: Filesystem device * @old_path: Current path * @new_path: New path * Return 0 if OK, -ve on error */ int (*rename)(struct udevice *dev, const char *old_path, const char *new_path); /** * ln() - Create a symbolic link * * @dev: Filesystem device * @path: Path of symlink to create * @target: Target the symlink points to * Return 0 if OK, -ve on error */ int (*ln)(struct udevice *dev, const char *path, const char *target); /** * readlink() - Read the target of a symbolic link * * @dev: Filesystem device * @path: Path to the symbolic link * @buf: Buffer to receive the target path * @size: Size of buffer * Return: length of target string, or -ve on error */ int (*readlink)(struct udevice *dev, const char *path, char *buf, int size); /** * statfs() - Get filesystem statistics * * @dev: Filesystem device * @stats: Returns filesystem statistics * Return 0 if OK, -ve on error */ int (*statfs)(struct udevice *dev, struct fs_statfs *stats); /** * unlink() - Delete a file * * @dev: Filesystem device * @path: Path of the file to delete * Return 0 if OK, -ve on error */ int (*unlink)(struct udevice *dev, const char *path); /** * mkdir() - Create a directory * * @dev: Filesystem device * @path: Path of the directory to create * Return 0 if OK, -ve on error */ int (*mkdir)(struct udevice *dev, const char *path); }; /* Get access to a filesystem's operations */ #define fs_get_ops(dev) ((struct fs_ops *)(dev)->driver->ops) /** * fs_mount() - Mount the filesystem * * @dev: Filesystem device * Return 0 if OK, -EISCONN if already mounted, other -ve on error */ int fs_mount(struct udevice *dev); /** * fs_unmount() - Unmount the filesystem * * @dev: Filesystem device * Return 0 if OK, -ENOTCONN if not mounted, other -ve on error */ int fs_unmount(struct udevice *dev); /** * fs_lookup_dir() - Look up a directory on a filesystem * * If a new directory-device is created, its uclass data is set up also * * @dev: Filesystem device * @path: Path to look up, "" or "/" for the root * @dirp: Returns associated directory device, creating if necessary * Return 0 if OK, -ENOENT, other -ve on error */ int fs_lookup_dir(struct udevice *dev, const char *path, struct udevice **dirp); /** * fs_do_ln() - Create a symbolic link on a filesystem * * @dev: Filesystem device * @path: Path of symlink to create (within the filesystem) * @target: Target the symlink points to * Return: 0 if OK, -ENOSYS if not supported, other -ve on error */ int fs_do_ln(struct udevice *dev, const char *path, const char *target); /** * fs_do_rename() - Rename or move a file on a filesystem * * Both paths must be within the same filesystem. * * @dev: Filesystem device * @old_path: Current path (within the filesystem) * @new_path: New path (within the filesystem) * Return: 0 if OK, -ENOSYS if not supported, other -ve on error */ int fs_do_rename(struct udevice *dev, const char *old_path, const char *new_path); /** * fs_readlink() - Read a symbolic link target on a filesystem * * @dev: Filesystem device * @path: Path to the symbolic link (within the filesystem) * @buf: Buffer to receive the target path * @size: Size of buffer * Return: length of target, -ENOSYS if not supported, other -ve on error */ int fs_readlink(struct udevice *dev, const char *path, char *buf, int size); /** * fs_do_statfs() - Get filesystem statistics * * @dev: Filesystem device * @stats: Returns filesystem statistics * Return: 0 if OK, -ENOSYS if not supported, other -ve on error */ int fs_do_statfs(struct udevice *dev, struct fs_statfs *stats); /** * fs_do_unlink() - Delete a file on a filesystem * * @dev: Filesystem device * @path: Path of the file to delete (within the filesystem) * Return: 0 if OK, -ENOSYS if not supported, other -ve on error */ int fs_do_unlink(struct udevice *dev, const char *path); /** * fs_do_mkdir() - Create a directory on a filesystem * * @dev: Filesystem device * @path: Path of the directory to create (within the filesystem) * Return: 0 if OK, -ENOSYS if not supported, other -ve on error */ int fs_do_mkdir(struct udevice *dev, const char *path); /** * fs_split_path() - Get a list of subdirs in a filename * * For example, '/path/to/fred' returns an alist containing allocated strings * 'path' and 'to', with \*leafp pointing to the 'f' * * @fname: Filename to parse * @subdirp: Returns an allocating string containing the subdirs, or "/" if none * @leafp: Returns a pointer to the leaf filename, within @fname */ int fs_split_path(const char *fname, char **subdirp, const char **leafp); /** * fs_split_path_inplace() - Split a path into directory and leaf in place * * Modifies @fname by null-terminating at the last '/'. Sets @dirp to * point to the directory part and @leafp to the leaf. If there is no * '/', @dirp is set to "" and @leafp points to @fname unchanged. * * @fname: Path to split (modified in place when it contains '/') * @dirp: Returns pointer to the directory part * @leafp: Returns pointer to the leaf filename */ void fs_split_path_inplace(char *fname, const char **dirp, const char **leafp); #endif |