f2fs: check last page index in cached bio to decide submission
authorJaegeuk Kim <jaegeuk@kernel.org>
Thu, 2 Feb 2017 00:51:22 +0000 (16:51 -0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Thu, 23 Feb 2017 18:10:48 +0000 (10:10 -0800)
If the cached bio has the last page's index, then we need to submit it.
Otherwise, we don't need to submit it and can wait for further IO merges.

Reviewed-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/checkpoint.c
fs/f2fs/data.c
fs/f2fs/f2fs.h
fs/f2fs/node.c
fs/f2fs/segment.c

index fb8cdfcaece6b1607b23f57a1ee49c0f93337a61..e6e42a4b13444c8580330205f142d9e43d609f96 100644 (file)
@@ -249,7 +249,8 @@ static int f2fs_write_meta_page(struct page *page,
        dec_page_count(sbi, F2FS_DIRTY_META);
 
        if (wbc->for_reclaim)
-               f2fs_submit_merged_bio_cond(sbi, NULL, page, 0, META, WRITE);
+               f2fs_submit_merged_bio_cond(sbi, page->mapping->host,
+                                               0, page->index, META, WRITE);
 
        unlock_page(page);
 
index e0b74b9ea38883ca16058729f089aab567c6033e..d14cc8be14f1d4602a6c9f5761ab8463219f4a1a 100644 (file)
@@ -243,8 +243,8 @@ static void __submit_merged_bio(struct f2fs_bio_info *io)
        io->bio = NULL;
 }
 
-static bool __has_merged_page(struct f2fs_bio_info *io, struct inode *inode,
-                                               struct page *page, nid_t ino)
+static bool __has_merged_page(struct f2fs_bio_info *io,
+                               struct inode *inode, nid_t ino, pgoff_t idx)
 {
        struct bio_vec *bvec;
        struct page *target;
@@ -253,7 +253,7 @@ static bool __has_merged_page(struct f2fs_bio_info *io, struct inode *inode,
        if (!io->bio)
                return false;
 
-       if (!inode && !page && !ino)
+       if (!inode && !ino)
                return true;
 
        bio_for_each_segment_all(bvec, io->bio, i) {
@@ -263,10 +263,11 @@ static bool __has_merged_page(struct f2fs_bio_info *io, struct inode *inode,
                else
                        target = fscrypt_control_page(bvec->bv_page);
 
+               if (idx != target->index)
+                       continue;
+
                if (inode && inode == target->mapping->host)
                        return true;
-               if (page && page == target)
-                       return true;
                if (ino && ino == ino_of_node(target))
                        return true;
        }
@@ -275,22 +276,21 @@ static bool __has_merged_page(struct f2fs_bio_info *io, struct inode *inode,
 }
 
 static bool has_merged_page(struct f2fs_sb_info *sbi, struct inode *inode,
-                                               struct page *page, nid_t ino,
-                                               enum page_type type)
+                               nid_t ino, pgoff_t idx, enum page_type type)
 {
        enum page_type btype = PAGE_TYPE_OF_BIO(type);
        struct f2fs_bio_info *io = &sbi->write_io[btype];
        bool ret;
 
        down_read(&io->io_rwsem);
-       ret = __has_merged_page(io, inode, page, ino);
+       ret = __has_merged_page(io, inode, ino, idx);
        up_read(&io->io_rwsem);
        return ret;
 }
 
 static void __f2fs_submit_merged_bio(struct f2fs_sb_info *sbi,
-                               struct inode *inode, struct page *page,
-                               nid_t ino, enum page_type type, int rw)
+                               struct inode *inode, nid_t ino, pgoff_t idx,
+                               enum page_type type, int rw)
 {
        enum page_type btype = PAGE_TYPE_OF_BIO(type);
        struct f2fs_bio_info *io;
@@ -299,7 +299,7 @@ static void __f2fs_submit_merged_bio(struct f2fs_sb_info *sbi,
 
        down_write(&io->io_rwsem);
 
-       if (!__has_merged_page(io, inode, page, ino))
+       if (!__has_merged_page(io, inode, ino, idx))
                goto out;
 
        /* change META to META_FLUSH in the checkpoint procedure */
@@ -318,15 +318,15 @@ out:
 void f2fs_submit_merged_bio(struct f2fs_sb_info *sbi, enum page_type type,
                                                                        int rw)
 {
-       __f2fs_submit_merged_bio(sbi, NULL, NULL, 0, type, rw);
+       __f2fs_submit_merged_bio(sbi, NULL, 0, 0, type, rw);
 }
 
 void f2fs_submit_merged_bio_cond(struct f2fs_sb_info *sbi,
-                               struct inode *inode, struct page *page,
-                               nid_t ino, enum page_type type, int rw)
+                               struct inode *inode, nid_t ino, pgoff_t idx,
+                               enum page_type type, int rw)
 {
-       if (has_merged_page(sbi, inode, page, ino, type))
-               __f2fs_submit_merged_bio(sbi, inode, page, ino, type, rw);
+       if (has_merged_page(sbi, inode, ino, idx, type))
+               __f2fs_submit_merged_bio(sbi, inode, ino, idx, type, rw);
 }
 
 void f2fs_flush_merged_bios(struct f2fs_sb_info *sbi)
@@ -1432,7 +1432,8 @@ out:
                ClearPageUptodate(page);
 
        if (wbc->for_reclaim) {
-               f2fs_submit_merged_bio_cond(sbi, NULL, page, 0, DATA, WRITE);
+               f2fs_submit_merged_bio_cond(sbi, inode, 0, page->index,
+                                               DATA, WRITE);
                remove_dirty_inode(inode);
                submitted = NULL;
        }
@@ -1480,10 +1481,10 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
        pgoff_t index;
        pgoff_t end;            /* Inclusive */
        pgoff_t done_index;
+       pgoff_t last_idx = ULONG_MAX;
        int cycled;
        int range_whole = 0;
        int tag;
-       int nwritten = 0;
 
        pagevec_init(&pvec, 0);
 
@@ -1569,7 +1570,7 @@ continue_unlock:
                                done = 1;
                                break;
                        } else if (submitted) {
-                               nwritten++;
+                               last_idx = page->index;
                        }
 
                        if (--wbc->nr_to_write <= 0 &&
@@ -1591,9 +1592,9 @@ continue_unlock:
        if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
                mapping->writeback_index = done_index;
 
-       if (nwritten)
+       if (last_idx != ULONG_MAX)
                f2fs_submit_merged_bio_cond(F2FS_M_SB(mapping), mapping->host,
-                                                       NULL, 0, DATA, WRITE);
+                                               0, last_idx, DATA, WRITE);
 
        return ret;
 }
index 77ae2a8f15ce67caae2467c782b50da7cfdd1a60..b8070f9e8285ca2b63a23118bf6dee28674370ba 100644 (file)
@@ -2233,8 +2233,8 @@ void destroy_checkpoint_caches(void);
 void f2fs_submit_merged_bio(struct f2fs_sb_info *sbi, enum page_type type,
                        int rw);
 void f2fs_submit_merged_bio_cond(struct f2fs_sb_info *sbi,
-                               struct inode *inode, struct page *page,
-                               nid_t ino, enum page_type type, int rw);
+                               struct inode *inode, nid_t ino, pgoff_t idx,
+                               enum page_type type, int rw);
 void f2fs_flush_merged_bios(struct f2fs_sb_info *sbi);
 int f2fs_submit_page_bio(struct f2fs_io_info *fio);
 int f2fs_submit_page_mbio(struct f2fs_io_info *fio);
index 5bd05e552d19084e823091a72385e453c8e7be7b..8203a2f8b350ae8ff0353ae5c7efbc7853163b38 100644 (file)
@@ -1374,7 +1374,8 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted,
        up_read(&sbi->node_write);
 
        if (wbc->for_reclaim) {
-               f2fs_submit_merged_bio_cond(sbi, NULL, page, 0, NODE, WRITE);
+               f2fs_submit_merged_bio_cond(sbi, page->mapping->host, 0,
+                                               page->index, NODE, WRITE);
                submitted = NULL;
        }
 
@@ -1404,12 +1405,12 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
                        struct writeback_control *wbc, bool atomic)
 {
        pgoff_t index, end;
+       pgoff_t last_idx = ULONG_MAX;
        struct pagevec pvec;
        int ret = 0;
        struct page *last_page = NULL;
        bool marked = false;
        nid_t ino = inode->i_ino;
-       int nwritten = 0;
 
        if (atomic) {
                last_page = last_fsync_dnode(sbi, ino);
@@ -1488,7 +1489,7 @@ continue_unlock:
                                f2fs_put_page(last_page, 0);
                                break;
                        } else if (submitted) {
-                               nwritten++;
+                               last_idx = page->index;
                        }
 
                        if (page == last_page) {
@@ -1514,8 +1515,9 @@ continue_unlock:
                goto retry;
        }
 out:
-       if (nwritten)
-               f2fs_submit_merged_bio_cond(sbi, NULL, NULL, ino, NODE, WRITE);
+       if (last_idx != ULONG_MAX)
+               f2fs_submit_merged_bio_cond(sbi, NULL, ino, last_idx,
+                                                       NODE, WRITE);
        return ret ? -EIO: 0;
 }
 
index 2f6d7370904cfb9f57b862d300c3fdeb1efaa95d..b2e0769a09d03be838044f826895f8aad4f6ead1 100644 (file)
@@ -263,7 +263,7 @@ static int __commit_inmem_pages(struct inode *inode,
                .op_flags = REQ_SYNC | REQ_PRIO,
                .encrypted_page = NULL,
        };
-       bool submit_bio = false;
+       pgoff_t last_idx = ULONG_MAX;
        int err = 0;
 
        list_for_each_entry_safe(cur, tmp, &fi->inmem_pages, list) {
@@ -289,15 +289,15 @@ static int __commit_inmem_pages(struct inode *inode,
 
                        /* record old blkaddr for revoking */
                        cur->old_addr = fio.old_blkaddr;
-
-                       submit_bio = true;
+                       last_idx = page->index;
                }
                unlock_page(page);
                list_move_tail(&cur->list, revoke_list);
        }
 
-       if (submit_bio)
-               f2fs_submit_merged_bio_cond(sbi, inode, NULL, 0, DATA, WRITE);
+       if (last_idx != ULONG_MAX)
+               f2fs_submit_merged_bio_cond(sbi, inode, 0, last_idx,
+                                                       DATA, WRITE);
 
        if (!err)
                __revoke_inmem_pages(inode, revoke_list, false, false);
@@ -1932,7 +1932,8 @@ void f2fs_wait_on_page_writeback(struct page *page,
        if (PageWriteback(page)) {
                struct f2fs_sb_info *sbi = F2FS_P_SB(page);
 
-               f2fs_submit_merged_bio_cond(sbi, NULL, page, 0, type, WRITE);
+               f2fs_submit_merged_bio_cond(sbi, page->mapping->host,
+                                               0, page->index, type, WRITE);
                if (ordered)
                        wait_on_page_writeback(page);
                else