diff options
author | Gary Bisson <gary.bisson@boundarydevices.com> | 2018-09-24 14:01:55 +0200 |
---|---|---|
committer | Gary Bisson <gary.bisson@boundarydevices.com> | 2018-09-24 14:01:55 +0200 |
commit | cc9333d7aace5c1de4e81932870b53bb6614dedd (patch) | |
tree | 835717abb66260b86e6116fe1e1871e1c128bf06 /fs/f2fs | |
parent | ded0ac8f40f9561d8ab2f8ef6c9ff8dc435f2b41 (diff) | |
parent | 70915e25e1cff60c32e79e5b02e9559c1ed7bab2 (diff) |
Merge tag 'v4.9.128' into 4.9-2.3.x-imx
This is the 4.9.128 stable release
Diffstat (limited to 'fs/f2fs')
-rw-r--r-- | fs/f2fs/file.c | 2 | ||||
-rw-r--r-- | fs/f2fs/gc.c | 8 | ||||
-rw-r--r-- | fs/f2fs/inline.c | 21 | ||||
-rw-r--r-- | fs/f2fs/node.c | 4 | ||||
-rw-r--r-- | fs/f2fs/segment.h | 3 | ||||
-rw-r--r-- | fs/f2fs/super.c | 21 |
6 files changed, 54 insertions, 5 deletions
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 7d0e8d6bf009..594e6e20d6dd 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1665,7 +1665,7 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg) struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct super_block *sb = sbi->sb; __u32 in; - int ret; + int ret = 0; if (!capable(CAP_SYS_ADMIN)) return -EPERM; diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index ad4dfd29d923..759056e776e5 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -877,7 +877,13 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, goto next; sum = page_address(sum_page); - f2fs_bug_on(sbi, type != GET_SUM_TYPE((&sum->footer))); + if (type != GET_SUM_TYPE((&sum->footer))) { + f2fs_msg(sbi->sb, KERN_ERR, "Inconsistent segment (%u) " + "type [%d, %d] in SSA and SIT", + segno, type, GET_SUM_TYPE((&sum->footer))); + set_sbi_flag(sbi, SBI_NEED_FSCK); + goto next; + } /* * this is to avoid deadlock: diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index a21faa1c6817..482888ee8942 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -124,6 +124,16 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page) if (err) return err; + if (unlikely(dn->data_blkaddr != NEW_ADDR)) { + f2fs_put_dnode(dn); + set_sbi_flag(fio.sbi, SBI_NEED_FSCK); + f2fs_msg(fio.sbi->sb, KERN_WARNING, + "%s: corrupted inline inode ino=%lx, i_addr[0]:0x%x, " + "run fsck to fix.", + __func__, dn->inode->i_ino, dn->data_blkaddr); + return -EINVAL; + } + f2fs_bug_on(F2FS_P_SB(page), PageWriteback(page)); read_inline_data(page, dn->inode_page); @@ -351,6 +361,17 @@ static int f2fs_move_inline_dirents(struct inode *dir, struct page *ipage, if (err) goto out; + if (unlikely(dn.data_blkaddr != NEW_ADDR)) { + f2fs_put_dnode(&dn); + set_sbi_flag(F2FS_P_SB(page), SBI_NEED_FSCK); + f2fs_msg(F2FS_P_SB(page)->sb, KERN_WARNING, + "%s: corrupted inline inode ino=%lx, i_addr[0]:0x%x, " + "run fsck to fix.", + __func__, dir->i_ino, dn.data_blkaddr); + err = -EINVAL; + goto out; + } + f2fs_wait_on_page_writeback(page, DATA, true); zero_user_segment(page, MAX_INLINE_DATA, PAGE_SIZE); diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 01177ecdeab8..addff6a3b176 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1463,7 +1463,9 @@ next_step: !is_cold_node(page))) continue; lock_node: - if (!trylock_page(page)) + if (wbc->sync_mode == WB_SYNC_ALL) + lock_page(page); + else if (!trylock_page(page)) continue; if (unlikely(page->mapping != NODE_MAPPING(sbi))) { diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index b164f8339281..3d9b9e98c4c2 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -386,6 +386,8 @@ static inline void __set_test_and_free(struct f2fs_sb_info *sbi, if (test_and_clear_bit(segno, free_i->free_segmap)) { free_i->free_segments++; + if (IS_CURSEC(sbi, secno)) + goto skip_free; next = find_next_bit(free_i->free_segmap, start_segno + sbi->segs_per_sec, start_segno); if (next >= start_segno + sbi->segs_per_sec) { @@ -393,6 +395,7 @@ static inline void __set_test_and_free(struct f2fs_sb_info *sbi, free_i->free_sections++; } } +skip_free: spin_unlock(&free_i->segmap_lock); } diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index e627671f0183..91bf72334722 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1425,12 +1425,17 @@ int sanity_check_ckpt(struct f2fs_sb_info *sbi) struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi); struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); unsigned int main_segs, blocks_per_seg; + unsigned int sit_segs, nat_segs; + unsigned int sit_bitmap_size, nat_bitmap_size; + unsigned int log_blocks_per_seg; int i; total = le32_to_cpu(raw_super->segment_count); fsmeta = le32_to_cpu(raw_super->segment_count_ckpt); - fsmeta += le32_to_cpu(raw_super->segment_count_sit); - fsmeta += le32_to_cpu(raw_super->segment_count_nat); + sit_segs = le32_to_cpu(raw_super->segment_count_sit); + fsmeta += sit_segs; + nat_segs = le32_to_cpu(raw_super->segment_count_nat); + fsmeta += nat_segs; fsmeta += le32_to_cpu(ckpt->rsvd_segment_count); fsmeta += le32_to_cpu(raw_super->segment_count_ssa); @@ -1451,6 +1456,18 @@ int sanity_check_ckpt(struct f2fs_sb_info *sbi) return 1; } + sit_bitmap_size = le32_to_cpu(ckpt->sit_ver_bitmap_bytesize); + nat_bitmap_size = le32_to_cpu(ckpt->nat_ver_bitmap_bytesize); + log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg); + + if (sit_bitmap_size != ((sit_segs / 2) << log_blocks_per_seg) / 8 || + nat_bitmap_size != ((nat_segs / 2) << log_blocks_per_seg) / 8) { + f2fs_msg(sbi->sb, KERN_ERR, + "Wrong bitmap size: sit: %u, nat:%u", + sit_bitmap_size, nat_bitmap_size); + return 1; + } + if (unlikely(f2fs_cp_error(sbi))) { f2fs_msg(sbi->sb, KERN_ERR, "A bug case: need to run fsck"); return 1; |