fsck.f2fs: large volume support

This patch support large volume over about 3TB.

Signed-off-by: Changman Lee <cm224.lee@samsung.com>
[Jaegeuk Kim: add missing cp_payload in f2fs_super_block]
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
Changman Lee 2014-05-12 22:03:46 +09:00 committed by Jaegeuk Kim
parent 03ca33c407
commit 4ea4f1db27
5 changed files with 39 additions and 9 deletions

View File

@ -203,9 +203,17 @@ static inline unsigned long __bitmap_size(struct f2fs_sb_info *sbi, int flag)
static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag) static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag)
{ {
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
int offset = (flag == NAT_BITMAP) ? int offset;
if (le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload) > 0) {
if (flag == NAT_BITMAP)
return &ckpt->sit_nat_version_bitmap;
else
return ((char *)ckpt + F2FS_BLKSIZE);
} else {
offset = (flag == NAT_BITMAP) ?
le32_to_cpu(ckpt->sit_ver_bitmap_bytesize) : 0; le32_to_cpu(ckpt->sit_ver_bitmap_bytesize) : 0;
return &ckpt->sit_nat_version_bitmap + offset; return &ckpt->sit_nat_version_bitmap + offset;
}
} }
static inline bool is_set_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f) static inline bool is_set_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f)

View File

@ -644,11 +644,14 @@ int fsck_chk_orphan_node(struct f2fs_sb_info *sbi)
block_t start_blk, orphan_blkaddr, i, j; block_t start_blk, orphan_blkaddr, i, j;
struct f2fs_orphan_block *orphan_blk; struct f2fs_orphan_block *orphan_blk;
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
if (!is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ORPHAN_PRESENT_FLAG)) if (!is_set_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG))
return 0; return 0;
start_blk = __start_cp_addr(sbi) + 1; start_blk = __start_cp_addr(sbi) + 1 +
le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload);
orphan_blkaddr = __start_sum_addr(sbi) - 1; orphan_blkaddr = __start_sum_addr(sbi) - 1;
orphan_blk = calloc(BLOCK_SZ, 1); orphan_blk = calloc(BLOCK_SZ, 1);

View File

@ -129,6 +129,7 @@ void print_raw_sb_info(struct f2fs_sb_info *sbi)
DISP_u32(sb, root_ino); DISP_u32(sb, root_ino);
DISP_u32(sb, node_ino); DISP_u32(sb, node_ino);
DISP_u32(sb, meta_ino); DISP_u32(sb, meta_ino);
DISP_u32(sb, cp_payload);
printf("\n"); printf("\n");
} }
@ -285,6 +286,7 @@ void *validate_checkpoint(struct f2fs_sb_info *sbi, block_t cp_addr, unsigned lo
/* Read the 2nd cp block in this CP pack */ /* Read the 2nd cp block in this CP pack */
cp_page_2 = malloc(PAGE_SIZE); cp_page_2 = malloc(PAGE_SIZE);
cp_addr += le32_to_cpu(cp_block->cp_pack_total_block_count) - 1; cp_addr += le32_to_cpu(cp_block->cp_pack_total_block_count) - 1;
if (dev_read_block(cp_page_2, cp_addr) < 0) if (dev_read_block(cp_page_2, cp_addr) < 0)
goto invalid_cp2; goto invalid_cp2;
@ -295,7 +297,7 @@ void *validate_checkpoint(struct f2fs_sb_info *sbi, block_t cp_addr, unsigned lo
crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset); crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset);
if (f2fs_crc_valid(crc, cp_block, crc_offset)) if (f2fs_crc_valid(crc, cp_block, crc_offset))
goto invalid_cp1; goto invalid_cp2;
cur_version = le64_to_cpu(cp_block->checkpoint_ver); cur_version = le64_to_cpu(cp_block->checkpoint_ver);
@ -319,8 +321,9 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi)
unsigned long blk_size = sbi->blocksize; unsigned long blk_size = sbi->blocksize;
unsigned long long cp1_version = 0, cp2_version = 0; unsigned long long cp1_version = 0, cp2_version = 0;
unsigned long long cp_start_blk_no; unsigned long long cp_start_blk_no;
unsigned int cp_blks = 1 + le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload);
sbi->ckpt = malloc(blk_size); sbi->ckpt = malloc(cp_blks * blk_size);
if (!sbi->ckpt) if (!sbi->ckpt)
return -ENOMEM; return -ENOMEM;
/* /*
@ -351,6 +354,20 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi)
memcpy(sbi->ckpt, cur_page, blk_size); memcpy(sbi->ckpt, cur_page, blk_size);
if (cp_blks > 1) {
int i;
unsigned long long cp_blk_no;
cp_blk_no = le32_to_cpu(raw_sb->cp_blkaddr);
if (cur_page == cp2)
cp_blk_no += 1 << le32_to_cpu(raw_sb->log_blocks_per_seg);
/* copy sit bitmap */
for (i = 1; i < cp_blks; i++) {
unsigned char *ckpt = (unsigned char *)sbi->ckpt;
dev_read_block(cur_page, cp_blk_no + i);
memcpy(ckpt + i * blk_size, cur_page, blk_size);
}
}
free(cp1); free(cp1);
free(cp2); free(cp2);
return 0; return 0;
@ -697,6 +714,7 @@ void check_block_count(struct f2fs_sb_info *sbi,
int valid_blocks = 0; int valid_blocks = 0;
unsigned int i; unsigned int i;
/* check segment usage */ /* check segment usage */
ASSERT(GET_SIT_VBLOCKS(raw_sit) <= sbi->blocks_per_seg); ASSERT(GET_SIT_VBLOCKS(raw_sit) <= sbi->blocks_per_seg);

View File

@ -277,6 +277,7 @@ struct f2fs_super_block {
__le16 volume_name[512]; /* volume name */ __le16 volume_name[512]; /* volume name */
__le32 extension_count; /* # of extensions below */ __le32 extension_count; /* # of extensions below */
__u8 extension_list[F2FS_MAX_EXTENSION][8]; /* extension array */ __u8 extension_list[F2FS_MAX_EXTENSION][8]; /* extension array */
__le32 cp_payload;
} __attribute__((packed)); } __attribute__((packed));
/* /*

View File

@ -341,8 +341,8 @@ int f2fs_crc_valid(u_int32_t blk_crc, void *buf, int len)
cal_crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, buf, len); cal_crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, buf, len);
if (cal_crc != blk_crc) { if (cal_crc != blk_crc) {
DBG(0,"CRC validation failed: cal_crc = %u \ DBG(0,"CRC validation failed: cal_crc = %u, "
blk_crc = %u buff_size = 0x%x", "blk_crc = %u buff_size = 0x%x\n",
cal_crc, blk_crc, len); cal_crc, blk_crc, len);
return -1; return -1;
} }