summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/f2fs/extent_cache.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c
index ab26728736eb..dcfeb43a5975 100644
--- a/fs/f2fs/extent_cache.c
+++ b/fs/f2fs/extent_cache.c
@@ -254,13 +254,21 @@ static struct extent_node *__lookup_extent_tree_ret(struct extent_tree *et,
{
struct rb_node **pnode = &et->root.rb_node;
struct rb_node *parent = NULL, *tmp_node;
- struct extent_node *en;
+ struct extent_node *en = et->cached_en;
- if (et->cached_en) {
- struct extent_info *cei = &et->cached_en->ei;
+ *insert_p = NULL;
+ *insert_parent = NULL;
+ *prev_ex = NULL;
+ *next_ex = NULL;
+
+ if (RB_EMPTY_ROOT(&et->root))
+ return NULL;
+
+ if (en) {
+ struct extent_info *cei = &en->ei;
if (cei->fofs <= fofs && cei->fofs + cei->len > fofs)
- return et->cached_en;
+ goto lookup_neighbors;
}
while (*pnode) {
@@ -272,7 +280,7 @@ static struct extent_node *__lookup_extent_tree_ret(struct extent_tree *et,
else if (fofs >= en->ei.fofs + en->ei.len)
pnode = &(*pnode)->rb_right;
else
- return en;
+ goto lookup_neighbors;
}
*insert_p = pnode;
@@ -290,8 +298,22 @@ static struct extent_node *__lookup_extent_tree_ret(struct extent_tree *et,
tmp_node = rb_prev(parent);
*prev_ex = tmp_node ?
rb_entry(tmp_node, struct extent_node, rb_node) : NULL;
-
return NULL;
+
+lookup_neighbors:
+ if (fofs == en->ei.fofs) {
+ /* lookup prev node for merging backward later */
+ tmp_node = rb_prev(&en->rb_node);
+ *prev_ex = tmp_node ?
+ rb_entry(tmp_node, struct extent_node, rb_node) : NULL;
+ }
+ if (fofs == en->ei.fofs + en->ei.len - 1) {
+ /* lookup next node for merging frontward later */
+ tmp_node = rb_next(&en->rb_node);
+ *next_ex = tmp_node ?
+ rb_entry(tmp_node, struct extent_node, rb_node) : NULL;
+ }
+ return en;
}
static struct extent_node *__try_merge_extent_node(struct f2fs_sb_info *sbi,