diff options
author | Hou Pengyang <houpengyang@huawei.com> | 2016-01-26 12:56:25 (GMT) |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2016-02-23 00:07:23 (GMT) |
commit | a03f01f26739391e3700991c540f6361457d6e3c (patch) | |
tree | 7c50f30bcb7e680050b819ccb10820e2c7a3ff29 /fs | |
parent | 7c506896cf933a07460dd9777ac023382446beac (diff) | |
download | linux-a03f01f26739391e3700991c540f6361457d6e3c.tar.xz |
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: Hou Pengyang <houpengyang@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/f2fs/extent_cache.c | 55 |
1 files changed, 25 insertions, 30 deletions
diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index ccd5c63..ecb1f99 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c @@ -50,6 +50,24 @@ static void __detach_extent_node(struct f2fs_sb_info *sbi, if (et->cached_en == en) 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) @@ -140,17 +158,10 @@ static unsigned int __free_extent_tree(struct f2fs_sb_info *sbi, next = rb_next(node); en = rb_entry(node, struct extent_node, rb_node); - if (free_all) { - spin_lock(&sbi->extent_lock); - if (!list_empty(&en->list)) - list_del_init(&en->list); - spin_unlock(&sbi->extent_lock); - } - - if (free_all || list_empty(&en->list)) { + if (free_all) + __release_extent_node(sbi, et, en); + else if (list_empty(&en->list)) __detach_extent_node(sbi, et, en); - kmem_cache_free(extent_node_slab, en); - } node = next; } @@ -329,7 +340,6 @@ lookup_neighbors: static struct extent_node *__try_merge_extent_node(struct f2fs_sb_info *sbi, struct extent_tree *et, struct extent_info *ei, - struct extent_node **den, struct extent_node *prev_ex, struct extent_node *next_ex) { @@ -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 (en) { - __detach_extent_node(sbi, et, prev_ex); - *den = prev_ex; - } + if (en) + __release_extent_node(sbi, et, prev_ex); next_ex->ei.fofs = ei->fofs; next_ex->ei.blk = ei->blk; next_ex->ei.len += ei->len; @@ -479,7 +487,7 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode, if (parts) __try_update_largest_extent(et, en); else - __detach_extent_node(sbi, et, en); + __release_extent_node(sbi, et, en); /* * 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, /* update in global extent list */ spin_lock(&sbi->extent_lock); - if (!parts && !list_empty(&en->list)) - list_del(&en->list); if (en1) list_add_tail(&en1->list, &sbi->extent_list); spin_unlock(&sbi->extent_lock); - /* release extent node */ - if (!parts) - kmem_cache_free(extent_node_slab, en); - en = next_en; } /* 3. update extent in extent cache */ if (blkaddr) { - struct extent_node *den = NULL; set_extent_info(&ei, fofs, blkaddr, len); - en1 = __try_merge_extent_node(sbi, et, &ei, &den, - prev_en, next_en); + en1 = __try_merge_extent_node(sbi, et, &ei, prev_en, next_en); if (!en1) en1 = __insert_extent_tree(sbi, et, &ei, insert_p, insert_parent); @@ -532,12 +532,7 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode, else list_move_tail(&en1->list, &sbi->extent_list); } - if (den && !list_empty(&den->list)) - list_del(&den->list); 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)) |