mirror of
https://gitee.com/openharmony/third_party_f2fs-tools
synced 2024-11-23 10:10:00 +00:00
fsck.f2fs: update curseg .next_blkoff/.alloc_type preferential
If .next_blkoff is inconsistent, we can update curseg .next_blkoff to first unused block address, and change .alloc_type to SSR preferential, instead of move curseg to other position. This can help to repair fuzzed image which has no more free segment. Signed-off-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
9e0a58749d
commit
54244dcafd
23
fsck/fsck.c
23
fsck/fsck.c
@ -2164,6 +2164,23 @@ int check_curseg_offsets(struct f2fs_sb_info *sbi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fix_curseg_info(struct f2fs_sb_info *sbi)
|
||||
{
|
||||
int i, need_update = 0;
|
||||
|
||||
for (i = 0; i < NO_CHECK_TYPE; i++) {
|
||||
if (check_curseg_offset(sbi, i)) {
|
||||
update_curseg_info(sbi, i);
|
||||
need_update = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (need_update) {
|
||||
write_curseg_info(sbi);
|
||||
flush_curseg_sit_entries(sbi);
|
||||
}
|
||||
}
|
||||
|
||||
int check_sit_types(struct f2fs_sb_info *sbi)
|
||||
{
|
||||
unsigned int i;
|
||||
@ -2752,11 +2769,7 @@ int fsck_verify(struct f2fs_sb_info *sbi)
|
||||
fix_hard_links(sbi);
|
||||
fix_nat_entries(sbi);
|
||||
rewrite_sit_area_bitmap(sbi);
|
||||
if (check_curseg_offsets(sbi)) {
|
||||
move_curseg_info(sbi, SM_I(sbi)->main_blkaddr, 0);
|
||||
write_curseg_info(sbi);
|
||||
flush_curseg_sit_entries(sbi);
|
||||
}
|
||||
fix_curseg_info(sbi);
|
||||
fix_checksum(sbi);
|
||||
fix_checkpoint(sbi);
|
||||
} else if (is_set_ckpt_flags(cp, CP_FSCK_FLAG) ||
|
||||
|
@ -185,6 +185,7 @@ extern void f2fs_do_umount(struct f2fs_sb_info *);
|
||||
extern int f2fs_sparse_initialize_meta(struct f2fs_sb_info *);
|
||||
|
||||
extern void flush_journal_entries(struct f2fs_sb_info *);
|
||||
extern void update_curseg_info(struct f2fs_sb_info *, int);
|
||||
extern void zero_journal_entries(struct f2fs_sb_info *);
|
||||
extern void flush_sit_entries(struct f2fs_sb_info *);
|
||||
extern void move_curseg_info(struct f2fs_sb_info *, u64, int);
|
||||
|
31
fsck/mount.c
31
fsck/mount.c
@ -2159,6 +2159,30 @@ void flush_sit_entries(struct f2fs_sb_info *sbi)
|
||||
free(sit_blk);
|
||||
}
|
||||
|
||||
int relocate_curseg_offset(struct f2fs_sb_info *sbi, int type)
|
||||
{
|
||||
struct curseg_info *curseg = CURSEG_I(sbi, type);
|
||||
struct seg_entry *se = get_seg_entry(sbi, curseg->segno);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < sbi->blocks_per_seg; i++) {
|
||||
if (!f2fs_test_bit(i, (const char *)se->cur_valid_map))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == sbi->blocks_per_seg)
|
||||
return -EINVAL;
|
||||
|
||||
DBG(1, "Update curseg[%d].next_blkoff %u -> %u, alloc_type %s -> SSR\n",
|
||||
type, curseg->next_blkoff, i,
|
||||
curseg->alloc_type == LFS ? "LFS" : "SSR");
|
||||
|
||||
curseg->next_blkoff = i;
|
||||
curseg->alloc_type = SSR;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int find_next_free_block(struct f2fs_sb_info *sbi, u64 *to, int left, int type)
|
||||
{
|
||||
struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
|
||||
@ -2255,6 +2279,13 @@ void move_curseg_info(struct f2fs_sb_info *sbi, u64 from, int left)
|
||||
}
|
||||
}
|
||||
|
||||
void update_curseg_info(struct f2fs_sb_info *sbi, int type)
|
||||
{
|
||||
if (!relocate_curseg_offset(sbi, type))
|
||||
return;
|
||||
move_curseg_info(sbi, SM_I(sbi)->main_blkaddr, 0);
|
||||
}
|
||||
|
||||
void zero_journal_entries(struct f2fs_sb_info *sbi)
|
||||
{
|
||||
int i;
|
||||
|
Loading…
Reference in New Issue
Block a user