--- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c @@ -670,18 +670,23 @@ static void __update_extent_tree_range(struct inode *inode, struct extent_info *tei, enum extent_type type) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); - struct extent_tree *et = F2FS_I(inode)->extent_tree[type]; + struct extent_tree *et; struct extent_node *en = NULL, *en1 = NULL; struct extent_node *prev_en = NULL, *next_en = NULL; struct extent_info ei, dei, prev; struct rb_node **insert_p = NULL, *insert_parent = NULL; + struct extent_tree_info *eti = &sbi->extent_tree[type]; unsigned int fofs = tei->fofs, len = tei->len; unsigned int end = fofs + len; bool updated = false; bool leftmost = false; - if (!et) + mutex_lock(&eti->extent_tree_lock); + et = F2FS_I(inode)->extent_tree[type]; + if (!et) { + mutex_unlock(&eti->extent_tree_lock); return; + } if (type == EX_READ) trace_f2fs_update_read_extent_tree_range(inode, fofs, len, @@ -695,6 +700,7 @@ static void __update_extent_tree_range(struct inode *inode, if (type == EX_READ) { if (is_inode_flag_set(inode, FI_NO_EXTENT)) { write_unlock(&et->lock); + mutex_unlock(&eti->extent_tree_lock); return; } @@ -824,6 +830,7 @@ static void __update_extent_tree_range(struct inode *inode, insert_p, insert_parent, leftmost); out_read_extent_cache: write_unlock(&et->lock); + mutex_unlock(&eti->extent_tree_lock); if (updated) f2fs_mark_inode_dirty_sync(inode, true); @@ -1003,6 +1010,9 @@ static unsigned int __shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink if (!mutex_trylock(&eti->extent_tree_lock)) goto out; + if (!F2FS_I(inode)->extent_tree[type]) + goto out; + remained = nr_shrink - (node_cnt + tree_cnt); spin_lock(&eti->extent_lock); @@ -1183,18 +1193,17 @@ static void __destroy_extent_tree(struct inode *inode, enum extent_type type) return; } + mutex_lock(&eti->extent_tree_lock); /* free all extent info belong to this extent tree */ node_cnt = __destroy_extent_node(inode, type); /* delete extent tree entry in radix tree */ - mutex_lock(&eti->extent_tree_lock); f2fs_bug_on(sbi, atomic_read(&et->node_cnt)); radix_tree_delete(&eti->extent_tree_root, inode->i_ino); kmem_cache_free(extent_tree_slab, et); atomic_dec(&eti->total_ext_tree); - mutex_unlock(&eti->extent_tree_lock); - F2FS_I(inode)->extent_tree[type] = NULL; + mutex_unlock(&eti->extent_tree_lock); trace_f2fs_destroy_extent_tree(inode, node_cnt, type); }