diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2015-01-07 13:47:57 -0500 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2015-01-09 20:02:28 -0500 |
commit | 7aed0d45376e531330cf20af581a76edc0347d06 (patch) | |
tree | e5462eff4888835a52f98bf5a431e2054f92a853 | |
parent | df1991391f9301efbd5e46fb776bf5103d4c59f8 (diff) |
f2fs: free radix_tree_nodes used by nat_set entries
In the normal case, the radix_tree_nodes are freed successfully.
But, when cp_error was detected, we should destroy them forcefully.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r-- | fs/f2fs/node.c | 21 | ||||
-rw-r--r-- | fs/f2fs/node.h | 1 |
2 files changed, 20 insertions, 2 deletions
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 9bed0161efee..d7c143626705 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c | |||
@@ -1894,7 +1894,7 @@ void flush_nat_entries(struct f2fs_sb_info *sbi) | |||
1894 | struct f2fs_nm_info *nm_i = NM_I(sbi); | 1894 | struct f2fs_nm_info *nm_i = NM_I(sbi); |
1895 | struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA); | 1895 | struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA); |
1896 | struct f2fs_summary_block *sum = curseg->sum_blk; | 1896 | struct f2fs_summary_block *sum = curseg->sum_blk; |
1897 | struct nat_entry_set *setvec[NATVEC_SIZE]; | 1897 | struct nat_entry_set *setvec[SETVEC_SIZE]; |
1898 | struct nat_entry_set *set, *tmp; | 1898 | struct nat_entry_set *set, *tmp; |
1899 | unsigned int found; | 1899 | unsigned int found; |
1900 | nid_t set_idx = 0; | 1900 | nid_t set_idx = 0; |
@@ -1911,7 +1911,7 @@ void flush_nat_entries(struct f2fs_sb_info *sbi) | |||
1911 | remove_nats_in_journal(sbi); | 1911 | remove_nats_in_journal(sbi); |
1912 | 1912 | ||
1913 | while ((found = __gang_lookup_nat_set(nm_i, | 1913 | while ((found = __gang_lookup_nat_set(nm_i, |
1914 | set_idx, NATVEC_SIZE, setvec))) { | 1914 | set_idx, SETVEC_SIZE, setvec))) { |
1915 | unsigned idx; | 1915 | unsigned idx; |
1916 | set_idx = setvec[found - 1]->set + 1; | 1916 | set_idx = setvec[found - 1]->set + 1; |
1917 | for (idx = 0; idx < found; idx++) | 1917 | for (idx = 0; idx < found; idx++) |
@@ -1991,6 +1991,7 @@ void destroy_node_manager(struct f2fs_sb_info *sbi) | |||
1991 | struct f2fs_nm_info *nm_i = NM_I(sbi); | 1991 | struct f2fs_nm_info *nm_i = NM_I(sbi); |
1992 | struct free_nid *i, *next_i; | 1992 | struct free_nid *i, *next_i; |
1993 | struct nat_entry *natvec[NATVEC_SIZE]; | 1993 | struct nat_entry *natvec[NATVEC_SIZE]; |
1994 | struct nat_entry_set *setvec[SETVEC_SIZE]; | ||
1994 | nid_t nid = 0; | 1995 | nid_t nid = 0; |
1995 | unsigned int found; | 1996 | unsigned int found; |
1996 | 1997 | ||
@@ -2015,11 +2016,27 @@ void destroy_node_manager(struct f2fs_sb_info *sbi) | |||
2015 | while ((found = __gang_lookup_nat_cache(nm_i, | 2016 | while ((found = __gang_lookup_nat_cache(nm_i, |
2016 | nid, NATVEC_SIZE, natvec))) { | 2017 | nid, NATVEC_SIZE, natvec))) { |
2017 | unsigned idx; | 2018 | unsigned idx; |
2019 | |||
2018 | nid = nat_get_nid(natvec[found - 1]) + 1; | 2020 | nid = nat_get_nid(natvec[found - 1]) + 1; |
2019 | for (idx = 0; idx < found; idx++) | 2021 | for (idx = 0; idx < found; idx++) |
2020 | __del_from_nat_cache(nm_i, natvec[idx]); | 2022 | __del_from_nat_cache(nm_i, natvec[idx]); |
2021 | } | 2023 | } |
2022 | f2fs_bug_on(sbi, nm_i->nat_cnt); | 2024 | f2fs_bug_on(sbi, nm_i->nat_cnt); |
2025 | |||
2026 | /* destroy nat set cache */ | ||
2027 | nid = 0; | ||
2028 | while ((found = __gang_lookup_nat_set(nm_i, | ||
2029 | nid, SETVEC_SIZE, setvec))) { | ||
2030 | unsigned idx; | ||
2031 | |||
2032 | nid = setvec[found - 1]->set + 1; | ||
2033 | for (idx = 0; idx < found; idx++) { | ||
2034 | /* entry_cnt is not zero, when cp_error was occurred */ | ||
2035 | f2fs_bug_on(sbi, !list_empty(&setvec[idx]->entry_list)); | ||
2036 | radix_tree_delete(&nm_i->nat_set_root, setvec[idx]->set); | ||
2037 | kmem_cache_free(nat_entry_set_slab, setvec[idx]); | ||
2038 | } | ||
2039 | } | ||
2023 | up_write(&nm_i->nat_tree_lock); | 2040 | up_write(&nm_i->nat_tree_lock); |
2024 | 2041 | ||
2025 | kfree(nm_i->nat_bitmap); | 2042 | kfree(nm_i->nat_bitmap); |
diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h index cac8a3d9acbd..f405bbf2435a 100644 --- a/fs/f2fs/node.h +++ b/fs/f2fs/node.h | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | /* vector size for gang look-up from nat cache that consists of radix tree */ | 26 | /* vector size for gang look-up from nat cache that consists of radix tree */ |
27 | #define NATVEC_SIZE 64 | 27 | #define NATVEC_SIZE 64 |
28 | #define SETVEC_SIZE 32 | ||
28 | 29 | ||
29 | /* return value for read_node_page */ | 30 | /* return value for read_node_page */ |
30 | #define LOCKED_PAGE 1 | 31 | #define LOCKED_PAGE 1 |