Skip to content

Commit

Permalink
f2fs: preserve extent info for extent cache
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Chao Yu authored and Jaegeuk Kim committed Apr 10, 2015
1 parent 028a41e commit 0bdee48
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 0 deletions.
49 changes: 49 additions & 0 deletions fs/f2fs/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,55 @@ static void f2fs_update_extent_tree(struct inode *inode, pgoff_t fofs,
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];
Expand Down
8 changes: 8 additions & 0 deletions fs/f2fs/f2fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,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)
{
Expand Down Expand Up @@ -1598,6 +1605,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);
Expand Down
5 changes: 5 additions & 0 deletions fs/f2fs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,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);
Expand Down

0 comments on commit 0bdee48

Please sign in to comment.