From: Simon Glass <sjg@chromium.org>
Add vfs_open_file() which resolves an absolute VFS path to a
UCLASS_FILE device in one call, replacing the repeated sequence of
vfs_find_mount / fs_split_path / fs_lookup_dir / dir_open_file.
Signed-off-by: Simon Glass <sjg@chromium.org>
---
fs/vfs.c | 35 +++++++++++++++++++++++++++++++++++
include/vfs.h | 16 ++++++++++++++++
2 files changed, 51 insertions(+)
@@ -331,6 +331,41 @@ void vfs_print_mounts(void)
}
}
+int vfs_open_file(const char *path, enum dir_open_flags_t oflags,
+ struct udevice **filp)
+{
+ struct udevice *vfs, *mnt, *dir;
+ const char *subpath, *leaf;
+ struct vfsmount *mnt_priv;
+ char *dirpath;
+ int ret;
+
+ vfs = vfs_root();
+ if (!vfs)
+ return log_msg_ret("voi", -ENXIO);
+
+ ret = vfs_find_mount(vfs, path, &mnt, &subpath);
+ if (ret)
+ return log_msg_ret("vom", ret);
+
+ mnt_priv = dev_get_uclass_priv(mnt);
+
+ ret = fs_split_path(subpath, &dirpath, &leaf);
+ if (ret)
+ return log_msg_ret("vos", ret);
+
+ ret = fs_lookup_dir(mnt_priv->target, dirpath, &dir);
+ free(dirpath);
+ if (ret)
+ return log_msg_ret("vod", ret);
+
+ ret = dir_open_file(dir, leaf, oflags, filp);
+ if (ret)
+ return log_msg_ret("vof", ret);
+
+ return 0;
+}
+
int vfs_ls(const char *path)
{
struct udevice *vfs, *mnt, *dir = NULL;
@@ -11,6 +11,8 @@
#ifndef __VFS_H
#define __VFS_H
+#include <dir.h>
+
struct udevice;
/**
@@ -136,4 +138,18 @@ void vfs_print_mounts(void);
*/
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);
+
#endif