f2fs: avoid to ra unneeded blocks in recover flow
authorChao Yu <chao2.yu@samsung.com>
Mon, 8 Dec 2014 07:02:52 +0000 (15:02 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Mon, 8 Dec 2014 22:19:09 +0000 (14:19 -0800)
To improve recovery speed, f2fs try to readahead many contiguous blocks in warm
node segment, but for most time, abnormal power-off do not occur frequently, so
when mount a normal power-off f2fs image, by contrary ra so many blocks and then
invalid them will hurt the performance of mount.
It's better to just ra the first next-block for normal condition.

Signed-off-by: Chao Yu <chao2.yu@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/checkpoint.c
fs/f2fs/f2fs.h
fs/f2fs/recovery.c

index b2d5431d6850929b24f462e9e600c25f80c0263e..e6c271fefacae5a514488d4c507bb870a47c7275 100644 (file)
@@ -72,21 +72,6 @@ out:
        return page;
 }
 
-struct page *get_meta_page_ra(struct f2fs_sb_info *sbi, pgoff_t index)
-{
-       bool readahead = false;
-       struct page *page;
-
-       page = find_get_page(META_MAPPING(sbi), index);
-       if (!page || (page && !PageUptodate(page)))
-               readahead = true;
-       f2fs_put_page(page, 0);
-
-       if (readahead)
-               ra_meta_pages(sbi, index, MAX_BIO_BLOCKS(sbi), META_POR);
-       return get_meta_page(sbi, index);
-}
-
 static inline bool is_valid_blkaddr(struct f2fs_sb_info *sbi,
                                                block_t blkaddr, int type)
 {
@@ -181,6 +166,20 @@ out:
        return blkno - start;
 }
 
+void ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index)
+{
+       struct page *page;
+       bool readahead = false;
+
+       page = find_get_page(META_MAPPING(sbi), index);
+       if (!page || (page && !PageUptodate(page)))
+               readahead = true;
+       f2fs_put_page(page, 0);
+
+       if (readahead)
+               ra_meta_pages(sbi, index, MAX_BIO_BLOCKS(sbi), META_POR);
+}
+
 static int f2fs_write_meta_page(struct page *page,
                                struct writeback_control *wbc)
 {
index 2695d78d57dd9de97a63ae7a1c587a0ebf527814..ec58bb2373fc862b0db949b8e66dd304fa0ba6fb 100644 (file)
@@ -1431,8 +1431,8 @@ void destroy_segment_manager_caches(void);
  */
 struct page *grab_meta_page(struct f2fs_sb_info *, pgoff_t);
 struct page *get_meta_page(struct f2fs_sb_info *, pgoff_t);
-struct page *get_meta_page_ra(struct f2fs_sb_info *, pgoff_t);
 int ra_meta_pages(struct f2fs_sb_info *, block_t, int, int);
+void ra_meta_pages_cond(struct f2fs_sb_info *, pgoff_t);
 long sync_meta_pages(struct f2fs_sb_info *, enum page_type, long);
 void add_dirty_inode(struct f2fs_sb_info *, nid_t, int type);
 void remove_dirty_inode(struct f2fs_sb_info *, nid_t, int type);
index 9a93a6e29b055f426ea817dcba18f850796f54ea..9160a37e1c7a4084e858d6ddb033946667a5ed17 100644 (file)
@@ -170,13 +170,15 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head)
        curseg = CURSEG_I(sbi, CURSEG_WARM_NODE);
        blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);
 
+       ra_meta_pages(sbi, blkaddr, 1, META_POR);
+
        while (1) {
                struct fsync_inode_entry *entry;
 
                if (blkaddr < MAIN_BLKADDR(sbi) || blkaddr >= MAX_BLKADDR(sbi))
                        return 0;
 
-               page = get_meta_page_ra(sbi, blkaddr);
+               page = get_meta_page(sbi, blkaddr);
 
                if (cp_ver != cpver_of_node(page))
                        break;
@@ -227,6 +229,8 @@ next:
                /* check next segment */
                blkaddr = next_blkaddr_of_node(page);
                f2fs_put_page(page, 1);
+
+               ra_meta_pages_cond(sbi, blkaddr);
        }
        f2fs_put_page(page, 1);
        return err;
@@ -436,7 +440,9 @@ static int recover_data(struct f2fs_sb_info *sbi,
                if (blkaddr < MAIN_BLKADDR(sbi) || blkaddr >= MAX_BLKADDR(sbi))
                        break;
 
-               page = get_meta_page_ra(sbi, blkaddr);
+               ra_meta_pages_cond(sbi, blkaddr);
+
+               page = get_meta_page(sbi, blkaddr);
 
                if (cp_ver != cpver_of_node(page)) {
                        f2fs_put_page(page, 1);