All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gao Xiang via Linux-erofs <linux-erofs@lists.ozlabs.org>
To: linux-erofs@lists.ozlabs.org
Subject: [WIP] [PATCH v3 12/12] erofs-utils: fuse: kill incomplate dcache
Date: Mon,  2 Nov 2020 23:59:38 +0800	[thread overview]
Message-ID: <20201102155938.2679-3-hsiangkao@aol.com> (raw)
In-Reply-To: <20201102155938.2679-1-hsiangkao@aol.com>

useless at all, use simplist bare disk lookup way for now
(also libfuse has an internal dcache, we can use it as well.
 plus no need to introduce dcache for unpack tool.)

(will fold into the original patch.)

Signed-off-by: Gao Xiang <hsiangkao@aol.com>
---
 fuse/Makefile.am |   2 +-
 fuse/dentry.c    | 130 ----------------------------------
 fuse/dentry.h    |  43 ------------
 fuse/main.c      |   5 --
 fuse/namei.c     | 179 +++++++++++++++++++++++------------------------
 fuse/namei.h     |   5 --
 6 files changed, 88 insertions(+), 276 deletions(-)
 delete mode 100644 fuse/dentry.c
 delete mode 100644 fuse/dentry.h

diff --git a/fuse/Makefile.am b/fuse/Makefile.am
index 5ff0b4d0e6ab..84e5f834d6a4 100644
--- a/fuse/Makefile.am
+++ b/fuse/Makefile.am
@@ -3,7 +3,7 @@
 
 AUTOMAKE_OPTIONS = foreign
 bin_PROGRAMS     = erofsfuse
-erofsfuse_SOURCES = main.c dentry.c namei.c read.c readir.c zmap.c
+erofsfuse_SOURCES = main.c namei.c read.c readir.c zmap.c
 erofsfuse_CFLAGS = -Wall -Werror \
                    -I$(top_srcdir)/include \
                    $(shell pkg-config fuse --cflags) \
diff --git a/fuse/dentry.c b/fuse/dentry.c
deleted file mode 100644
index 0f722294d530..000000000000
--- a/fuse/dentry.c
+++ /dev/null
@@ -1,130 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * erofs-utils/fuse/dentry.c
- *
- * Created by Li Guifu <blucerlee@gmail.com>
- */
-#include <stdlib.h>
-#include "dentry.h"
-#include "erofs/internal.h"
-#include "erofs/print.h"
-
-#define DCACHE_ENTRY_CALLOC()   calloc(1, sizeof(struct dcache_entry))
-#define DCACHE_ENTRY_LIFE       8
-
-struct dcache_entry root_entry;
-
-int dcache_init_root(uint32_t nid)
-{
-	if (root_entry.nid)
-		return -1;
-
-	/* Root entry doesn't need most of the fields. Namely, it only uses the
-	 * nid field and the subdirs pointer.
-	 */
-	erofs_info("Initializing root_entry dcache entry");
-	root_entry.nid = nid;
-	root_entry.subdirs = NULL;
-	root_entry.siblings = NULL;
-
-	return 0;
-}
-
-/* Inserts a node as a subdirs of a given parent. The parent is updated to
- * point the newly inserted subdirs as the first subdirs. We return the new
- * entry so that further entries can be inserted.
- *
- *      [0]                  [0]
- *       /        ==>          \
- *      /         ==>           \
- * .->[1]->[2]-.       .->[1]->[3]->[2]-.
- * `-----------麓       `----------------麓
- */
-struct dcache_entry *dcache_insert(struct dcache_entry *parent,
-				   const char *name, int namelen, uint32_t nid)
-{
-	struct dcache_entry *new_entry;
-
-	erofs_dbg("Inserting %s,%d to dcache", name, namelen);
-
-	/* TODO: Deal with names that exceed the allocated size */
-	if (namelen + 1 > DCACHE_ENTRY_NAME_LEN)
-		return NULL;
-
-	if (parent == NULL)
-		parent = &root_entry;
-
-	new_entry = DCACHE_ENTRY_CALLOC();
-	if (!new_entry)
-		return NULL;
-
-	strncpy(new_entry->name, name, namelen);
-	new_entry->name[namelen] = 0;
-	new_entry->nid = nid;
-
-	if (!parent->subdirs) {
-		new_entry->siblings = new_entry;
-		parent->subdirs = new_entry;
-	} else {
-		new_entry->siblings = parent->subdirs->siblings;
-		parent->subdirs->siblings = new_entry;
-		parent->subdirs = new_entry;
-	}
-
-	return new_entry;
-}
-
-/* Lookup a cache entry for a given file name.  Return value is a struct pointer
- * that can be used to both obtain the nid number and insert further child
- * entries.
- * TODO: Prune entries by using the LRU counter
- */
-struct dcache_entry *dcache_lookup(struct dcache_entry *parent,
-				   const char *name, int namelen)
-{
-	struct dcache_entry *iter;
-
-	if (parent == NULL)
-		parent = &root_entry;
-
-	if (!parent->subdirs)
-		return NULL;
-
-	/* Iterate the list of siblings to see if there is any match */
-	iter = parent->subdirs;
-
-	do {
-		if (strncmp(iter->name, name, namelen) == 0 &&
-		    iter->name[namelen] == 0) {
-			parent->subdirs = iter;
-
-			return iter;
-		}
-
-		iter = iter->siblings;
-	} while (iter != parent->subdirs);
-
-	return NULL;
-}
-
-struct dcache_entry *dcache_try_insert(struct dcache_entry *parent,
-				   const char *name, int namelen, uint32_t nid)
-{
-	struct dcache_entry *d = dcache_lookup(parent, name, namelen);
-
-	if (d)
-		return d;
-
-	return dcache_insert(parent, name, namelen, nid);
-
-}
-erofs_nid_t dcache_get_nid(struct dcache_entry *entry)
-{
-	return entry ? entry->nid : root_entry.nid;
-}
-
-struct dcache_entry *dcache_root(void)
-{
-	return &root_entry;
-}
-
diff --git a/fuse/dentry.h b/fuse/dentry.h
deleted file mode 100644
index 12f4cf6bafd9..000000000000
--- a/fuse/dentry.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * erofs-utils/fuse/dentry.h
- *
- * Created by Li Guifu <blucerlee@gmail.com>
- */
-#ifndef _EROFS_DENTRY_H
-#define _EROFS_DENTRY_H
-
-#include <stdint.h>
-#include "erofs/internal.h"
-
-/* fixme: Deal with names that exceed the allocated size */
-#ifdef __64BITS
-#define DCACHE_ENTRY_NAME_LEN       EROFS_NAME_LEN
-#else
-#define DCACHE_ENTRY_NAME_LEN       EROFS_NAME_LEN
-#endif
-
-/* This struct declares a node of a k-tree.  Every node has a pointer to one of
- * the subdirs and a pointer (in a circular list fashion) to its siblings.
- */
-
-struct dcache_entry {
-	struct dcache_entry *subdirs;
-	struct dcache_entry *siblings;
-	uint32_t nid;
-	uint16_t lru_count;
-	uint8_t user_count;
-	char name[DCACHE_ENTRY_NAME_LEN];
-};
-
-struct dcache_entry *dcache_insert(struct dcache_entry *parent,
-				   const char *name, int namelen, uint32_t n);
-struct dcache_entry *dcache_lookup(struct dcache_entry *parent,
-				   const char *name, int namelen);
-struct dcache_entry *dcache_try_insert(struct dcache_entry *parent,
-				       const char *name, int namelen,
-				       uint32_t nid);
-
-erofs_nid_t dcache_get_nid(struct dcache_entry *entry);
-int dcache_init_root(uint32_t n);
-#endif
diff --git a/fuse/main.c b/fuse/main.c
index e423312d9e1a..563b2c378952 100644
--- a/fuse/main.c
+++ b/fuse/main.c
@@ -116,11 +116,6 @@ static void signal_handle_sigsegv(int signal)
 void *erofs_init(struct fuse_conn_info *info)
 {
 	erofs_info("Using FUSE protocol %d.%d", info->proto_major, info->proto_minor);
-
-	if (inode_init(sbi.root_nid) != 0) {
-		erofs_err("inode initialization failed");
-		abort();
-	}
 	return NULL;
 }
 
diff --git a/fuse/namei.c b/fuse/namei.c
index 4c428dbc59f6..5ee3f8d2a4b6 100644
--- a/fuse/namei.c
+++ b/fuse/namei.c
@@ -16,7 +16,6 @@
 #include "erofs/defs.h"
 #include "erofs/print.h"
 #include "erofs/io.h"
-#include "dentry.h"
 
 #define IS_PATH_SEPARATOR(__c)      ((__c) == '/')
 #define MINORBITS	20
@@ -99,124 +98,127 @@ int erofs_iget_by_nid(erofs_nid_t nid, struct erofs_vnode *vi)
 	return 0;
 }
 
-/* dirent + name string */
-struct dcache_entry *list_name(const char *buf, struct dcache_entry *parent,
-				const char *name, unsigned int len,
-				uint32_t dirend)
+
+struct erofs_dirent *find_target_dirent(erofs_nid_t pnid,
+					void *dentry_blk,
+					const char *name, unsigned int len,
+					unsigned int nameoff,
+					unsigned int maxsize)
 {
-	struct dcache_entry *entry = NULL;
-	struct erofs_dirent *ds, *de;
-
-	ds = (struct erofs_dirent *)buf;
-	de = (struct erofs_dirent *)(buf + le16_to_cpu(ds->nameoff));
-
-	while (ds < de) {
-		erofs_nid_t nid = le64_to_cpu(ds->nid);
-		uint16_t nameoff = le16_to_cpu(ds->nameoff);
-		char *d_name = (char *)(buf + nameoff);
-		uint16_t name_len = (ds + 1 >= de) ?
-			(uint16_t)strnlen(d_name, dirend - nameoff) :
-			le16_to_cpu(ds[1].nameoff) - nameoff;
-
-		#if defined(EROFS_DEBUG_ENTRY)
-		{
-			char debug[EROFS_BLKSIZ];
-
-			memcpy(debug, d_name, name_len);
-			debug[name_len] = '\0';
-			erofs_info("list entry: %s nid=%u", debug, nid);
+	struct erofs_dirent *de = dentry_blk;
+	const struct erofs_dirent *end = dentry_blk + nameoff;
+
+	while (de < end) {
+		const char *de_name;
+		unsigned int de_namelen;
+
+		nameoff = le16_to_cpu(de->nameoff);
+		de_name = (char *)dentry_blk + nameoff;
+
+		/* the last dirent in the block? */
+		if (de + 1 >= end)
+			de_namelen = strnlen(de_name, maxsize - nameoff);
+		else
+			de_namelen = le16_to_cpu(de[1].nameoff) - nameoff;
+
+		/* a corrupted entry is found */
+		if (nameoff + de_namelen > maxsize ||
+		    de_namelen > EROFS_NAME_LEN) {
+			erofs_err("bogus dirent @ nid %llu", pnid | 0ULL);
+			DBG_BUGON(1);
+			return ERR_PTR(-EFSCORRUPTED);
 		}
-		#endif
-
-		entry = dcache_try_insert(parent, d_name, name_len, nid);
-		if (len == name_len && !memcmp(name, d_name, name_len))
-			return entry;
 
-		entry = NULL;
-		++ds;
+		if (len == de_namelen && !memcmp(de_name, name, de_namelen))
+			return de;
+		++de;
 	}
-
-	return entry;
+	return NULL;
 }
 
-struct dcache_entry *disk_lookup(struct dcache_entry *parent, const char *name,
-		unsigned int name_len)
+int erofs_namei(erofs_nid_t *nid,
+		const char *name, unsigned int len)
 {
 	int ret;
 	char buf[EROFS_BLKSIZ];
-	struct dcache_entry *entry = NULL;
 	struct erofs_vnode v;
-	uint32_t nr_cnt, dir_nr, dirsize, blkno;
 
-	ret = erofs_iget_by_nid(parent->nid, &v);
+	ret = erofs_iget_by_nid(*nid, &v);
 	if (ret)
-		return NULL;
-
-	/* to check whether dirent is in the inline dirs */
-	blkno = v.raw_blkaddr;
-	dirsize = v.i_size;
-	dir_nr = erofs_blknr(dirsize);
-
-	nr_cnt = 0;
-	while (nr_cnt < dir_nr) {
-		ret = blk_read(buf, blkno + nr_cnt, 1);
-		if (ret < 0)
-			return NULL;
-
-		entry = list_name(buf, parent, name, name_len, EROFS_BLKSIZ);
-		if (entry)
-			goto next;
-
-		++nr_cnt;
-	}
-
-	if (v.datalayout == EROFS_INODE_FLAT_INLINE) {
-		uint32_t dir_off = erofs_blkoff(dirsize);
-		off_t dir_addr = iloc(dcache_get_nid(parent)) +
-			v.inode_isize + v.xattr_isize;
-
-		memset(buf, 0, sizeof(buf));
-		ret = dev_read(buf, dir_addr, dir_off);
-		if (ret < 0)
-			return NULL;
+		return ret;
 
-		entry = list_name(buf, parent, name, name_len, dir_off);
+	{
+		unsigned int offset = 0;
+
+		struct erofs_inode tmp = {
+			.u = {
+				.i_blkaddr = v.raw_blkaddr,
+			},
+			.nid = v.nid,
+			.i_size = v.i_size,
+			.datalayout = v.datalayout,
+			.inode_isize = v.inode_isize,
+			.xattr_isize = v.xattr_isize,
+		};
+
+		while (offset < v.i_size) {
+			int maxsize = min(v.i_size - offset, EROFS_BLKSIZ);
+			struct erofs_dirent *de = (void *)buf;
+			unsigned int nameoff;
+
+			ret = erofs_read_raw_data(&tmp, buf, offset, maxsize);
+			if (ret)
+				return ret;
+
+			nameoff = le16_to_cpu(de->nameoff);
+
+			if (nameoff < sizeof(struct erofs_dirent) ||
+			    nameoff >= PAGE_SIZE) {
+				erofs_err("invalid de[0].nameoff %u @ nid %llu",
+					  nameoff, *nid | 0ULL);
+				return -EFSCORRUPTED;
+			}
+
+			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);
+				return 0;
+			}
+			offset += maxsize;
+		}
 	}
-next:
-	return entry;
+	return -ENOENT;
 }
 
 extern struct dcache_entry root_entry;
 int walk_path(const char *_path, erofs_nid_t *out_nid)
 {
-	struct dcache_entry *next, *ret;
+	int ret;
+	erofs_nid_t nid = sbi.root_nid;
 	const char *path = _path;
 
-	ret = next = &root_entry;
 	for (;;) {
 		uint8_t path_len;
 
 		path = skip_trailing_backslash(path);
 		path_len = get_path_token_len(path);
-		ret = next;
 		if (path_len == 0)
 			break;
 
-		next = dcache_lookup(ret, path, path_len);
-		if (!next) {
-			next = disk_lookup(ret, path, path_len);
-			if (!next)
-				return -ENOENT;
-		}
+		ret = erofs_namei(&nid, path, path_len);
+		if (ret)
+			return ret;
 
 		path += path_len;
 	}
 
-	if (!ret)
-		return -ENOENT;
-	erofs_dbg("find path = %s nid=%u", _path, ret->nid);
+	erofs_dbg("find path = %s nid=%llu", _path, nid | 0ULL);
 
-	*out_nid = ret->nid;
+	*out_nid = nid;
 	return 0;
 
 }
@@ -233,10 +235,3 @@ int erofs_iget_by_path(const char *path, struct erofs_vnode *v)
 	return erofs_iget_by_nid(nid, v);
 }
 
-int inode_init(erofs_nid_t root)
-{
-	dcache_init_root(root);
-
-	return 0;
-}
-
diff --git a/fuse/namei.h b/fuse/namei.h
index 1803a673daaf..2625ec58d434 100644
--- a/fuse/namei.h
+++ b/fuse/namei.h
@@ -10,13 +10,8 @@
 #include "erofs/internal.h"
 #include "erofs_fs.h"
 
-int inode_init(erofs_nid_t root);
-struct dcache_entry *get_cached_dentry(struct dcache_entry **parent,
-				       const char **path);
 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);
-struct dcache_entry *disk_lookup(struct dcache_entry *parent, const char *name,
-		unsigned int name_len);
 int walk_path(const char *path, erofs_nid_t *out_nid);
 
 #endif
-- 
2.24.0


      parent reply	other threads:[~2020-11-02 16:00 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20201102155558.1995-1-hsiangkao.ref@aol.com>
2020-11-02 15:55 ` [WIP] [PATCH v3 00/12] erofs-utils: introduce fuse implementation Gao Xiang via Linux-erofs
2020-11-02 15:55   ` [WIP] [PATCH v3 01/12] " Gao Xiang via Linux-erofs
2020-11-02 15:55   ` [WIP] [PATCH v3 02/12] erofs-utils: fuse: add special file support Gao Xiang via Linux-erofs
2020-11-02 15:55   ` [WIP] [PATCH v3 03/12] erofs-utils: fuse: add compressed " Gao Xiang via Linux-erofs
2020-11-02 15:55   ` [WIP] [PATCH v3 04/12] erofs-utils: fuse: refactor raw data logic Gao Xiang via Linux-erofs
2020-11-02 15:55   ` [WIP] [PATCH v3 05/12] erofs-utils: fuse: kill sbk Gao Xiang via Linux-erofs
2020-11-02 15:55   ` [WIP] [PATCH v3 06/12] erofs-utils: fuse: kill nid2addr, addr2nid Gao Xiang via Linux-erofs
2020-11-02 15:55   ` [WIP] [PATCH v3 07/12] erofs-utils: fuse: kill erofs_get_root_nid() Gao Xiang via Linux-erofs
2020-11-02 15:55   ` [WIP] [PATCH v3 08/12] erofs-utils: fuse: move erofs_init() to main.c Gao Xiang via Linux-erofs
2020-11-02 15:55   ` [WIP] [PATCH v3 09/12] erofs-utils: fuse: move superblock logic into lib/ Gao Xiang via Linux-erofs
2020-11-02 15:59     ` [WIP] [PATCH v3 10/12] erofs-utils: fuse: kill getattr.c Gao Xiang via Linux-erofs
2020-11-02 15:59       ` [WIP] [PATCH v3 11/12] erofs-utils: fuse: kill open.c Gao Xiang via Linux-erofs
2020-11-02 15:59       ` Gao Xiang via Linux-erofs [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201102155938.2679-3-hsiangkao@aol.com \
    --to=linux-erofs@lists.ozlabs.org \
    --cc=hsiangkao@aol.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.