f2fs: large volume support
f2fs's cp has one page which consists of struct f2fs_checkpoint and version bitmap of sit and nat. To support lots of segments, we need more blocks for sit bitmap. So let's arrange sit bitmap as following: +-----------------+------------+ | f2fs_checkpoint | sit bitmap | | + nat bitmap | | +-----------------+------------+ 0 4k N blocks Signed-off-by: Changman Lee <cm224.lee@samsung.com> [Jaegeuk Kim: simple code change for readability] Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
bac4eef653
commit
1dbe415216
|
@ -371,7 +371,9 @@ void recover_orphan_inodes(struct f2fs_sb_info *sbi)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sbi->por_doing = true;
|
sbi->por_doing = true;
|
||||||
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;
|
||||||
|
|
||||||
ra_meta_pages(sbi, start_blk, orphan_blkaddr, META_CP);
|
ra_meta_pages(sbi, start_blk, orphan_blkaddr, META_CP);
|
||||||
|
@ -512,8 +514,11 @@ 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);
|
||||||
|
block_t cp_blk_no;
|
||||||
|
int i;
|
||||||
|
|
||||||
sbi->ckpt = kzalloc(blk_size, GFP_KERNEL);
|
sbi->ckpt = kzalloc(cp_blks * blk_size, GFP_KERNEL);
|
||||||
if (!sbi->ckpt)
|
if (!sbi->ckpt)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
/*
|
/*
|
||||||
|
@ -544,6 +549,23 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi)
|
||||||
cp_block = (struct f2fs_checkpoint *)page_address(cur_page);
|
cp_block = (struct f2fs_checkpoint *)page_address(cur_page);
|
||||||
memcpy(sbi->ckpt, cp_block, blk_size);
|
memcpy(sbi->ckpt, cp_block, blk_size);
|
||||||
|
|
||||||
|
if (cp_blks <= 1)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
cp_blk_no = le32_to_cpu(fsb->cp_blkaddr);
|
||||||
|
if (cur_page == cp2)
|
||||||
|
cp_blk_no += 1 << le32_to_cpu(fsb->log_blocks_per_seg);
|
||||||
|
|
||||||
|
for (i = 1; i < cp_blks; i++) {
|
||||||
|
void *sit_bitmap_ptr;
|
||||||
|
unsigned char *ckpt = (unsigned char *)sbi->ckpt;
|
||||||
|
|
||||||
|
cur_page = get_meta_page(sbi, cp_blk_no + i);
|
||||||
|
sit_bitmap_ptr = page_address(cur_page);
|
||||||
|
memcpy(ckpt + i * blk_size, sit_bitmap_ptr, blk_size);
|
||||||
|
f2fs_put_page(cur_page, 1);
|
||||||
|
}
|
||||||
|
done:
|
||||||
f2fs_put_page(cp1, 1);
|
f2fs_put_page(cp1, 1);
|
||||||
f2fs_put_page(cp2, 1);
|
f2fs_put_page(cp2, 1);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -736,6 +758,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
|
||||||
__u32 crc32 = 0;
|
__u32 crc32 = 0;
|
||||||
void *kaddr;
|
void *kaddr;
|
||||||
int i;
|
int i;
|
||||||
|
int cp_payload_blks = le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This avoids to conduct wrong roll-forward operations and uses
|
* This avoids to conduct wrong roll-forward operations and uses
|
||||||
|
@ -786,16 +809,19 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
|
||||||
|
|
||||||
orphan_blocks = (sbi->n_orphans + F2FS_ORPHANS_PER_BLOCK - 1)
|
orphan_blocks = (sbi->n_orphans + F2FS_ORPHANS_PER_BLOCK - 1)
|
||||||
/ F2FS_ORPHANS_PER_BLOCK;
|
/ F2FS_ORPHANS_PER_BLOCK;
|
||||||
ckpt->cp_pack_start_sum = cpu_to_le32(1 + orphan_blocks);
|
ckpt->cp_pack_start_sum = cpu_to_le32(1 + cp_payload_blks +
|
||||||
|
orphan_blocks);
|
||||||
|
|
||||||
if (is_umount) {
|
if (is_umount) {
|
||||||
set_ckpt_flags(ckpt, CP_UMOUNT_FLAG);
|
set_ckpt_flags(ckpt, CP_UMOUNT_FLAG);
|
||||||
ckpt->cp_pack_total_block_count = cpu_to_le32(2 +
|
ckpt->cp_pack_total_block_count = cpu_to_le32(2 +
|
||||||
data_sum_blocks + orphan_blocks + NR_CURSEG_NODE_TYPE);
|
cp_payload_blks + data_sum_blocks +
|
||||||
|
orphan_blocks + NR_CURSEG_NODE_TYPE);
|
||||||
} else {
|
} else {
|
||||||
clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG);
|
clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG);
|
||||||
ckpt->cp_pack_total_block_count = cpu_to_le32(2 +
|
ckpt->cp_pack_total_block_count = cpu_to_le32(2 +
|
||||||
data_sum_blocks + orphan_blocks);
|
cp_payload_blks + data_sum_blocks +
|
||||||
|
orphan_blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sbi->n_orphans)
|
if (sbi->n_orphans)
|
||||||
|
@ -821,6 +847,15 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
|
||||||
set_page_dirty(cp_page);
|
set_page_dirty(cp_page);
|
||||||
f2fs_put_page(cp_page, 1);
|
f2fs_put_page(cp_page, 1);
|
||||||
|
|
||||||
|
for (i = 1; i < 1 + cp_payload_blks; i++) {
|
||||||
|
cp_page = grab_meta_page(sbi, start_blk++);
|
||||||
|
kaddr = page_address(cp_page);
|
||||||
|
memcpy(kaddr, (char *)ckpt + i * F2FS_BLKSIZE,
|
||||||
|
(1 << sbi->log_blocksize));
|
||||||
|
set_page_dirty(cp_page);
|
||||||
|
f2fs_put_page(cp_page, 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (sbi->n_orphans) {
|
if (sbi->n_orphans) {
|
||||||
write_orphan_inodes(sbi, start_blk);
|
write_orphan_inodes(sbi, start_blk);
|
||||||
start_blk += orphan_blocks;
|
start_blk += orphan_blocks;
|
||||||
|
|
|
@ -764,9 +764,18 @@ 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 ((unsigned 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 block_t __start_cp_addr(struct f2fs_sb_info *sbi)
|
static inline block_t __start_cp_addr(struct f2fs_sb_info *sbi)
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#define F2FS_LOG_SECTORS_PER_BLOCK 3 /* 4KB: F2FS_BLKSIZE */
|
#define F2FS_LOG_SECTORS_PER_BLOCK 3 /* 4KB: F2FS_BLKSIZE */
|
||||||
#define F2FS_BLKSIZE 4096 /* support only 4KB block */
|
#define F2FS_BLKSIZE 4096 /* support only 4KB block */
|
||||||
#define F2FS_MAX_EXTENSION 64 /* # of extension entries */
|
#define F2FS_MAX_EXTENSION 64 /* # of extension entries */
|
||||||
|
#define F2FS_BLK_ALIGN(x) (((x) + F2FS_BLKSIZE - 1) / F2FS_BLKSIZE)
|
||||||
|
|
||||||
#define NULL_ADDR ((block_t)0) /* used as block_t addresses */
|
#define NULL_ADDR ((block_t)0) /* used as block_t addresses */
|
||||||
#define NEW_ADDR ((block_t)-1) /* used as block_t addresses */
|
#define NEW_ADDR ((block_t)-1) /* used as block_t addresses */
|
||||||
|
@ -75,6 +76,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;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue