From: Simon Glass <sjg@chromium.org>
Path resolution is the core operation underlying every file access:
ls, read, write, mkdir, unlink, rename and symlink following all go
through ext4l_resolve_path_internal(). Add a struct ext4l_state
parameter so it uses per-mount state instead of the global, replacing
direct references to efs.mounted, efs.sb and efs.sb->s_root with the
state pointer.
The public ext4l_resolve_path() wrapper still passes the global for
now; it will be converted when the remaining public functions are
updated.
Signed-off-by: Simon Glass <sjg@chromium.org>
---
fs/ext4l/fs.c | 16 +++++++++++++---
fs/ext4l/interface.c | 20 +++++++++++---------
2 files changed, 24 insertions(+), 12 deletions(-)
@@ -21,6 +21,15 @@
#include <vfs.h>
#include <dm/device-internal.h>
+/**
+ * struct ext4l_fs_priv - Private data for ext4l UCLASS_FS devices
+ *
+ * @state: Per-mount state
+ */
+struct ext4l_fs_priv {
+ struct ext4l_state state;
+};
+
/**
* struct ext4l_dir_priv - Private info for ext4l directory devices
*
@@ -119,9 +128,10 @@ static const struct fs_ops ext4l_vfs_ops = {
};
U_BOOT_DRIVER(ext4_fs) = {
- .name = "ext4_fs",
- .id = UCLASS_FS,
- .ops = &ext4l_vfs_ops,
+ .name = "ext4_fs",
+ .id = UCLASS_FS,
+ .ops = &ext4l_vfs_ops,
+ .priv_auto = sizeof(struct ext4l_fs_priv),
};
/* ext4l directory driver */
@@ -500,13 +500,15 @@ static int ext4l_read_symlink(struct inode *inode, char *target, size_t max_len)
/**
* ext4l_resolve_path_internal() - Resolve path with symlink following
*
+ * @state: Per-mount state
* @path: Path to resolve
* @inodep: Output inode pointer
* @depth: Current recursion depth (for symlink loop detection)
* Return: 0 on success, negative on error
*/
-static int ext4l_resolve_path_internal(const char *path, struct inode **inodep,
- int depth)
+static int ext4l_resolve_path_internal(struct ext4l_state *state,
+ const char *path,
+ struct inode **inodep, int depth)
{
struct inode *dir;
struct dentry *dentry, *result;
@@ -517,12 +519,12 @@ static int ext4l_resolve_path_internal(const char *path, struct inode **inodep,
if (depth > 8)
return -ELOOP;
- if (!efs.mounted) {
+ if (!state->mounted) {
ext4_debug("ext4l_resolve_path: filesystem not mounted\n");
return -ENODEV;
}
- dir = efs.sb->s_root->d_inode;
+ dir = state->sb->s_root->d_inode;
if (!path || !*path || (strcmp(path, "/") == 0)) {
*inodep = dir;
@@ -564,7 +566,7 @@ static int ext4l_resolve_path_internal(const char *path, struct inode **inodep,
}
dentry->d_name.name = "..";
dentry->d_name.len = 2;
- dentry->d_sb = efs.sb;
+ dentry->d_sb = state->sb;
dentry->d_parent = NULL;
result = ext4_lookup(dir, dentry, 0);
@@ -599,7 +601,7 @@ static int ext4l_resolve_path_internal(const char *path, struct inode **inodep,
dentry->d_name.name = component;
dentry->d_name.len = strlen(component);
- dentry->d_sb = efs.sb;
+ dentry->d_sb = state->sb;
dentry->d_parent = NULL;
result = ext4_lookup(dir, dentry, 0);
@@ -674,8 +676,8 @@ static int ext4l_resolve_path_internal(const char *path, struct inode **inodep,
free(path_copy);
/* Recursively resolve the new path */
- ret = ext4l_resolve_path_internal(new_path, inodep,
- depth + 1);
+ ret = ext4l_resolve_path_internal(state, new_path,
+ inodep, depth + 1);
free(new_path);
return ret;
}
@@ -697,7 +699,7 @@ static int ext4l_resolve_path_internal(const char *path, struct inode **inodep,
*/
static int ext4l_resolve_path(const char *path, struct inode **inodep)
{
- return ext4l_resolve_path_internal(path, inodep, 0);
+ return ext4l_resolve_path_internal(&efs, path, inodep, 0);
}
/**