summaryrefslogtreecommitdiffstats
path: root/fs/f2fs/data.c
diff options
context:
space:
mode:
authorChao Yu <chao2.yu@samsung.com>2015-03-19 19:26:02 +0800
committerJaegeuk Kim <jaegeuk@kernel.org>2015-04-10 15:08:50 -0700
commit028a41e89383e1208dff1afe3e260b8cb6d3431c (patch)
tree657e0dd1fd94bd848faa03b1d39eebf775906c74 /fs/f2fs/data.c
parent93dfc52656e9ae1009ccba67e67ff69285b7743f (diff)
downloadlinux-028a41e89383e1208dff1afe3e260b8cb6d3431c.tar.gz
linux-028a41e89383e1208dff1afe3e260b8cb6d3431c.tar.bz2
linux-028a41e89383e1208dff1afe3e260b8cb6d3431c.zip
f2fs: initialize extent tree with on-disk extent info of inode
With normal extent info cache, we records largest extent mapping between logical block and physical block into extent info, and we persist extent info in on-disk inode. When we enable extent tree cache, if extent info of on-disk inode is exist, and the extent is not a small fragmented mapping extent. We'd better to load the extent info into extent tree cache when inode is loaded. By this way we can have more chance to hit extent tree cache rather than taking more time to read dnode page for block address. Signed-off-by: Chao Yu <chao2.yu@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/data.c')
-rw-r--r--fs/f2fs/data.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 67b3a99e03d5..e3be4be3a6d8 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -572,6 +572,39 @@ static unsigned int __free_extent_tree(struct f2fs_sb_info *sbi,
return count - et->count;
}
+static void f2fs_init_extent_tree(struct inode *inode,
+ struct f2fs_extent *i_ext)
+{
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+ struct extent_tree *et;
+ struct extent_node *en;
+ struct extent_info ei;
+
+ if (le32_to_cpu(i_ext->len) < F2FS_MIN_EXTENT_LEN)
+ return;
+
+ et = __grab_extent_tree(inode);
+
+ write_lock(&et->lock);
+ if (et->count)
+ goto out;
+
+ set_extent_info(&ei, le32_to_cpu(i_ext->fofs),
+ le32_to_cpu(i_ext->blk), le32_to_cpu(i_ext->len));
+
+ en = __insert_extent_tree(sbi, et, &ei, NULL);
+ if (en) {
+ et->cached_en = en;
+
+ spin_lock(&sbi->extent_lock);
+ list_add_tail(&en->list, &sbi->extent_list);
+ spin_unlock(&sbi->extent_lock);
+ }
+out:
+ write_unlock(&et->lock);
+ atomic_dec(&et->refcount);
+}
+
static bool f2fs_lookup_extent_tree(struct inode *inode, pgoff_t pgofs,
struct extent_info *ei)
{
@@ -782,6 +815,16 @@ out:
return;
}
+void f2fs_init_extent_cache(struct inode *inode, struct f2fs_extent *i_ext)
+{
+ if (test_opt(F2FS_I_SB(inode), EXTENT_CACHE))
+ f2fs_init_extent_tree(inode, i_ext);
+
+ write_lock(&F2FS_I(inode)->ext_lock);
+ get_extent_info(&F2FS_I(inode)->ext, *i_ext);
+ write_unlock(&F2FS_I(inode)->ext_lock);
+}
+
static bool f2fs_lookup_extent_cache(struct inode *inode, pgoff_t pgofs,
struct extent_info *ei)
{