diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2015-06-30 01:01:14 +0200 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2015-08-04 23:09:56 +0200 |
commit | 84bc926c076963d5b992640f5c8d242754801fd6 (patch) | |
tree | 449d6caa46fd24d069a06c8d70215d4013aa2d5b /fs/f2fs | |
parent | f2fs: use extent_cache by default (diff) | |
download | linux-84bc926c076963d5b992640f5c8d242754801fd6.tar.xz linux-84bc926c076963d5b992640f5c8d242754801fd6.zip |
f2fs: check the largest extent at look-up time
Because of the extent shrinker or other -ENOMEM scenarios, it cannot guarantee
that the largest extent would be cached in the tree all the time.
Instead of relying on extent_tree, we can simply check the cached one in extent
tree accordingly.
Reviewed-by: Chao Yu <chao2.yu@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs')
-rw-r--r-- | fs/f2fs/data.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index be0945cd9808..cdc1c2b781b8 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -512,12 +512,22 @@ static bool f2fs_lookup_extent_tree(struct inode *inode, pgoff_t pgofs, struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct extent_tree *et = F2FS_I(inode)->extent_tree; struct extent_node *en; + bool ret = false; f2fs_bug_on(sbi, !et); trace_f2fs_lookup_extent_tree_start(inode, pgofs); read_lock(&et->lock); + + if (et->largest.fofs <= pgofs && + et->largest.fofs + et->largest.len > pgofs) { + *ei = et->largest; + ret = true; + stat_inc_read_hit(sbi->sb); + goto out; + } + en = __lookup_extent_tree(et, pgofs); if (en) { *ei = en->ei; @@ -526,13 +536,15 @@ static bool f2fs_lookup_extent_tree(struct inode *inode, pgoff_t pgofs, list_move_tail(&en->list, &sbi->extent_list); et->cached_en = en; spin_unlock(&sbi->extent_lock); + ret = true; stat_inc_read_hit(sbi->sb); } +out: stat_inc_total_hit(sbi->sb); read_unlock(&et->lock); - trace_f2fs_lookup_extent_tree_end(inode, pgofs, en); - return en ? true : false; + trace_f2fs_lookup_extent_tree_end(inode, pgofs, ei); + return ret; } /* return true, if on-disk extent should be updated */ |