Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 62c8af65 authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim
Browse files

f2fs: support fast lookup in extent cache



This patch adds a fast lookup path for rb-tree extent cache.

In this patch we add a recently accessed extent node pointer 'cached_en' in
extent tree. In lookup path of extent cache, we will firstly lookup the last
accessed extent node which cached_en points, if we do not hit in this node,
we will try to lookup extent node in rb-tree.

By this way we can avoid unnecessary slow lookup in rb-tree sometimes.

Note that, side-effect of this patch is that we will increase memory cost,
because we will store a pointer variable in each struct extent tree
additionally.

Signed-off-by: default avatarChao Yu <chao2.yu@samsung.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 1ec4610c
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -395,6 +395,9 @@ static void __detach_extent_node(struct f2fs_sb_info *sbi,
	rb_erase(&en->rb_node, &et->root);
	et->count--;
	atomic_dec(&sbi->total_ext_node);

	if (et->cached_en == en)
		et->cached_en = NULL;
}

static struct extent_node *__lookup_extent_tree(struct extent_tree *et,
@@ -403,16 +406,25 @@ static struct extent_node *__lookup_extent_tree(struct extent_tree *et,
	struct rb_node *node = et->root.rb_node;
	struct extent_node *en;

	if (et->cached_en) {
		struct extent_info *cei = &et->cached_en->ei;

		if (cei->fofs <= fofs && cei->fofs + cei->len > fofs)
			return et->cached_en;
	}

	while (node) {
		en = rb_entry(node, struct extent_node, rb_node);

		if (fofs < en->ei.fofs)
		if (fofs < en->ei.fofs) {
			node = node->rb_left;
		else if (fofs >= en->ei.fofs + en->ei.len)
		} else if (fofs >= en->ei.fofs + en->ei.len) {
			node = node->rb_right;
		else
		} else {
			et->cached_en = en;
			return en;
		}
	}
	return NULL;
}

@@ -587,6 +599,7 @@ static void f2fs_update_extent_tree(struct inode *inode, pgoff_t fofs,
		memset(et, 0, sizeof(struct extent_tree));
		et->ino = ino;
		et->root = RB_ROOT;
		et->cached_en = NULL;
		rwlock_init(&et->lock);
		atomic_set(&et->refcount, 0);
		et->count = 0;
+1 −0
Original line number Diff line number Diff line
@@ -298,6 +298,7 @@ struct extent_node {
struct extent_tree {
	nid_t ino;			/* inode number */
	struct rb_root root;		/* root of extent info rb-tree */
	struct extent_node *cached_en;	/* recently accessed extent node */
	rwlock_t lock;			/* protect extent info rb-tree */
	atomic_t refcount;		/* reference count of rb-tree */
	unsigned int count;		/* # of extent node in rb-tree*/