Commit a03f01f2 authored by Hou Pengyang's avatar Hou Pengyang Committed by Jaegeuk Kim

f2fs: reconstruct the code to free an extent_node

There are three steps to free an extent node:
1) list_del_init, 2)__detach_extent_node, 3) kmem_cache_free

In path f2fs_destroy_extent_tree, 1->2->3 to free a node,
But in path f2fs_update_extent_tree_range, it is 2->1->3.

This patch makes all the order to be: 1->2->3
It makes sense, since in the next patch, we import a victim list in the
path shrink_extent_tree, we could check if the extent_node is in the victim
list by checking the list_empty(). So it is necessary to put 1) first.
Signed-off-by: default avatarHou Pengyang <houpengyang@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 7c506896
...@@ -50,6 +50,24 @@ static void __detach_extent_node(struct f2fs_sb_info *sbi, ...@@ -50,6 +50,24 @@ static void __detach_extent_node(struct f2fs_sb_info *sbi,
if (et->cached_en == en) if (et->cached_en == en)
et->cached_en = NULL; et->cached_en = NULL;
kmem_cache_free(extent_node_slab, en);
}
/*
* Flow to release an extent_node:
* 1. list_del_init
* 2. __detach_extent_node
* 3. kmem_cache_free.
*/
static void __release_extent_node(struct f2fs_sb_info *sbi,
struct extent_tree *et, struct extent_node *en)
{
spin_lock(&sbi->extent_lock);
if (!list_empty(&en->list))
list_del_init(&en->list);
spin_unlock(&sbi->extent_lock);
__detach_extent_node(sbi, et, en);
} }
static struct extent_tree *__grab_extent_tree(struct inode *inode) static struct extent_tree *__grab_extent_tree(struct inode *inode)
...@@ -140,17 +158,10 @@ static unsigned int __free_extent_tree(struct f2fs_sb_info *sbi, ...@@ -140,17 +158,10 @@ static unsigned int __free_extent_tree(struct f2fs_sb_info *sbi,
next = rb_next(node); next = rb_next(node);
en = rb_entry(node, struct extent_node, rb_node); en = rb_entry(node, struct extent_node, rb_node);
if (free_all) { if (free_all)
spin_lock(&sbi->extent_lock); __release_extent_node(sbi, et, en);
if (!list_empty(&en->list)) else if (list_empty(&en->list))
list_del_init(&en->list);
spin_unlock(&sbi->extent_lock);
}
if (free_all || list_empty(&en->list)) {
__detach_extent_node(sbi, et, en); __detach_extent_node(sbi, et, en);
kmem_cache_free(extent_node_slab, en);
}
node = next; node = next;
} }
...@@ -329,7 +340,6 @@ static struct extent_node *__lookup_extent_tree_ret(struct extent_tree *et, ...@@ -329,7 +340,6 @@ static struct extent_node *__lookup_extent_tree_ret(struct extent_tree *et,
static struct extent_node *__try_merge_extent_node(struct f2fs_sb_info *sbi, static struct extent_node *__try_merge_extent_node(struct f2fs_sb_info *sbi,
struct extent_tree *et, struct extent_info *ei, struct extent_tree *et, struct extent_info *ei,
struct extent_node **den,
struct extent_node *prev_ex, struct extent_node *prev_ex,
struct extent_node *next_ex) struct extent_node *next_ex)
{ {
...@@ -342,10 +352,8 @@ static struct extent_node *__try_merge_extent_node(struct f2fs_sb_info *sbi, ...@@ -342,10 +352,8 @@ static struct extent_node *__try_merge_extent_node(struct f2fs_sb_info *sbi,
} }
if (next_ex && __is_front_mergeable(ei, &next_ex->ei)) { if (next_ex && __is_front_mergeable(ei, &next_ex->ei)) {
if (en) { if (en)
__detach_extent_node(sbi, et, prev_ex); __release_extent_node(sbi, et, prev_ex);
*den = prev_ex;
}
next_ex->ei.fofs = ei->fofs; next_ex->ei.fofs = ei->fofs;
next_ex->ei.blk = ei->blk; next_ex->ei.blk = ei->blk;
next_ex->ei.len += ei->len; next_ex->ei.len += ei->len;
...@@ -479,7 +487,7 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode, ...@@ -479,7 +487,7 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode,
if (parts) if (parts)
__try_update_largest_extent(et, en); __try_update_largest_extent(et, en);
else else
__detach_extent_node(sbi, et, en); __release_extent_node(sbi, et, en);
/* /*
* if original extent is split into zero or two parts, extent * if original extent is split into zero or two parts, extent
...@@ -493,26 +501,18 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode, ...@@ -493,26 +501,18 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode,
/* update in global extent list */ /* update in global extent list */
spin_lock(&sbi->extent_lock); spin_lock(&sbi->extent_lock);
if (!parts && !list_empty(&en->list))
list_del(&en->list);
if (en1) if (en1)
list_add_tail(&en1->list, &sbi->extent_list); list_add_tail(&en1->list, &sbi->extent_list);
spin_unlock(&sbi->extent_lock); spin_unlock(&sbi->extent_lock);
/* release extent node */
if (!parts)
kmem_cache_free(extent_node_slab, en);
en = next_en; en = next_en;
} }
/* 3. update extent in extent cache */ /* 3. update extent in extent cache */
if (blkaddr) { if (blkaddr) {
struct extent_node *den = NULL;
set_extent_info(&ei, fofs, blkaddr, len); set_extent_info(&ei, fofs, blkaddr, len);
en1 = __try_merge_extent_node(sbi, et, &ei, &den, en1 = __try_merge_extent_node(sbi, et, &ei, prev_en, next_en);
prev_en, next_en);
if (!en1) if (!en1)
en1 = __insert_extent_tree(sbi, et, &ei, en1 = __insert_extent_tree(sbi, et, &ei,
insert_p, insert_parent); insert_p, insert_parent);
...@@ -532,12 +532,7 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode, ...@@ -532,12 +532,7 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode,
else else
list_move_tail(&en1->list, &sbi->extent_list); list_move_tail(&en1->list, &sbi->extent_list);
} }
if (den && !list_empty(&den->list))
list_del(&den->list);
spin_unlock(&sbi->extent_lock); spin_unlock(&sbi->extent_lock);
if (den)
kmem_cache_free(extent_node_slab, den);
} }
if (is_inode_flag_set(F2FS_I(inode), FI_NO_EXTENT)) if (is_inode_flag_set(F2FS_I(inode), FI_NO_EXTENT))
......
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