Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Chao Yu and committed by
Jaegeuk Kim
0bdee482 028a41e8

+62
+49
fs/f2fs/data.c
··· 719 719 atomic_dec(&et->refcount); 720 720 } 721 721 722 + void 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 + } 763 + out: 764 + read_unlock(&et->lock); 765 + atomic_dec(&et->refcount); 766 + 767 + if (sync) 768 + update_inode_page(inode); 769 + } 770 + 722 771 void f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) 723 772 { 724 773 struct extent_tree *treevec[EXT_TREE_VEC_SIZE];
+8
fs/f2fs/f2fs.h
··· 371 371 ei->len = len; 372 372 } 373 373 374 + static 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 + 374 381 static inline bool __is_extent_mergeable(struct extent_info *back, 375 382 struct extent_info *front) 376 383 { ··· 1605 1598 void f2fs_destroy_extent_tree(struct inode *); 1606 1599 void f2fs_init_extent_cache(struct inode *, struct f2fs_extent *); 1607 1600 void f2fs_update_extent_cache(struct dnode_of_data *); 1601 + void f2fs_preserve_extent_tree(struct inode *); 1608 1602 struct page *find_data_page(struct inode *, pgoff_t, bool); 1609 1603 struct page *get_lock_data_page(struct inode *, pgoff_t); 1610 1604 struct page *get_new_data_page(struct inode *, struct page *, pgoff_t, bool);
+5
fs/f2fs/inode.c
··· 343 343 no_delete: 344 344 stat_dec_inline_dir(inode); 345 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 350 f2fs_destroy_extent_tree(inode); 351 + 347 352 invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino, inode->i_ino); 348 353 if (xnid) 349 354 invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid);