diff options
Diffstat (limited to 'fs/f2fs/segment.h')
-rw-r--r-- | fs/f2fs/segment.h | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index 9d44ce83acb2..5e8ad4280a50 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h | |||
@@ -164,6 +164,9 @@ struct seg_entry { | |||
164 | unsigned int ckpt_valid_blocks:10; /* # of valid blocks last cp */ | 164 | unsigned int ckpt_valid_blocks:10; /* # of valid blocks last cp */ |
165 | unsigned int padding:6; /* padding */ | 165 | unsigned int padding:6; /* padding */ |
166 | unsigned char *cur_valid_map; /* validity bitmap of blocks */ | 166 | unsigned char *cur_valid_map; /* validity bitmap of blocks */ |
167 | #ifdef CONFIG_F2FS_CHECK_FS | ||
168 | unsigned char *cur_valid_map_mir; /* mirror of current valid bitmap */ | ||
169 | #endif | ||
167 | /* | 170 | /* |
168 | * # of valid blocks and the validity bitmap stored in the the last | 171 | * # of valid blocks and the validity bitmap stored in the the last |
169 | * checkpoint pack. This information is used by the SSR mode. | 172 | * checkpoint pack. This information is used by the SSR mode. |
@@ -186,9 +189,12 @@ struct segment_allocation { | |||
186 | * the page is atomically written, and it is in inmem_pages list. | 189 | * the page is atomically written, and it is in inmem_pages list. |
187 | */ | 190 | */ |
188 | #define ATOMIC_WRITTEN_PAGE ((unsigned long)-1) | 191 | #define ATOMIC_WRITTEN_PAGE ((unsigned long)-1) |
192 | #define DUMMY_WRITTEN_PAGE ((unsigned long)-2) | ||
189 | 193 | ||
190 | #define IS_ATOMIC_WRITTEN_PAGE(page) \ | 194 | #define IS_ATOMIC_WRITTEN_PAGE(page) \ |
191 | (page_private(page) == (unsigned long)ATOMIC_WRITTEN_PAGE) | 195 | (page_private(page) == (unsigned long)ATOMIC_WRITTEN_PAGE) |
196 | #define IS_DUMMY_WRITTEN_PAGE(page) \ | ||
197 | (page_private(page) == (unsigned long)DUMMY_WRITTEN_PAGE) | ||
192 | 198 | ||
193 | struct inmem_pages { | 199 | struct inmem_pages { |
194 | struct list_head list; | 200 | struct list_head list; |
@@ -203,6 +209,9 @@ struct sit_info { | |||
203 | block_t sit_blocks; /* # of blocks used by SIT area */ | 209 | block_t sit_blocks; /* # of blocks used by SIT area */ |
204 | block_t written_valid_blocks; /* # of valid blocks in main area */ | 210 | block_t written_valid_blocks; /* # of valid blocks in main area */ |
205 | char *sit_bitmap; /* SIT bitmap pointer */ | 211 | char *sit_bitmap; /* SIT bitmap pointer */ |
212 | #ifdef CONFIG_F2FS_CHECK_FS | ||
213 | char *sit_bitmap_mir; /* SIT bitmap mirror */ | ||
214 | #endif | ||
206 | unsigned int bitmap_size; /* SIT bitmap size */ | 215 | unsigned int bitmap_size; /* SIT bitmap size */ |
207 | 216 | ||
208 | unsigned long *tmp_map; /* bitmap for temporal use */ | 217 | unsigned long *tmp_map; /* bitmap for temporal use */ |
@@ -317,6 +326,9 @@ static inline void seg_info_from_raw_sit(struct seg_entry *se, | |||
317 | se->ckpt_valid_blocks = GET_SIT_VBLOCKS(rs); | 326 | se->ckpt_valid_blocks = GET_SIT_VBLOCKS(rs); |
318 | memcpy(se->cur_valid_map, rs->valid_map, SIT_VBLOCK_MAP_SIZE); | 327 | memcpy(se->cur_valid_map, rs->valid_map, SIT_VBLOCK_MAP_SIZE); |
319 | memcpy(se->ckpt_valid_map, rs->valid_map, SIT_VBLOCK_MAP_SIZE); | 328 | memcpy(se->ckpt_valid_map, rs->valid_map, SIT_VBLOCK_MAP_SIZE); |
329 | #ifdef CONFIG_F2FS_CHECK_FS | ||
330 | memcpy(se->cur_valid_map_mir, rs->valid_map, SIT_VBLOCK_MAP_SIZE); | ||
331 | #endif | ||
320 | se->type = GET_SIT_TYPE(rs); | 332 | se->type = GET_SIT_TYPE(rs); |
321 | se->mtime = le64_to_cpu(rs->mtime); | 333 | se->mtime = le64_to_cpu(rs->mtime); |
322 | } | 334 | } |
@@ -414,6 +426,12 @@ static inline void get_sit_bitmap(struct f2fs_sb_info *sbi, | |||
414 | void *dst_addr) | 426 | void *dst_addr) |
415 | { | 427 | { |
416 | struct sit_info *sit_i = SIT_I(sbi); | 428 | struct sit_info *sit_i = SIT_I(sbi); |
429 | |||
430 | #ifdef CONFIG_F2FS_CHECK_FS | ||
431 | if (memcmp(sit_i->sit_bitmap, sit_i->sit_bitmap_mir, | ||
432 | sit_i->bitmap_size)) | ||
433 | f2fs_bug_on(sbi, 1); | ||
434 | #endif | ||
417 | memcpy(dst_addr, sit_i->sit_bitmap, sit_i->bitmap_size); | 435 | memcpy(dst_addr, sit_i->sit_bitmap, sit_i->bitmap_size); |
418 | } | 436 | } |
419 | 437 | ||
@@ -634,6 +652,12 @@ static inline pgoff_t current_sit_addr(struct f2fs_sb_info *sbi, | |||
634 | 652 | ||
635 | check_seg_range(sbi, start); | 653 | check_seg_range(sbi, start); |
636 | 654 | ||
655 | #ifdef CONFIG_F2FS_CHECK_FS | ||
656 | if (f2fs_test_bit(offset, sit_i->sit_bitmap) != | ||
657 | f2fs_test_bit(offset, sit_i->sit_bitmap_mir)) | ||
658 | f2fs_bug_on(sbi, 1); | ||
659 | #endif | ||
660 | |||
637 | /* calculate sit block address */ | 661 | /* calculate sit block address */ |
638 | if (f2fs_test_bit(offset, sit_i->sit_bitmap)) | 662 | if (f2fs_test_bit(offset, sit_i->sit_bitmap)) |
639 | blk_addr += sit_i->sit_blocks; | 663 | blk_addr += sit_i->sit_blocks; |
@@ -659,6 +683,9 @@ static inline void set_to_next_sit(struct sit_info *sit_i, unsigned int start) | |||
659 | unsigned int block_off = SIT_BLOCK_OFFSET(start); | 683 | unsigned int block_off = SIT_BLOCK_OFFSET(start); |
660 | 684 | ||
661 | f2fs_change_bit(block_off, sit_i->sit_bitmap); | 685 | f2fs_change_bit(block_off, sit_i->sit_bitmap); |
686 | #ifdef CONFIG_F2FS_CHECK_FS | ||
687 | f2fs_change_bit(block_off, sit_i->sit_bitmap_mir); | ||
688 | #endif | ||
662 | } | 689 | } |
663 | 690 | ||
664 | static inline unsigned long long get_mtime(struct f2fs_sb_info *sbi) | 691 | static inline unsigned long long get_mtime(struct f2fs_sb_info *sbi) |
@@ -689,6 +716,15 @@ static inline block_t sum_blk_addr(struct f2fs_sb_info *sbi, int base, int type) | |||
689 | - (base + 1) + type; | 716 | - (base + 1) + type; |
690 | } | 717 | } |
691 | 718 | ||
719 | static inline bool no_fggc_candidate(struct f2fs_sb_info *sbi, | ||
720 | unsigned int secno) | ||
721 | { | ||
722 | if (get_valid_blocks(sbi, secno, sbi->segs_per_sec) >= | ||
723 | sbi->fggc_threshold) | ||
724 | return true; | ||
725 | return false; | ||
726 | } | ||
727 | |||
692 | static inline bool sec_usage_check(struct f2fs_sb_info *sbi, unsigned int secno) | 728 | static inline bool sec_usage_check(struct f2fs_sb_info *sbi, unsigned int secno) |
693 | { | 729 | { |
694 | if (IS_CURSEC(sbi, secno) || (sbi->cur_victim_sec == secno)) | 730 | if (IS_CURSEC(sbi, secno) || (sbi->cur_victim_sec == secno)) |
@@ -700,8 +736,8 @@ static inline bool sec_usage_check(struct f2fs_sb_info *sbi, unsigned int secno) | |||
700 | * It is very important to gather dirty pages and write at once, so that we can | 736 | * It is very important to gather dirty pages and write at once, so that we can |
701 | * submit a big bio without interfering other data writes. | 737 | * submit a big bio without interfering other data writes. |
702 | * By default, 512 pages for directory data, | 738 | * By default, 512 pages for directory data, |
703 | * 512 pages (2MB) * 3 for three types of nodes, and | 739 | * 512 pages (2MB) * 8 for nodes, and |
704 | * max_bio_blocks for meta are set. | 740 | * 256 pages * 8 for meta are set. |
705 | */ | 741 | */ |
706 | static inline int nr_pages_to_skip(struct f2fs_sb_info *sbi, int type) | 742 | static inline int nr_pages_to_skip(struct f2fs_sb_info *sbi, int type) |
707 | { | 743 | { |