aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs
diff options
context:
space:
mode:
authorChao Yu <chao2.yu@samsung.com>2013-11-22 02:48:54 -0500
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2013-12-22 20:18:05 -0500
commit9af0ff1c527ebb267d9a3b6aa8af93c5843d4390 (patch)
tree4255b05374f6b6c76c0abf1f3d65f33be367cfbb /fs/f2fs
parent93dfe2ac516250755f7d5edd438b0ce67c0e3aa6 (diff)
f2fs: readahead contiguous pages for restore_node_summary
If cp has no CP_UMOUNT_FLAG, we will read all pages in whole node segment one by one, it makes low performance. So let's merge contiguous pages and readahead for better performance. Signed-off-by: Chao Yu <chao2.yu@samsung.com> [Jaegeuk Kim: adjust the new bio operations] Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs/f2fs')
-rw-r--r--fs/f2fs/node.c89
1 files changed, 63 insertions, 26 deletions
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 0e1a3df18e58..0855168af7d7 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1565,47 +1565,84 @@ int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
1565 return 0; 1565 return 0;
1566} 1566}
1567 1567
1568/*
1569 * ra_sum_pages() merge contiguous pages into one bio and submit.
1570 * these pre-readed pages are linked in pages list.
1571 */
1572static int ra_sum_pages(struct f2fs_sb_info *sbi, struct list_head *pages,
1573 int start, int nrpages)
1574{
1575 struct page *page;
1576 int page_idx = start;
1577
1578 for (; page_idx < start + nrpages; page_idx++) {
1579 /* alloc temporal page for read node summary info*/
1580 page = alloc_page(GFP_NOFS | __GFP_ZERO);
1581 if (!page) {
1582 struct page *tmp;
1583 list_for_each_entry_safe(page, tmp, pages, lru) {
1584 list_del(&page->lru);
1585 unlock_page(page);
1586 __free_pages(page, 0);
1587 }
1588 return -ENOMEM;
1589 }
1590
1591 lock_page(page);
1592 page->index = page_idx;
1593 list_add_tail(&page->lru, pages);
1594 }
1595
1596 list_for_each_entry(page, pages, lru)
1597 f2fs_submit_page_mbio(sbi, page, page->index, META, READ);
1598
1599 f2fs_submit_merged_bio(sbi, META, true, READ);
1600 return 0;
1601}
1602
1568int restore_node_summary(struct f2fs_sb_info *sbi, 1603int restore_node_summary(struct f2fs_sb_info *sbi,
1569 unsigned int segno, struct f2fs_summary_block *sum) 1604 unsigned int segno, struct f2fs_summary_block *sum)
1570{ 1605{
1571 struct f2fs_node *rn; 1606 struct f2fs_node *rn;
1572 struct f2fs_summary *sum_entry; 1607 struct f2fs_summary *sum_entry;
1573 struct page *page; 1608 struct page *page, *tmp;
1574 block_t addr; 1609 block_t addr;
1575 int i, last_offset; 1610 int bio_blocks = MAX_BIO_BLOCKS(max_hw_blocks(sbi));
1576 1611 int i, last_offset, nrpages, err = 0;
1577 /* alloc temporal page for read node */ 1612 LIST_HEAD(page_list);
1578 page = alloc_page(GFP_NOFS | __GFP_ZERO);
1579 if (!page)
1580 return -ENOMEM;
1581 lock_page(page);
1582 1613
1583 /* scan the node segment */ 1614 /* scan the node segment */
1584 last_offset = sbi->blocks_per_seg; 1615 last_offset = sbi->blocks_per_seg;
1585 addr = START_BLOCK(sbi, segno); 1616 addr = START_BLOCK(sbi, segno);
1586 sum_entry = &sum->entries[0]; 1617 sum_entry = &sum->entries[0];
1587 1618
1588 for (i = 0; i < last_offset; i++, sum_entry++) { 1619 for (i = 0; i < last_offset; i += nrpages, addr += nrpages) {
1589 /* 1620 nrpages = min(last_offset - i, bio_blocks);
1590 * In order to read next node page,
1591 * we must clear PageUptodate flag.
1592 */
1593 ClearPageUptodate(page);
1594 1621
1595 if (f2fs_submit_page_bio(sbi, page, addr, READ_SYNC)) 1622 /* read ahead node pages */
1596 goto out; 1623 err = ra_sum_pages(sbi, &page_list, addr, nrpages);
1624 if (err)
1625 return err;
1597 1626
1598 lock_page(page); 1627 list_for_each_entry_safe(page, tmp, &page_list, lru) {
1599 rn = F2FS_NODE(page); 1628
1600 sum_entry->nid = rn->footer.nid; 1629 lock_page(page);
1601 sum_entry->version = 0; 1630 if(PageUptodate(page)) {
1602 sum_entry->ofs_in_node = 0; 1631 rn = F2FS_NODE(page);
1603 addr++; 1632 sum_entry->nid = rn->footer.nid;
1633 sum_entry->version = 0;
1634 sum_entry->ofs_in_node = 0;
1635 sum_entry++;
1636 } else {
1637 err = -EIO;
1638 }
1639
1640 list_del(&page->lru);
1641 unlock_page(page);
1642 __free_pages(page, 0);
1643 }
1604 } 1644 }
1605 unlock_page(page); 1645 return err;
1606out:
1607 __free_pages(page, 0);
1608 return 0;
1609} 1646}
1610 1647
1611static bool flush_nats_in_journal(struct f2fs_sb_info *sbi) 1648static bool flush_nats_in_journal(struct f2fs_sb_info *sbi)