Signed-off-by: Gao Xiang <hsiang...@aol.com>
---
 fuse/namei.c  | 82 +++++++++++++++++++++------------------------------
 fuse/namei.h  |  2 --
 fuse/read.c   | 16 ++--------
 fuse/readir.c | 10 ++-----
 4 files changed, 39 insertions(+), 71 deletions(-)

diff --git a/fuse/namei.c b/fuse/namei.c
index 5ee3f8d2a4b6..37cf549cd2a6 100644
--- a/fuse/namei.c
+++ b/fuse/namei.c
@@ -17,27 +17,6 @@
 #include "erofs/print.h"
 #include "erofs/io.h"
 
-#define IS_PATH_SEPARATOR(__c)      ((__c) == '/')
-#define MINORBITS      20
-#define MINORMASK      ((1U << MINORBITS) - 1)
-#define DT_UNKNOWN     0
-
-static const char *skip_trailing_backslash(const char *path)
-{
-       while (IS_PATH_SEPARATOR(*path))
-               path++;
-       return path;
-}
-
-static uint8_t get_path_token_len(const char *path)
-{
-       uint8_t len = 0;
-
-       while (path[len] != '/' && path[len])
-               len++;
-       return len;
-}
-
 static inline dev_t new_decode_dev(u32 dev)
 {
        unsigned major = (dev & 0xfff00) >> 8;
@@ -45,7 +24,7 @@ static inline dev_t new_decode_dev(u32 dev)
        return makedev(major, minor);
 }
 
-int erofs_iget_by_nid(erofs_nid_t nid, struct erofs_vnode *vi)
+static int erofs_iget_by_nid(erofs_nid_t nid, struct erofs_vnode *vi)
 {
        int ret, ifmt;
        char buf[EROFS_BLKSIZ];
@@ -136,14 +115,20 @@ struct erofs_dirent *find_target_dirent(erofs_nid_t pnid,
        return NULL;
 }
 
-int erofs_namei(erofs_nid_t *nid,
+struct nameidata {
+       erofs_nid_t     nid;
+       unsigned int    ftype;
+};
+
+int erofs_namei(struct nameidata *nd,
                const char *name, unsigned int len)
 {
+       erofs_nid_t nid = nd->nid;
        int ret;
        char buf[EROFS_BLKSIZ];
        struct erofs_vnode v;
 
-       ret = erofs_iget_by_nid(*nid, &v);
+       ret = erofs_iget_by_nid(nid, &v);
        if (ret)
                return ret;
 
@@ -154,7 +139,7 @@ int erofs_namei(erofs_nid_t *nid,
                        .u = {
                                .i_blkaddr = v.raw_blkaddr,
                        },
-                       .nid = v.nid,
+                       .nid = nid,
                        .i_size = v.i_size,
                        .datalayout = v.datalayout,
                        .inode_isize = v.inode_isize,
@@ -175,17 +160,17 @@ int erofs_namei(erofs_nid_t *nid,
                        if (nameoff < sizeof(struct erofs_dirent) ||
                            nameoff >= PAGE_SIZE) {
                                erofs_err("invalid de[0].nameoff %u @ nid %llu",
-                                         nameoff, *nid | 0ULL);
+                                         nameoff, nid | 0ULL);
                                return -EFSCORRUPTED;
                        }
 
-                       de = find_target_dirent(*nid, buf, name, len,
+                       de = find_target_dirent(nid, buf, name, len,
                                                nameoff, maxsize);
                        if (IS_ERR(de))
                                return PTR_ERR(de);
 
                        if (de) {
-                               *nid = le64_to_cpu(de->nid);
+                               nd->nid = le64_to_cpu(de->nid);
                                return 0;
                        }
                        offset += maxsize;
@@ -194,44 +179,43 @@ int erofs_namei(erofs_nid_t *nid,
        return -ENOENT;
 }
 
-extern struct dcache_entry root_entry;
-int walk_path(const char *_path, erofs_nid_t *out_nid)
+static int link_path_walk(const char *name, struct nameidata *nd)
 {
-       int ret;
-       erofs_nid_t nid = sbi.root_nid;
-       const char *path = _path;
+       nd->nid = sbi.root_nid;
+
+       while (*name == '/')
+               name++;
 
-       for (;;) {
-               uint8_t path_len;
+       /* At this point we know we have a real path component. */
+       while (*name != '\0') {
+               const char *p = name;
+               int ret;
 
-               path = skip_trailing_backslash(path);
-               path_len = get_path_token_len(path);
-               if (path_len == 0)
-                       break;
+               do {
+                       ++p;
+               } while (*p != '\0' && *p != '/');
 
-               ret = erofs_namei(&nid, path, path_len);
+               DBG_BUGON(p <= name);
+               ret = erofs_namei(nd, name, p - name);
                if (ret)
                        return ret;
 
-               path += path_len;
+               name = p;
+               /* Skip until no more slashes. */
+               for (name = p; *name == '/'; ++name);
        }
-
-       erofs_dbg("find path = %s nid=%llu", _path, nid | 0ULL);
-
-       *out_nid = nid;
        return 0;
-
 }
 
 int erofs_iget_by_path(const char *path, struct erofs_vnode *v)
 {
        int ret;
-       erofs_nid_t nid;
+       struct nameidata nd;
 
-       ret = walk_path(path, &nid);
+       ret = link_path_walk(path, &nd);
        if (ret)
                return ret;
 
-       return erofs_iget_by_nid(nid, v);
+       return erofs_iget_by_nid(nd.nid, v);
 }
 
diff --git a/fuse/namei.h b/fuse/namei.h
index 2625ec58d434..bd5adfda2969 100644
--- a/fuse/namei.h
+++ b/fuse/namei.h
@@ -11,7 +11,5 @@
 #include "erofs_fs.h"
 
 int erofs_iget_by_path(const char *path, struct erofs_vnode *v);
-int erofs_iget_by_nid(erofs_nid_t nid, struct erofs_vnode *v);
-int walk_path(const char *path, erofs_nid_t *out_nid);
 
 #endif
diff --git a/fuse/read.c b/fuse/read.c
index 10a26d84c37c..aa5221a60d4e 100644
--- a/fuse/read.c
+++ b/fuse/read.c
@@ -116,21 +116,16 @@ int erofs_read(const char *path, char *buffer, size_t 
size, off_t offset,
               struct fuse_file_info *fi)
 {
        int ret;
-       erofs_nid_t nid;
        struct erofs_vnode v;
 
        UNUSED(fi);
        erofs_info("path:%s size=%zd offset=%llu", path, size, (long 
long)offset);
 
-       ret = walk_path(path, &nid);
+       ret = erofs_iget_by_path(path, &v);
        if (ret)
                return ret;
 
-       ret = erofs_iget_by_nid(nid, &v);
-       if (ret)
-               return ret;
-
-       erofs_info("path:%s nid=%llu mode=%u", path, (unsigned long long)nid, 
v.datalayout);
+       erofs_info("path:%s nid=%llu mode=%u", path, v.nid | 0ULL, 
v.datalayout);
        switch (v.datalayout) {
        case EROFS_INODE_FLAT_PLAIN:
        case EROFS_INODE_FLAT_INLINE:
@@ -148,15 +143,10 @@ int erofs_read(const char *path, char *buffer, size_t 
size, off_t offset,
 int erofs_readlink(const char *path, char *buffer, size_t size)
 {
        int ret;
-       erofs_nid_t nid;
        size_t lnksz;
        struct erofs_vnode v;
 
-       ret = walk_path(path, &nid);
-       if (ret)
-               return ret;
-
-       ret = erofs_iget_by_nid(nid, &v);
+       ret = erofs_iget_by_path(path, &v);
        if (ret)
                return ret;
 
diff --git a/fuse/readir.c b/fuse/readir.c
index 5281c8b80e59..1d28016a8900 100644
--- a/fuse/readir.c
+++ b/fuse/readir.c
@@ -66,7 +66,6 @@ int erofs_readdir(const char *path, void *buf, 
fuse_fill_dir_t filler,
                  off_t offset, struct fuse_file_info *fi)
 {
        int ret;
-       erofs_nid_t nid;
        struct erofs_vnode v;
        char dirsbuf[EROFS_BLKSIZ];
        uint32_t dir_nr, dir_off, nr_cnt;
@@ -74,14 +73,11 @@ int erofs_readdir(const char *path, void *buf, 
fuse_fill_dir_t filler,
        erofs_dbg("readdir:%s offset=%llu", path, (long long)offset);
        UNUSED(fi);
 
-       ret = walk_path(path, &nid);
+       ret = erofs_iget_by_path(path, &v);
        if (ret)
                return ret;
 
-       erofs_dbg("path=%s nid = %llu", path, (unsigned long long)nid);
-       ret = erofs_iget_by_nid(nid, &v);
-       if (ret)
-               return ret;
+       erofs_dbg("path=%s nid = %llu", path, v.nid | 0ULL);
 
        if (!S_ISDIR(v.i_mode))
                return -ENOTDIR;
@@ -107,7 +103,7 @@ int erofs_readdir(const char *path, void *buf, 
fuse_fill_dir_t filler,
        if (v.datalayout == EROFS_INODE_FLAT_INLINE) {
                off_t addr;
 
-               addr = iloc(nid) + v.inode_isize + v.xattr_isize;
+               addr = iloc(v.nid) + v.inode_isize + v.xattr_isize;
 
                memset(dirsbuf, 0, sizeof(dirsbuf));
                ret = dev_read(dirsbuf, addr, dir_off);
-- 
2.24.0

Reply via email to