|
@@ -14,6 +14,7 @@
|
|
|
#include <linux/blkdev.h>
|
|
|
#include <linux/prefetch.h>
|
|
|
#include <linux/vmalloc.h>
|
|
|
+#include <linux/swap.h>
|
|
|
|
|
|
#include "f2fs.h"
|
|
|
#include "segment.h"
|
|
@@ -1706,41 +1707,89 @@ static int build_curseg(struct f2fs_sb_info *sbi)
|
|
|
return restore_curseg_summaries(sbi);
|
|
|
}
|
|
|
|
|
|
+static int ra_sit_pages(struct f2fs_sb_info *sbi, int start, int nrpages)
|
|
|
+{
|
|
|
+ struct address_space *mapping = sbi->meta_inode->i_mapping;
|
|
|
+ struct page *page;
|
|
|
+ block_t blk_addr, prev_blk_addr = 0;
|
|
|
+ int sit_blk_cnt = SIT_BLK_CNT(sbi);
|
|
|
+ int blkno = start;
|
|
|
+
|
|
|
+ for (; blkno < start + nrpages && blkno < sit_blk_cnt; blkno++) {
|
|
|
+
|
|
|
+ blk_addr = current_sit_addr(sbi, blkno * SIT_ENTRY_PER_BLOCK);
|
|
|
+
|
|
|
+ if (blkno != start && prev_blk_addr + 1 != blk_addr)
|
|
|
+ break;
|
|
|
+ prev_blk_addr = blk_addr;
|
|
|
+repeat:
|
|
|
+ page = grab_cache_page(mapping, blk_addr);
|
|
|
+ if (!page) {
|
|
|
+ cond_resched();
|
|
|
+ goto repeat;
|
|
|
+ }
|
|
|
+ if (PageUptodate(page)) {
|
|
|
+ mark_page_accessed(page);
|
|
|
+ f2fs_put_page(page, 1);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ submit_read_page(sbi, page, blk_addr, READ_SYNC);
|
|
|
+
|
|
|
+ mark_page_accessed(page);
|
|
|
+ f2fs_put_page(page, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ f2fs_submit_read_bio(sbi, READ_SYNC);
|
|
|
+ return blkno - start;
|
|
|
+}
|
|
|
+
|
|
|
static void build_sit_entries(struct f2fs_sb_info *sbi)
|
|
|
{
|
|
|
struct sit_info *sit_i = SIT_I(sbi);
|
|
|
struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
|
|
|
struct f2fs_summary_block *sum = curseg->sum_blk;
|
|
|
- unsigned int start;
|
|
|
-
|
|
|
- for (start = 0; start < TOTAL_SEGS(sbi); start++) {
|
|
|
- struct seg_entry *se = &sit_i->sentries[start];
|
|
|
- struct f2fs_sit_block *sit_blk;
|
|
|
- struct f2fs_sit_entry sit;
|
|
|
- struct page *page;
|
|
|
- int i;
|
|
|
+ int sit_blk_cnt = SIT_BLK_CNT(sbi);
|
|
|
+ unsigned int i, start, end;
|
|
|
+ unsigned int readed, start_blk = 0;
|
|
|
+ int nrpages = MAX_BIO_BLOCKS(max_hw_blocks(sbi));
|
|
|
|
|
|
- mutex_lock(&curseg->curseg_mutex);
|
|
|
- for (i = 0; i < sits_in_cursum(sum); i++) {
|
|
|
- if (le32_to_cpu(segno_in_journal(sum, i)) == start) {
|
|
|
- sit = sit_in_journal(sum, i);
|
|
|
- mutex_unlock(&curseg->curseg_mutex);
|
|
|
- goto got_it;
|
|
|
+ do {
|
|
|
+ readed = ra_sit_pages(sbi, start_blk, nrpages);
|
|
|
+
|
|
|
+ start = start_blk * sit_i->sents_per_block;
|
|
|
+ end = (start_blk + readed) * sit_i->sents_per_block;
|
|
|
+
|
|
|
+ for (; start < end && start < TOTAL_SEGS(sbi); start++) {
|
|
|
+ struct seg_entry *se = &sit_i->sentries[start];
|
|
|
+ struct f2fs_sit_block *sit_blk;
|
|
|
+ struct f2fs_sit_entry sit;
|
|
|
+ struct page *page;
|
|
|
+
|
|
|
+ mutex_lock(&curseg->curseg_mutex);
|
|
|
+ for (i = 0; i < sits_in_cursum(sum); i++) {
|
|
|
+ if (le32_to_cpu(segno_in_journal(sum, i)) == start) {
|
|
|
+ sit = sit_in_journal(sum, i);
|
|
|
+ mutex_unlock(&curseg->curseg_mutex);
|
|
|
+ goto got_it;
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- mutex_unlock(&curseg->curseg_mutex);
|
|
|
- page = get_current_sit_page(sbi, start);
|
|
|
- sit_blk = (struct f2fs_sit_block *)page_address(page);
|
|
|
- sit = sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, start)];
|
|
|
- f2fs_put_page(page, 1);
|
|
|
+ mutex_unlock(&curseg->curseg_mutex);
|
|
|
+
|
|
|
+ page = get_current_sit_page(sbi, start);
|
|
|
+ sit_blk = (struct f2fs_sit_block *)page_address(page);
|
|
|
+ sit = sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, start)];
|
|
|
+ f2fs_put_page(page, 1);
|
|
|
got_it:
|
|
|
- check_block_count(sbi, start, &sit);
|
|
|
- seg_info_from_raw_sit(se, &sit);
|
|
|
- if (sbi->segs_per_sec > 1) {
|
|
|
- struct sec_entry *e = get_sec_entry(sbi, start);
|
|
|
- e->valid_blocks += se->valid_blocks;
|
|
|
+ check_block_count(sbi, start, &sit);
|
|
|
+ seg_info_from_raw_sit(se, &sit);
|
|
|
+ if (sbi->segs_per_sec > 1) {
|
|
|
+ struct sec_entry *e = get_sec_entry(sbi, start);
|
|
|
+ e->valid_blocks += se->valid_blocks;
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
+ start_blk += readed;
|
|
|
+ } while (start_blk < sit_blk_cnt);
|
|
|
}
|
|
|
|
|
|
static void init_free_segmap(struct f2fs_sb_info *sbi)
|