aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/segment.c
diff options
context:
space:
mode:
authorChao Yu <chao2.yu@samsung.com>2013-11-21 20:09:59 -0500
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2013-12-22 20:18:02 -0500
commit74de593af77b109f202c47e090c9e134c8882869 (patch)
treef7afcd5d6ac031268442cb0b5d21a003ebcd10ee /fs/f2fs/segment.c
parentd4d288bc72c020d335868ce217695c4d5dfd74d0 (diff)
f2fs: read contiguous sit entry pages by merging for mount performance
Previously we read sit entries page one by one, this method lost the chance of reading contiguous page together. So we read pages as contiguous as possible for better mount performance. change log: o merge judgements/use 'Continue' or 'Break' instead of 'Goto' as Gu Zheng suggested. o add mark_page_accessed() before release page to delay VM reclaiming. o remove '*order' for simplification of function as Jaegeuk Kim suggested. Signed-off-by: Chao Yu <chao2.yu@samsung.com> [Jaegeuk Kim: fix a bug on the block address calculation] Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs/f2fs/segment.c')
-rw-r--r--fs/f2fs/segment.c101
1 files changed, 75 insertions, 26 deletions
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index a1acaa025bde..6dd1dc16a9d5 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -14,6 +14,7 @@
14#include <linux/blkdev.h> 14#include <linux/blkdev.h>
15#include <linux/prefetch.h> 15#include <linux/prefetch.h>
16#include <linux/vmalloc.h> 16#include <linux/vmalloc.h>
17#include <linux/swap.h>
17 18
18#include "f2fs.h" 19#include "f2fs.h"
19#include "segment.h" 20#include "segment.h"
@@ -1706,41 +1707,89 @@ static int build_curseg(struct f2fs_sb_info *sbi)
1706 return restore_curseg_summaries(sbi); 1707 return restore_curseg_summaries(sbi);
1707} 1708}
1708 1709
1710static int ra_sit_pages(struct f2fs_sb_info *sbi, int start, int nrpages)
1711{
1712 struct address_space *mapping = sbi->meta_inode->i_mapping;
1713 struct page *page;
1714 block_t blk_addr, prev_blk_addr = 0;
1715 int sit_blk_cnt = SIT_BLK_CNT(sbi);
1716 int blkno = start;
1717
1718 for (; blkno < start + nrpages && blkno < sit_blk_cnt; blkno++) {
1719
1720 blk_addr = current_sit_addr(sbi, blkno * SIT_ENTRY_PER_BLOCK);
1721
1722 if (blkno != start && prev_blk_addr + 1 != blk_addr)
1723 break;
1724 prev_blk_addr = blk_addr;
1725repeat:
1726 page = grab_cache_page(mapping, blk_addr);
1727 if (!page) {
1728 cond_resched();
1729 goto repeat;
1730 }
1731 if (PageUptodate(page)) {
1732 mark_page_accessed(page);
1733 f2fs_put_page(page, 1);
1734 continue;
1735 }
1736
1737 submit_read_page(sbi, page, blk_addr, READ_SYNC);
1738
1739 mark_page_accessed(page);
1740 f2fs_put_page(page, 0);
1741 }
1742
1743 f2fs_submit_read_bio(sbi, READ_SYNC);
1744 return blkno - start;
1745}
1746
1709static void build_sit_entries(struct f2fs_sb_info *sbi) 1747static void build_sit_entries(struct f2fs_sb_info *sbi)
1710{ 1748{
1711 struct sit_info *sit_i = SIT_I(sbi); 1749 struct sit_info *sit_i = SIT_I(sbi);
1712 struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA); 1750 struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
1713 struct f2fs_summary_block *sum = curseg->sum_blk; 1751 struct f2fs_summary_block *sum = curseg->sum_blk;
1714 unsigned int start; 1752 int sit_blk_cnt = SIT_BLK_CNT(sbi);
1715 1753 unsigned int i, start, end;
1716 for (start = 0; start < TOTAL_SEGS(sbi); start++) { 1754 unsigned int readed, start_blk = 0;
1717 struct seg_entry *se = &sit_i->sentries[start]; 1755 int nrpages = MAX_BIO_BLOCKS(max_hw_blocks(sbi));
1718 struct f2fs_sit_block *sit_blk;
1719 struct f2fs_sit_entry sit;
1720 struct page *page;
1721 int i;
1722 1756
1723 mutex_lock(&curseg->curseg_mutex); 1757 do {
1724 for (i = 0; i < sits_in_cursum(sum); i++) { 1758 readed = ra_sit_pages(sbi, start_blk, nrpages);
1725 if (le32_to_cpu(segno_in_journal(sum, i)) == start) { 1759
1726 sit = sit_in_journal(sum, i); 1760 start = start_blk * sit_i->sents_per_block;
1727 mutex_unlock(&curseg->curseg_mutex); 1761 end = (start_blk + readed) * sit_i->sents_per_block;
1728 goto got_it; 1762
1763 for (; start < end && start < TOTAL_SEGS(sbi); start++) {
1764 struct seg_entry *se = &sit_i->sentries[start];
1765 struct f2fs_sit_block *sit_blk;
1766 struct f2fs_sit_entry sit;
1767 struct page *page;
1768
1769 mutex_lock(&curseg->curseg_mutex);
1770 for (i = 0; i < sits_in_cursum(sum); i++) {
1771 if (le32_to_cpu(segno_in_journal(sum, i)) == start) {
1772 sit = sit_in_journal(sum, i);
1773 mutex_unlock(&curseg->curseg_mutex);
1774 goto got_it;
1775 }
1729 } 1776 }
1730 } 1777 mutex_unlock(&curseg->curseg_mutex);
1731 mutex_unlock(&curseg->curseg_mutex); 1778
1732 page = get_current_sit_page(sbi, start); 1779 page = get_current_sit_page(sbi, start);
1733 sit_blk = (struct f2fs_sit_block *)page_address(page); 1780 sit_blk = (struct f2fs_sit_block *)page_address(page);
1734 sit = sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, start)]; 1781 sit = sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, start)];
1735 f2fs_put_page(page, 1); 1782 f2fs_put_page(page, 1);
1736got_it: 1783got_it:
1737 check_block_count(sbi, start, &sit); 1784 check_block_count(sbi, start, &sit);
1738 seg_info_from_raw_sit(se, &sit); 1785 seg_info_from_raw_sit(se, &sit);
1739 if (sbi->segs_per_sec > 1) { 1786 if (sbi->segs_per_sec > 1) {
1740 struct sec_entry *e = get_sec_entry(sbi, start); 1787 struct sec_entry *e = get_sec_entry(sbi, start);
1741 e->valid_blocks += se->valid_blocks; 1788 e->valid_blocks += se->valid_blocks;
1789 }
1742 } 1790 }
1743 } 1791 start_blk += readed;
1792 } while (start_blk < sit_blk_cnt);
1744} 1793}
1745 1794
1746static void init_free_segmap(struct f2fs_sb_info *sbi) 1795static void init_free_segmap(struct f2fs_sb_info *sbi)