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