aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/f2fs/segment.c101
-rw-r--r--fs/f2fs/segment.h2
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
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)
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)