[Concept,05/34] vfs: Tidy fs_split_path() allocation

Message ID 20260403140523.1998228-6-sjg@u-boot.org
State New
Headers
Series Add a virtual filesystem (VFS) layer to U-Boot |

Commit Message

Simon Glass April 3, 2026, 2:04 p.m. UTC
  From: Simon Glass <sjg@chromium.org>

fs_split_path() duplicates the entire filename then truncates it to
get the directory part. Instead, find the last slash first and only
allocate the directory portion.

When there is no slash at all, return an empty string rather than "/"
since a bare filename has no directory component.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 fs/fs-uclass.c | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)
  

Patch

diff --git a/fs/fs-uclass.c b/fs/fs-uclass.c
index a335391bd74..6bb50bb2543 100644
--- a/fs/fs-uclass.c
+++ b/fs/fs-uclass.c
@@ -12,27 +12,34 @@ 
 #include <dir.h>
 #include <dm.h>
 #include <fs.h>
+#include <malloc.h>
 #include <dm/device-internal.h>
 
 int fs_split_path(const char *fname, char **subdirp, const char **leafp)
 {
-	char *subdir, *p;
+	const char *last_slash;
+	char *subdir;
 
 	if (!*fname)
 		return log_msg_ret("fsp", -EINVAL);
 
-	/* allocate space for the whole filename, for simplicity */
-	subdir = strdup(fname);
-	if (!subdir)
-		return log_msg_ret("fsp", -ENOMEM);
-
-	p = strrchr(subdir, '/');
-	if (p) {
-		*leafp = p + 1;
-		*p = '\0';
+	last_slash = strrchr(fname, '/');
+	if (last_slash) {
+		int dir_len = last_slash - fname;
+
+		if (!dir_len)
+			dir_len = 1;	/* root "/" */
+		subdir = malloc(dir_len + 1);
+		if (!subdir)
+			return log_msg_ret("fsp", -ENOMEM);
+		memcpy(subdir, fname, dir_len);
+		subdir[dir_len] = '\0';
+		*leafp = last_slash + 1;
 	} else {
+		subdir = strdup("");
+		if (!subdir)
+			return log_msg_ret("fsp", -ENOMEM);
 		*leafp = fname;
-		strcpy(subdir, "/");
 	}
 	*subdirp = subdir;