f2fs: preserve extent info for extent cache
PATCH 4/4 f2fs: preserve extent info for extent cache
This patch tries to preserve last extent info in extent tree cache into on-disk inode, so this can help us to reuse the last extent info next time for performance.
Signed-off-by Chao Yu <[email protected]>
--- fs/f2fs/data.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ fs/f2fs/f2fs.h | 8 ++++++++ fs/f2fs/inode.c | 5 +++++ 3 files changed, 62 insertions(+)
fs/f2fs/data.c +49 -0
@@ -718,6 +718,55 @@ update_extent:atomic_dec (&et->refcount); } +void f2fs_preserve_extent_tree (struct inode *inode) +{ +struct extent_tree *et; +struct extent_info *ext = &F2FS_I (inode)->ext; +bool sync = false; + +if (!test_opt (F2FS_I_SB (inode),EXTENT_CACHE )) +return ; + + et =__find_extent_tree (F2FS_I_SB (inode), inode->i_ino); +if (!et) { +if (ext->len) { + ext->len =0 ; +update_inode_page (inode); + } +return ; + } + +read_lock (&et->lock); +if (et->count) { +struct extent_node *en; + +if (et->cached_en) { + en = et->cached_en; + }else { +struct rb_node *node =rb_first (&et->root); + +if (!node) + node =rb_last (&et->root); + en = rb_entry(node, struct extent_node, rb_node); + } + +if (__is_extent_same (ext, &en->ei)) + goto out; + + *ext = en->ei; + sync = true; + }else if (ext->len) { + ext->len =0 ; + sync = true; + } +out: +read_unlock (&et->lock); +atomic_dec (&et->refcount); + +if (sync) +update_inode_page (inode); +} +void f2fs_shrink_extent_tree (struct f2fs_sb_info *sbi,int nr_shrink) {struct extent_tree *treevec[EXT_TREE_VEC_SIZE ];
fs/f2fs/f2fs.h +8 -0
@@ -362,6 +362,13 @@ static inline void set_extent_info(struct extent_info *ei, unsigned int fofs, ei->len = len; } +static inline bool __is_extent_same (struct extent_info *ei1, +struct extent_info *ei2) +{ +return (ei1->fofs == ei2->fofs && ei1->blk == ei2->blk && + ei1->len == ei2->len); +} +static inline bool __is_extent_mergeable (struct extent_info *back,struct extent_info *front) {
@@ -1579,6 +1586,7 @@ void f2fs_shrink_extent_tree(struct f2fs_sb_info *, int);void f2fs_destroy_extent_tree (struct inode *);void f2fs_init_extent_cache (struct inode *,struct f2fs_extent *);void f2fs_update_extent_cache (struct dnode_of_data *); +void f2fs_preserve_extent_tree (struct inode *);struct page *find_data_page (struct inode *,pgoff_t ,bool );struct page *get_lock_data_page (struct inode *,pgoff_t );struct page *get_new_data_page (struct inode *,struct page *,pgoff_t ,bool );
fs/f2fs/inode.c +5 -0
@@ -333,7 +333,12 @@ void f2fs_evict_inode(struct inode *inode) no_delete:stat_dec_inline_dir (inode);stat_dec_inline_inode (inode); + +/* update extent info in inode */ +if (inode->i_nlink) +f2fs_preserve_extent_tree (inode);f2fs_destroy_extent_tree (inode); +invalidate_mapping_pages (NODE_MAPPING (sbi), inode->i_ino, inode->i_ino);if (xnid)invalidate_mapping_pages (NODE_MAPPING (sbi), xnid, xnid);
Signature · 1 line
2.3.1