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

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
...@@ -395,6 +395,9 @@ static void __detach_extent_node(struct f2fs_sb_info *sbi, ...@@ -395,6 +395,9 @@ static void __detach_extent_node(struct f2fs_sb_info *sbi,
rb_erase(&en->rb_node, &et->root); rb_erase(&en->rb_node, &et->root);
et->count--; et->count--;
atomic_dec(&sbi->total_ext_node); 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, static struct extent_node *__lookup_extent_tree(struct extent_tree *et,
...@@ -403,15 +406,24 @@ static struct extent_node *__lookup_extent_tree(struct extent_tree *et, ...@@ -403,15 +406,24 @@ static struct extent_node *__lookup_extent_tree(struct extent_tree *et,
struct rb_node *node = et->root.rb_node; struct rb_node *node = et->root.rb_node;
struct extent_node *en; 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) { while (node) {
en = rb_entry(node, struct extent_node, rb_node); en = rb_entry(node, struct extent_node, rb_node);
if (fofs < en->ei.fofs) if (fofs < en->ei.fofs) {
node = node->rb_left; 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; node = node->rb_right;
else } else {
et->cached_en = en;
return en; return en;
}
} }
return NULL; return NULL;
} }
...@@ -587,6 +599,7 @@ static void f2fs_update_extent_tree(struct inode *inode, pgoff_t fofs, ...@@ -587,6 +599,7 @@ static void f2fs_update_extent_tree(struct inode *inode, pgoff_t fofs,
memset(et, 0, sizeof(struct extent_tree)); memset(et, 0, sizeof(struct extent_tree));
et->ino = ino; et->ino = ino;
et->root = RB_ROOT; et->root = RB_ROOT;
et->cached_en = NULL;
rwlock_init(&et->lock); rwlock_init(&et->lock);
atomic_set(&et->refcount, 0); atomic_set(&et->refcount, 0);
et->count = 0; et->count = 0;
......
...@@ -298,6 +298,7 @@ struct extent_node { ...@@ -298,6 +298,7 @@ struct extent_node {
struct extent_tree { struct extent_tree {
nid_t ino; /* inode number */ nid_t ino; /* inode number */
struct rb_root root; /* root of extent info rb-tree */ 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 */ rwlock_t lock; /* protect extent info rb-tree */
atomic_t refcount; /* reference count of rb-tree */ atomic_t refcount; /* reference count of rb-tree */
unsigned int count; /* # of extent node in rb-tree*/ unsigned int count; /* # of extent node in rb-tree*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment