mirror of
https://gitee.com/openharmony/third_party_f2fs-tools
synced 2024-11-23 10:10:00 +00:00
fsck.f2fs: check next block is free or not
If block allocation is made to the next block offset, we should drop that block. Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
b700e313b4
commit
a6b2870ddb
19
fsck/f2fs.h
19
fsck/f2fs.h
@ -266,10 +266,15 @@ static inline block_t __start_sum_addr(struct f2fs_sb_info *sbi)
|
|||||||
#define GET_SEGNO_FROM_SEG0(sbi, blk_addr) \
|
#define GET_SEGNO_FROM_SEG0(sbi, blk_addr) \
|
||||||
(GET_SEGOFF_FROM_SEG0(sbi, blk_addr) >> sbi->log_blocks_per_seg)
|
(GET_SEGOFF_FROM_SEG0(sbi, blk_addr) >> sbi->log_blocks_per_seg)
|
||||||
|
|
||||||
#define FREE_I_START_SEGNO(sbi) GET_SEGNO_FROM_SEG0(sbi, SM_I(sbi)->main_blkaddr)
|
#define GET_BLKOFF_FROM_SEG0(sbi, blk_addr) \
|
||||||
|
(GET_SEGOFF_FROM_SEG0(sbi, blk_addr) & (sbi->blocks_per_seg - 1))
|
||||||
|
|
||||||
|
#define FREE_I_START_SEGNO(sbi) \
|
||||||
|
GET_SEGNO_FROM_SEG0(sbi, SM_I(sbi)->main_blkaddr)
|
||||||
#define GET_R2L_SEGNO(sbi, segno) (segno + FREE_I_START_SEGNO(sbi))
|
#define GET_R2L_SEGNO(sbi, segno) (segno + FREE_I_START_SEGNO(sbi))
|
||||||
|
|
||||||
#define START_BLOCK(sbi, segno) (SM_I(sbi)->main_blkaddr + (segno << sbi->log_blocks_per_seg))
|
#define START_BLOCK(sbi, segno) (SM_I(sbi)->main_blkaddr + \
|
||||||
|
(segno << sbi->log_blocks_per_seg))
|
||||||
|
|
||||||
static inline struct curseg_info *CURSEG_I(struct f2fs_sb_info *sbi, int type)
|
static inline struct curseg_info *CURSEG_I(struct f2fs_sb_info *sbi, int type)
|
||||||
{
|
{
|
||||||
@ -311,6 +316,8 @@ static inline bool IS_VALID_NID(struct f2fs_sb_info *sbi, u32 nid)
|
|||||||
|
|
||||||
static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info *sbi, u32 addr)
|
static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info *sbi, u32 addr)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
if (addr >= F2FS_RAW_SUPER(sbi)->block_count ||
|
if (addr >= F2FS_RAW_SUPER(sbi)->block_count ||
|
||||||
addr < SM_I(sbi)->main_blkaddr) {
|
addr < SM_I(sbi)->main_blkaddr) {
|
||||||
DBG(0, "block addr [0x%x]\n", addr);
|
DBG(0, "block addr [0x%x]\n", addr);
|
||||||
@ -318,6 +325,14 @@ static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info *sbi, u32 addr)
|
|||||||
ASSERT(addr >= SM_I(sbi)->main_blkaddr);
|
ASSERT(addr >= SM_I(sbi)->main_blkaddr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < NO_CHECK_TYPE; i++) {
|
||||||
|
struct curseg_info *curseg = CURSEG_I(sbi, i);
|
||||||
|
|
||||||
|
if (START_BLOCK(sbi, curseg->segno) +
|
||||||
|
curseg->next_blkoff == addr)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
27
fsck/fsck.c
27
fsck/fsck.c
@ -843,6 +843,24 @@ static void fix_checkpoint(struct f2fs_sb_info *sbi)
|
|||||||
ASSERT(ret >= 0);
|
ASSERT(ret >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int check_curseg_offset(struct f2fs_sb_info *sbi)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < NO_CHECK_TYPE; i++) {
|
||||||
|
struct curseg_info *curseg = CURSEG_I(sbi, i);
|
||||||
|
struct seg_entry *se;
|
||||||
|
|
||||||
|
se = get_seg_entry(sbi, curseg->segno);
|
||||||
|
if (f2fs_test_bit(curseg->next_blkoff,
|
||||||
|
(const char *)se->cur_valid_map) == 1) {
|
||||||
|
ASSERT_MSG("Next block offset is not free, type:%d", i);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int fsck_verify(struct f2fs_sb_info *sbi)
|
int fsck_verify(struct f2fs_sb_info *sbi)
|
||||||
{
|
{
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
@ -944,6 +962,15 @@ int fsck_verify(struct f2fs_sb_info *sbi)
|
|||||||
config.bug_on = 1;
|
config.bug_on = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("[FSCK] next block offset is free ");
|
||||||
|
if (check_curseg_offset(sbi) == 0) {
|
||||||
|
printf(" [Ok..]\n");
|
||||||
|
} else {
|
||||||
|
printf(" [Fail]\n");
|
||||||
|
ret = EXIT_ERR_CODE;
|
||||||
|
config.bug_on = 1;
|
||||||
|
}
|
||||||
|
|
||||||
printf("[FSCK] other corrupted bugs ");
|
printf("[FSCK] other corrupted bugs ");
|
||||||
if (config.bug_on == 0) {
|
if (config.bug_on == 0) {
|
||||||
printf(" [Ok..]\n");
|
printf(" [Ok..]\n");
|
||||||
|
46
fsck/mount.c
46
fsck/mount.c
@ -505,11 +505,6 @@ void reset_curseg(struct f2fs_sb_info *sbi, int type)
|
|||||||
struct summary_footer *sum_footer;
|
struct summary_footer *sum_footer;
|
||||||
struct seg_entry *se;
|
struct seg_entry *se;
|
||||||
|
|
||||||
curseg->segno = curseg->next_segno;
|
|
||||||
curseg->zone = GET_ZONENO_FROM_SEGNO(sbi, curseg->segno);
|
|
||||||
curseg->next_blkoff = 0;
|
|
||||||
curseg->next_segno = NULL_SEGNO;
|
|
||||||
|
|
||||||
sum_footer = &(curseg->sum_blk->footer);
|
sum_footer = &(curseg->sum_blk->footer);
|
||||||
memset(sum_footer, 0, sizeof(struct summary_footer));
|
memset(sum_footer, 0, sizeof(struct summary_footer));
|
||||||
if (IS_DATASEG(type))
|
if (IS_DATASEG(type))
|
||||||
@ -522,7 +517,6 @@ void reset_curseg(struct f2fs_sb_info *sbi, int type)
|
|||||||
|
|
||||||
static void read_compacted_summaries(struct f2fs_sb_info *sbi)
|
static void read_compacted_summaries(struct f2fs_sb_info *sbi)
|
||||||
{
|
{
|
||||||
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
|
|
||||||
struct curseg_info *curseg;
|
struct curseg_info *curseg;
|
||||||
unsigned int i, j, offset;
|
unsigned int i, j, offset;
|
||||||
block_t start;
|
block_t start;
|
||||||
@ -545,18 +539,14 @@ static void read_compacted_summaries(struct f2fs_sb_info *sbi)
|
|||||||
offset = 2 * SUM_JOURNAL_SIZE;
|
offset = 2 * SUM_JOURNAL_SIZE;
|
||||||
for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
|
for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
|
||||||
unsigned short blk_off;
|
unsigned short blk_off;
|
||||||
unsigned int segno;
|
struct curseg_info *curseg = CURSEG_I(sbi, i);
|
||||||
|
|
||||||
curseg = CURSEG_I(sbi, i);
|
|
||||||
segno = le32_to_cpu(ckpt->cur_data_segno[i]);
|
|
||||||
blk_off = le16_to_cpu(ckpt->cur_data_blkoff[i]);
|
|
||||||
curseg->next_segno = segno;
|
|
||||||
reset_curseg(sbi, i);
|
reset_curseg(sbi, i);
|
||||||
curseg->alloc_type = ckpt->alloc_type[i];
|
|
||||||
curseg->next_blkoff = blk_off;
|
|
||||||
|
|
||||||
if (curseg->alloc_type == SSR)
|
if (curseg->alloc_type == SSR)
|
||||||
blk_off = sbi->blocks_per_seg;
|
blk_off = sbi->blocks_per_seg;
|
||||||
|
else
|
||||||
|
blk_off = curseg->next_blkoff;
|
||||||
|
|
||||||
for (j = 0; j < blk_off; j++) {
|
for (j = 0; j < blk_off; j++) {
|
||||||
struct f2fs_summary *s;
|
struct f2fs_summary *s;
|
||||||
@ -605,16 +595,12 @@ static void read_normal_summaries(struct f2fs_sb_info *sbi, int type)
|
|||||||
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
|
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
|
||||||
struct f2fs_summary_block *sum_blk;
|
struct f2fs_summary_block *sum_blk;
|
||||||
struct curseg_info *curseg;
|
struct curseg_info *curseg;
|
||||||
unsigned short blk_off;
|
|
||||||
unsigned int segno = 0;
|
unsigned int segno = 0;
|
||||||
block_t blk_addr = 0;
|
block_t blk_addr = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (IS_DATASEG(type)) {
|
if (IS_DATASEG(type)) {
|
||||||
segno = le32_to_cpu(ckpt->cur_data_segno[type]);
|
segno = le32_to_cpu(ckpt->cur_data_segno[type]);
|
||||||
blk_off = le16_to_cpu(ckpt->cur_data_blkoff[type -
|
|
||||||
CURSEG_HOT_DATA]);
|
|
||||||
|
|
||||||
if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG))
|
if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG))
|
||||||
blk_addr = sum_blk_addr(sbi, NR_CURSEG_TYPE, type);
|
blk_addr = sum_blk_addr(sbi, NR_CURSEG_TYPE, type);
|
||||||
else
|
else
|
||||||
@ -622,9 +608,6 @@ static void read_normal_summaries(struct f2fs_sb_info *sbi, int type)
|
|||||||
} else {
|
} else {
|
||||||
segno = le32_to_cpu(ckpt->cur_node_segno[type -
|
segno = le32_to_cpu(ckpt->cur_node_segno[type -
|
||||||
CURSEG_HOT_NODE]);
|
CURSEG_HOT_NODE]);
|
||||||
blk_off = le16_to_cpu(ckpt->cur_node_blkoff[type -
|
|
||||||
CURSEG_HOT_NODE]);
|
|
||||||
|
|
||||||
if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG))
|
if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG))
|
||||||
blk_addr = sum_blk_addr(sbi, NR_CURSEG_NODE_TYPE,
|
blk_addr = sum_blk_addr(sbi, NR_CURSEG_NODE_TYPE,
|
||||||
type - CURSEG_HOT_NODE);
|
type - CURSEG_HOT_NODE);
|
||||||
@ -641,10 +624,7 @@ static void read_normal_summaries(struct f2fs_sb_info *sbi, int type)
|
|||||||
|
|
||||||
curseg = CURSEG_I(sbi, type);
|
curseg = CURSEG_I(sbi, type);
|
||||||
memcpy(curseg->sum_blk, sum_blk, PAGE_CACHE_SIZE);
|
memcpy(curseg->sum_blk, sum_blk, PAGE_CACHE_SIZE);
|
||||||
curseg->next_segno = segno;
|
|
||||||
reset_curseg(sbi, type);
|
reset_curseg(sbi, type);
|
||||||
curseg->alloc_type = ckpt->alloc_type[type];
|
|
||||||
curseg->next_blkoff = blk_off;
|
|
||||||
free(sum_blk);
|
free(sum_blk);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -663,7 +643,10 @@ static void restore_curseg_summaries(struct f2fs_sb_info *sbi)
|
|||||||
|
|
||||||
static void build_curseg(struct f2fs_sb_info *sbi)
|
static void build_curseg(struct f2fs_sb_info *sbi)
|
||||||
{
|
{
|
||||||
|
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
|
||||||
struct curseg_info *array;
|
struct curseg_info *array;
|
||||||
|
unsigned short blk_off;
|
||||||
|
unsigned int segno;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
array = malloc(sizeof(*array) * NR_CURSEG_TYPE);
|
array = malloc(sizeof(*array) * NR_CURSEG_TYPE);
|
||||||
@ -674,8 +657,21 @@ static void build_curseg(struct f2fs_sb_info *sbi)
|
|||||||
for (i = 0; i < NR_CURSEG_TYPE; i++) {
|
for (i = 0; i < NR_CURSEG_TYPE; i++) {
|
||||||
array[i].sum_blk = malloc(PAGE_CACHE_SIZE);
|
array[i].sum_blk = malloc(PAGE_CACHE_SIZE);
|
||||||
ASSERT(array[i].sum_blk);
|
ASSERT(array[i].sum_blk);
|
||||||
array[i].segno = NULL_SEGNO;
|
if (i <= CURSEG_COLD_DATA) {
|
||||||
array[i].next_blkoff = 0;
|
blk_off = le16_to_cpu(ckpt->cur_data_blkoff[i]);
|
||||||
|
segno = le32_to_cpu(ckpt->cur_data_segno[i]);
|
||||||
|
}
|
||||||
|
if (i > CURSEG_COLD_DATA) {
|
||||||
|
blk_off = le16_to_cpu(ckpt->cur_node_blkoff[i -
|
||||||
|
CURSEG_HOT_NODE]);
|
||||||
|
segno = le32_to_cpu(ckpt->cur_node_segno[i -
|
||||||
|
CURSEG_HOT_NODE]);
|
||||||
|
}
|
||||||
|
array[i].segno = segno;
|
||||||
|
array[i].zone = GET_ZONENO_FROM_SEGNO(sbi, segno);
|
||||||
|
array[i].next_segno = NULL_SEGNO;
|
||||||
|
array[i].next_blkoff = blk_off;
|
||||||
|
array[i].alloc_type = ckpt->alloc_type[i];
|
||||||
}
|
}
|
||||||
restore_curseg_summaries(sbi);
|
restore_curseg_summaries(sbi);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user