aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChao Yu <chao2.yu@samsung.com>2015-03-19 07:27:51 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2015-04-10 18:08:51 -0400
commit0bdee482509fe8c3cf0e66231ed37b8e70954093 (patch)
tree2477ba4cbcefcbf2fce8e860e1d7e70c6aafa524
parent028a41e89383e1208dff1afe3e260b8cb6d3431c (diff)
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 <chao2.yu@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--fs/f2fs/data.c49
-rw-r--r--fs/f2fs/f2fs.h8
-rw-r--r--fs/f2fs/inode.c5
3 files changed, 62 insertions, 0 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index e3be4be3a6d8..8a940e518be8 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -719,6 +719,55 @@ update_extent:
719 atomic_dec(&et->refcount); 719 atomic_dec(&et->refcount);
720} 720}
721 721
722void f2fs_preserve_extent_tree(struct inode *inode)
723{
724 struct extent_tree *et;
725 struct extent_info *ext = &F2FS_I(inode)->ext;
726 bool sync = false;
727
728 if (!test_opt(F2FS_I_SB(inode), EXTENT_CACHE))
729 return;
730
731 et = __find_extent_tree(F2FS_I_SB(inode), inode->i_ino);
732 if (!et) {
733 if (ext->len) {
734 ext->len = 0;
735 update_inode_page(inode);
736 }
737 return;
738 }
739
740 read_lock(&et->lock);
741 if (et->count) {
742 struct extent_node *en;
743
744 if (et->cached_en) {
745 en = et->cached_en;
746 } else {
747 struct rb_node *node = rb_first(&et->root);
748
749 if (!node)
750 node = rb_last(&et->root);
751 en = rb_entry(node, struct extent_node, rb_node);
752 }
753
754 if (__is_extent_same(ext, &en->ei))
755 goto out;
756
757 *ext = en->ei;
758 sync = true;
759 } else if (ext->len) {
760 ext->len = 0;
761 sync = true;
762 }
763out:
764 read_unlock(&et->lock);
765 atomic_dec(&et->refcount);
766
767 if (sync)
768 update_inode_page(inode);
769}
770
722void f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) 771void f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink)
723{ 772{
724 struct extent_tree *treevec[EXT_TREE_VEC_SIZE]; 773 struct extent_tree *treevec[EXT_TREE_VEC_SIZE];
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 431b4af693e5..0be198339c3b 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -371,6 +371,13 @@ static inline void set_extent_info(struct extent_info *ei, unsigned int fofs,
371 ei->len = len; 371 ei->len = len;
372} 372}
373 373
374static inline bool __is_extent_same(struct extent_info *ei1,
375 struct extent_info *ei2)
376{
377 return (ei1->fofs == ei2->fofs && ei1->blk == ei2->blk &&
378 ei1->len == ei2->len);
379}
380
374static inline bool __is_extent_mergeable(struct extent_info *back, 381static inline bool __is_extent_mergeable(struct extent_info *back,
375 struct extent_info *front) 382 struct extent_info *front)
376{ 383{
@@ -1598,6 +1605,7 @@ void f2fs_shrink_extent_tree(struct f2fs_sb_info *, int);
1598void f2fs_destroy_extent_tree(struct inode *); 1605void f2fs_destroy_extent_tree(struct inode *);
1599void f2fs_init_extent_cache(struct inode *, struct f2fs_extent *); 1606void f2fs_init_extent_cache(struct inode *, struct f2fs_extent *);
1600void f2fs_update_extent_cache(struct dnode_of_data *); 1607void f2fs_update_extent_cache(struct dnode_of_data *);
1608void f2fs_preserve_extent_tree(struct inode *);
1601struct page *find_data_page(struct inode *, pgoff_t, bool); 1609struct page *find_data_page(struct inode *, pgoff_t, bool);
1602struct page *get_lock_data_page(struct inode *, pgoff_t); 1610struct page *get_lock_data_page(struct inode *, pgoff_t);
1603struct page *get_new_data_page(struct inode *, struct page *, pgoff_t, bool); 1611struct page *get_new_data_page(struct inode *, struct page *, pgoff_t, bool);
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index 9e64d3efb2d2..07237ac2935e 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -343,7 +343,12 @@ void f2fs_evict_inode(struct inode *inode)
343no_delete: 343no_delete:
344 stat_dec_inline_dir(inode); 344 stat_dec_inline_dir(inode);
345 stat_dec_inline_inode(inode); 345 stat_dec_inline_inode(inode);
346
347 /* update extent info in inode */
348 if (inode->i_nlink)
349 f2fs_preserve_extent_tree(inode);
346 f2fs_destroy_extent_tree(inode); 350 f2fs_destroy_extent_tree(inode);
351
347 invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino, inode->i_ino); 352 invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino, inode->i_ino);
348 if (xnid) 353 if (xnid)
349 invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid); 354 invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid);