[PATCH] erofs-utils: lib: add support for symlink file in erofs_ilookup()

Hongzhen Luo hongzhen at linux.alibaba.com
Sun Aug 11 18:09:57 AEST 2024


When the `path` contains symbolic links, erofs_ilookup() does not
function properly. This adds support for symlink files.

Signed-off-by: Hongzhen Luo <hongzhen at linux.alibaba.com>
---
 lib/namei.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/lib/namei.c b/lib/namei.c
index 6f35ee6..dce2991 100644
--- a/lib/namei.c
+++ b/lib/namei.c
@@ -195,6 +195,22 @@ struct nameidata {
 	unsigned int	ftype;
 };
 
+static int link_path_walk(const char *name, struct nameidata *nd);
+
+static int step_into_link(struct nameidata *nd, struct erofs_inode *vi)
+{
+	char buf[EROFS_MAX_BLOCK_SIZE];
+	int err;
+
+	if (vi->i_size > EROFS_MAX_BLOCK_SIZE)
+		return -EINVAL;
+	memset(buf, 0, sizeof(buf));
+	err = erofs_pread(vi, buf, vi->i_size, 0);
+	if (err)
+		return err;
+	return link_path_walk(buf, nd);
+}
+
 int erofs_namei(struct nameidata *nd, const char *name, unsigned int len)
 {
 	erofs_nid_t nid = nd->nid;
@@ -233,6 +249,11 @@ int erofs_namei(struct nameidata *nd, const char *name, unsigned int len)
 			return PTR_ERR(de);
 
 		if (de) {
+			vi.nid = de->nid;
+			ret = erofs_read_inode_from_disk(&vi);
+			if (S_ISLNK(vi.i_mode)) {
+				return step_into_link(nd, &vi);
+			}
 			nd->nid = le64_to_cpu(de->nid);
 			return 0;
 		}
@@ -243,7 +264,8 @@ int erofs_namei(struct nameidata *nd, const char *name, unsigned int len)
 
 static int link_path_walk(const char *name, struct nameidata *nd)
 {
-	nd->nid = nd->sbi->root_nid;
+	if (*name == '/')
+		nd->nid = nd->sbi->root_nid;
 
 	while (*name == '/')
 		name++;
@@ -274,6 +296,7 @@ int erofs_ilookup(const char *path, struct erofs_inode *vi)
 	int ret;
 	struct nameidata nd = { .sbi = vi->sbi };
 
+	nd.nid = nd.sbi->root_nid;
 	ret = link_path_walk(path, &nd);
 	if (ret)
 		return ret;
-- 
2.43.5



More information about the Linux-erofs mailing list