This path separate nat_entry mem alloc from nat_tree_lock, which will benefit in some low mem case.
Signed-off-by: Yunlei He <heyun...@huawei.com> --- fs/f2fs/node.c | 48 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index fef5c68..5adefea 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -257,22 +257,15 @@ static struct nat_entry *grab_nat_entry(struct f2fs_nm_info *nm_i, nid_t nid, if (no_fail) { new = f2fs_kmem_cache_alloc(nat_entry_slab, GFP_NOFS); - f2fs_radix_tree_insert(&nm_i->nat_root, nid, new); } else { new = kmem_cache_alloc(nat_entry_slab, GFP_NOFS); if (!new) return NULL; - if (radix_tree_insert(&nm_i->nat_root, nid, new)) { - kmem_cache_free(nat_entry_slab, new); - return NULL; - } } memset(new, 0, sizeof(struct nat_entry)); nat_set_nid(new, nid); nat_reset_flag(new); - list_add_tail(&new->list, &nm_i->nat_entries); - nm_i->nat_cnt++; return new; } @@ -281,18 +274,36 @@ static void cache_nat_entry(struct f2fs_sb_info *sbi, nid_t nid, { struct f2fs_nm_info *nm_i = NM_I(sbi); struct nat_entry *e; + struct nat_entry *e_new = grab_nat_entry(nm_i, nid, false); + radix_tree_preload(GFP_NOFS | __GFP_NOFAIL); + down_write(&nm_i->nat_tree_lock); e = __lookup_nat_cache(nm_i, nid); if (!e) { - e = grab_nat_entry(nm_i, nid, false); - if (e) - node_info_from_raw_nat(&e->ni, ne); + if (!e_new) { + up_write(&nm_i->nat_tree_lock); + return; + } + + if (radix_tree_insert(&nm_i->nat_root, nid, e_new)) { + kmem_cache_free(nat_entry_slab, e_new); + radix_tree_preload_end(); + up_write(&nm_i->nat_tree_lock); + return; + } + + radix_tree_preload_end(); + list_add_tail(&e_new->list, &nm_i->nat_entries); + nm_i->nat_cnt++; + node_info_from_raw_nat(&e_new->ni, ne); } else { f2fs_bug_on(sbi, nat_get_ino(e) != le32_to_cpu(ne->ino) || nat_get_blkaddr(e) != le32_to_cpu(ne->block_addr) || nat_get_version(e) != ne->version); + kmem_cache_free(nat_entry_slab, e_new); } + up_write(&nm_i->nat_tree_lock); } static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni, @@ -300,13 +311,17 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni, { struct f2fs_nm_info *nm_i = NM_I(sbi); struct nat_entry *e; + struct nat_entry *e_new = grab_nat_entry(nm_i, ni->nid, true); down_write(&nm_i->nat_tree_lock); e = __lookup_nat_cache(nm_i, ni->nid); if (!e) { - e = grab_nat_entry(nm_i, ni->nid, true); - copy_node_info(&e->ni, ni); + f2fs_radix_tree_insert(&nm_i->nat_root, ni->nid, e_new); + list_add_tail(&e_new->list, &nm_i->nat_entries); + nm_i->nat_cnt++; + copy_node_info(&e_new->ni, ni); f2fs_bug_on(sbi, ni->blk_addr == NEW_ADDR); + e = e_new; } else if (new_blkaddr == NEW_ADDR) { /* * when nid is reallocated, @@ -315,7 +330,9 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni, */ copy_node_info(&e->ni, ni); f2fs_bug_on(sbi, ni->blk_addr != NULL_ADDR); - } + kmem_cache_free(nat_entry_slab, e_new); + } else + kmem_cache_free(nat_entry_slab, e_new); /* sanity check */ f2fs_bug_on(sbi, nat_get_blkaddr(e) != ni->blk_addr); @@ -424,9 +441,7 @@ void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni) f2fs_put_page(page, 1); cache: /* cache nat entry */ - down_write(&nm_i->nat_tree_lock); cache_nat_entry(sbi, nid, &ne); - up_write(&nm_i->nat_tree_lock); } /* @@ -2375,6 +2390,9 @@ static void remove_nats_in_journal(struct f2fs_sb_info *sbi) ne = __lookup_nat_cache(nm_i, nid); if (!ne) { ne = grab_nat_entry(nm_i, nid, true); + f2fs_radix_tree_insert(&nm_i->nat_root, nid, ne); + list_add_tail(&ne->list, &nm_i->nat_entries); + nm_i->nat_cnt++; node_info_from_raw_nat(&ne->ni, &raw_ne); } -- 1.9.1 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel