diff options
-rw-r--r-- | fs/f2fs/segment.c | 101 | ||||
-rw-r--r-- | fs/f2fs/segment.h | 2 |
2 files changed, 77 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 | ||
1710 | static 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; | ||
1725 | repeat: | ||
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 | |||
1709 | static void build_sit_entries(struct f2fs_sb_info *sbi) | 1747 | static 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); |
1736 | got_it: | 1783 | got_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 | ||
1746 | static void init_free_segmap(struct f2fs_sb_info *sbi) | 1795 | static void init_free_segmap(struct f2fs_sb_info *sbi) |
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index 38f6196493ff..b84dd2396665 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h | |||
@@ -78,6 +78,8 @@ | |||
78 | (segno / SIT_ENTRY_PER_BLOCK) | 78 | (segno / SIT_ENTRY_PER_BLOCK) |
79 | #define START_SEGNO(sit_i, segno) \ | 79 | #define START_SEGNO(sit_i, segno) \ |
80 | (SIT_BLOCK_OFFSET(sit_i, segno) * SIT_ENTRY_PER_BLOCK) | 80 | (SIT_BLOCK_OFFSET(sit_i, segno) * SIT_ENTRY_PER_BLOCK) |
81 | #define SIT_BLK_CNT(sbi) \ | ||
82 | ((TOTAL_SEGS(sbi) + SIT_ENTRY_PER_BLOCK - 1) / SIT_ENTRY_PER_BLOCK) | ||
81 | #define f2fs_bitmap_size(nr) \ | 83 | #define f2fs_bitmap_size(nr) \ |
82 | (BITS_TO_LONGS(nr) * sizeof(unsigned long)) | 84 | (BITS_TO_LONGS(nr) * sizeof(unsigned long)) |
83 | #define TOTAL_SEGS(sbi) (SM_I(sbi)->main_segments) | 85 | #define TOTAL_SEGS(sbi) (SM_I(sbi)->main_segments) |