diff options
Diffstat (limited to 'fs/f2fs/gc.c')
-rw-r--r-- | fs/f2fs/gc.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 195cf0f9d9ef..963fb4571fd9 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -591,7 +591,7 @@ block_t f2fs_start_bidx_of_node(unsigned int node_ofs, struct inode *inode) int dec = (node_ofs - indirect_blks - 3) / (NIDS_PER_BLOCK + 1); bidx = node_ofs - 5 - dec; } - return bidx * ADDRS_PER_BLOCK + ADDRS_PER_INODE(inode); + return bidx * ADDRS_PER_BLOCK(inode) + ADDRS_PER_INODE(inode); } static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, @@ -656,6 +656,11 @@ static int ra_data_block(struct inode *inode, pgoff_t index) if (f2fs_lookup_extent_cache(inode, index, &ei)) { dn.data_blkaddr = ei.blk + index - ei.fofs; + if (unlikely(!f2fs_is_valid_blkaddr(sbi, dn.data_blkaddr, + DATA_GENERIC_ENHANCE_READ))) { + err = -EFAULT; + goto put_page; + } goto got_it; } @@ -665,8 +670,12 @@ static int ra_data_block(struct inode *inode, pgoff_t index) goto put_page; f2fs_put_dnode(&dn); + if (!__is_valid_data_blkaddr(dn.data_blkaddr)) { + err = -ENOENT; + goto put_page; + } if (unlikely(!f2fs_is_valid_blkaddr(sbi, dn.data_blkaddr, - DATA_GENERIC))) { + DATA_GENERIC_ENHANCE))) { err = -EFAULT; goto put_page; } @@ -1175,6 +1184,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, "type [%d, %d] in SSA and SIT", segno, type, GET_SUM_TYPE((&sum->footer))); set_sbi_flag(sbi, SBI_NEED_FSCK); + f2fs_stop_checkpoint(sbi, false); goto skip; } @@ -1346,7 +1356,7 @@ void f2fs_build_gc_manager(struct f2fs_sb_info *sbi) sbi->gc_pin_file_threshold = DEF_GC_FAILED_PINNED_FILES; /* give warm/cold data area from slower device */ - if (sbi->s_ndevs && !__is_large_section(sbi)) + if (f2fs_is_multi_device(sbi) && !__is_large_section(sbi)) SIT_I(sbi)->last_victim[ALLOC_NEXT] = GET_SEGNO(sbi, FDEV(0).end_blk) + 1; } |