f2fs: support lower priority asynchronous readahead in ra_meta_pages
authorChao Yu <chao2.yu@samsung.com>
Mon, 12 Oct 2015 09:05:59 +0000 (17:05 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Mon, 12 Oct 2015 21:03:15 +0000 (14:03 -0700)
Now, we use ra_meta_pages to reads continuous physical blocks as much as
possible to improve performance of following reads. However, ra_meta_pages
uses a synchronous readahead approach by submitting bio with READ, as READ
is with high priority, it can not be used in the case of preloading blocks,
and it's not sure when these RAed pages will be used.

This patch supports asynchronous readahead in ra_meta_pages by tagging bio
with READA flag in order to allow preloading.

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/gc.c
fs/f2fs/node.c
fs/f2fs/recovery.c
fs/f2fs/segment.c

index 60a95992384feb8b28b1b1c21ca3748e8e444384..f661d80474be7ab8f91de74525fa65198cfa68f9 100644 (file)
@@ -140,7 +140,8 @@ bool is_valid_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr, int type)
 /*
  * Readahead CP/NAT/SIT/SSA pages
  */
-int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, int type)
+int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
+                                                       int type, bool sync)
 {
        block_t prev_blk_addr = 0;
        struct page *page;
@@ -148,7 +149,7 @@ int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, int type
        struct f2fs_io_info fio = {
                .sbi = sbi,
                .type = META,
-               .rw = READ_SYNC | REQ_META | REQ_PRIO,
+               .rw = sync ? (READ_SYNC | REQ_META | REQ_PRIO) : READA,
                .encrypted_page = NULL,
        };
 
@@ -214,7 +215,7 @@ void ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index)
        f2fs_put_page(page, 0);
 
        if (readahead)
-               ra_meta_pages(sbi, index, MAX_BIO_BLOCKS(sbi), META_POR);
+               ra_meta_pages(sbi, index, MAX_BIO_BLOCKS(sbi), META_POR, true);
 }
 
 static int f2fs_write_meta_page(struct page *page,
@@ -521,7 +522,7 @@ int recover_orphan_inodes(struct f2fs_sb_info *sbi)
        start_blk = __start_cp_addr(sbi) + 1 + __cp_payload(sbi);
        orphan_blocks = __start_sum_addr(sbi) - 1 - __cp_payload(sbi);
 
-       ra_meta_pages(sbi, start_blk, orphan_blocks, META_CP);
+       ra_meta_pages(sbi, start_blk, orphan_blocks, META_CP, true);
 
        for (i = 0; i < orphan_blocks; i++) {
                struct page *page = get_meta_page(sbi, start_blk + i);
index 6c0e83c5ced57f650442eaac2cb1af885dcfe28e..5f372c03de325b3013e621c28c8eb9918efac1c2 100644 (file)
@@ -1808,7 +1808,7 @@ 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_tmp_page(struct f2fs_sb_info *, pgoff_t);
 bool is_valid_blkaddr(struct f2fs_sb_info *, block_t, int);
-int ra_meta_pages(struct f2fs_sb_info *, block_t, int, int);
+int ra_meta_pages(struct f2fs_sb_info *, block_t, int, int, bool);
 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);
index 94278dbbdf7cc2c7b3b5fe230b1783984c1ab030..3f19634e2aa51efe9c2cfbf544f5d9508e4c469e 100644 (file)
@@ -840,7 +840,7 @@ gc_more:
        /* readahead multi ssa blocks those have contiguous address */
        if (sbi->segs_per_sec > 1)
                ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno), sbi->segs_per_sec,
-                                                               META_SSA);
+                                                       META_SSA, true);
 
        for (i = 0; i < sbi->segs_per_sec; i++) {
                /*
index c61dfb6953087820a2d9171262f808b5fde26b0d..ad98e35f3fcb5258d155c1306a179c51b86ec6eb 100644 (file)
@@ -1529,7 +1529,8 @@ static void build_free_nids(struct f2fs_sb_info *sbi)
                return;
 
        /* readahead nat pages to be scanned */
-       ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), FREE_NID_PAGES, META_NAT);
+       ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), FREE_NID_PAGES,
+                                                       META_NAT, true);
 
        while (1) {
                struct page *page = get_current_nat_page(sbi, nid);
@@ -1804,7 +1805,7 @@ int restore_node_summary(struct f2fs_sb_info *sbi,
                nrpages = min(last_offset - i, bio_blocks);
 
                /* readahead node pages */
-               ra_meta_pages(sbi, addr, nrpages, META_POR);
+               ra_meta_pages(sbi, addr, nrpages, META_POR, true);
 
                for (idx = addr; idx < addr + nrpages; idx++) {
                        struct page *page = get_tmp_page(sbi, idx);
index 75dbc0708c7b2314e540eed2e188a621e2748a6d..cbf74f47cce8ad9005bf8486df4435c79e0b6b04 100644 (file)
@@ -180,7 +180,7 @@ 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);
+       ra_meta_pages(sbi, blkaddr, 1, META_POR, true);
 
        while (1) {
                struct fsync_inode_entry *entry;
index 13aa7a6eee53fc129aa8ef0535dea6cdf5bf1073..5337fd6fdc32f2459aa33e28e191fac57cf89734 100644 (file)
@@ -1621,7 +1621,7 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi)
 
                if (npages >= 2)
                        ra_meta_pages(sbi, start_sum_block(sbi), npages,
-                                                               META_CP);
+                                                       META_CP, true);
 
                /* restore for compacted data summary */
                if (read_compacted_summaries(sbi))
@@ -1631,7 +1631,7 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi)
 
        if (__exist_node_summaries(sbi))
                ra_meta_pages(sbi, sum_blk_addr(sbi, NR_CURSEG_TYPE, type),
-                                       NR_CURSEG_TYPE - type, META_CP);
+                                       NR_CURSEG_TYPE - type, META_CP, true);
 
        for (; type <= CURSEG_COLD_NODE; type++) {
                err = read_normal_summaries(sbi, type);
@@ -2118,7 +2118,7 @@ static void build_sit_entries(struct f2fs_sb_info *sbi)
        int nrpages = MAX_BIO_BLOCKS(sbi);
 
        do {
-               readed = ra_meta_pages(sbi, start_blk, nrpages, META_SIT);
+               readed = ra_meta_pages(sbi, start_blk, nrpages, META_SIT, true);
 
                start = start_blk * sit_i->sents_per_block;
                end = (start_blk + readed) * sit_i->sents_per_block;