f2fs系列文章fill_super(三)

本文详述了f2fs文件系统中如何构建segment管理结构,包括分配和初始化f2fs_sm_info,建立和恢复discard_list、wait_list、sit_entry_set等链表,构建sit_info、free_segmap、curseg_info,以及恢复seg_entry和sec_entry的操作。重点讨论了build_segment_manager、build_sit_info、build_free_segmap、build_curseg等关键函数的功能及其在恢复f2fs状态中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    这篇文章完成f2fs的segment管理结构f2fs_sm_info的创建和恢复。    

    build_segment_manager:首先分配容纳f2fs_sm_info的空间,然后用f2fs_super_block中的数据对f2fs_sm_info的一些关于segment数量的信息进行初始化。接着初始化其中的三个链表discard_list、wait_list、sit_entry_set。然后调用build_sit_info构建sit_info,主要是sit_info以及管理的结构的空间的分配。接着调用build_free_segmap构建free_segmap_info,这里主要完成空间的分配,并将所有的segment和section设置为脏,其修改过程在后面再完成。然后调用build_curseg来构建各种curseg_info,并完成curren segment的恢复。接着调用build_sit_entries来恢复所有的seg_entry和sec_entry,然后调用init_free_segmap来恢复free_segmap和free_secmap,接着调用build_dirty_segmap来构建dirty_seglist_info。最后更新sit_info中的min和max的mtime。

int build_segment_manager(struct f2fs_sb_info *sbi)
{
	struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
	struct f2fs_sm_info *sm_info;
	int err;

	sm_info = kzalloc(sizeof(struct f2fs_sm_info), GFP_KERNEL);
	if (!sm_info)
		return -ENOMEM;

	sbi->sm_info = sm_info;
	sm_info->seg0_blkaddr = le32_to_cpu(raw_super->segment0_blkaddr);
	sm_info->main_blkaddr = le32_to_cpu(raw_super->main_blkaddr);
	sm_info->segment_count = le32_to_cpu(raw_super->segment_count);
	sm_info->reserved_segments = le32_to_cpu(ckpt->rsvd_segment_count);
	sm_info->ovp_segments = le32_to_cpu(ckpt->overprov_segment_count);
	sm_info->main_segments = le32_to_cpu(raw_super->segment_count_main);
	sm_info->ssa_blkaddr = le32_to_cpu(raw_super->ssa_blkaddr);
	sm_info->rec_prefree_segments = sm_info->main_segments * DEF_RECLAIM_PREFREE_SEGMENTS / 100;
	if (sm_info->rec_prefree_segments > DEF_MAX_RECLAIM_PREFREE_SEGMENTS)
		sm_info->rec_prefree_segments = DEF_MAX_RECLAIM_PREFREE_SEGMENTS;

	if (!test_opt(sbi, LFS))
		sm_info->ipu_policy = 1 << F2FS_IPU_FSYNC;
	sm_info->min_ipu_util = DEF_MIN_IPU_UTIL;
	sm_info->min_fsync_blocks = DEF_MIN_FSYNC_BLOCKS;

	INIT_LIST_HEAD(&sm_info->discard_list);
	INIT_LIST_HEAD(&sm_info->wait_list);
	sm_info->nr_discards = 0;
	sm_info->max_discards = 0;

	sm_info->trim_sections = DEF_BATCHED_TRIM_SECTIONS;

	INIT_LIST_HEAD(&sm_info->sit_entry_set);

	if (test_opt(sbi, FLUSH_MERGE) && !f2fs_readonly(sbi->sb)) {
		err = create_flush_cmd_control(sbi);
		if (err)
			return err;
	}

	err = build_sit_info(sbi);
	if (err)
		return err;
	err = build_free_segmap(sbi);
	if (err)
		return err;
	err = build_curseg(sbi);
	if (err)
		return err;

	build_sit_entries(sbi);

	init_free_segmap(sbi);
	err = build_dirty_segmap(sbi);
	if (err)
		return err;

	init_min_max_mtime(sbi);
	return 0;
}

       build_sit_info:主要完成f2fs_sm_info中的sit_info的空间的分配和其中的几个字段和位图的空间的分配,这些包括所有f2fs_sit_entry对应的内存结构seg_entry的空间、记录当前的sit位图的cur_valid_map和上次cp的sit位图的ckpt_valid_map、记录discard块的位图discard_map、临时位图tmp_map、所有section的相关信息的sec_entries。还有sit_info的一些字段的赋值。

 static int build_sit_info(struct f2fs_sb_info *sbi)

{
	struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
	struct sit_info *sit_i;
	unsigned int sit_segs, start;
	char *src_bitmap, *dst_bitmap;
	unsigned int bitmap_size;

	sit_i = kzalloc(sizeof(struct sit_info), GFP_KERNEL);
	if (!sit_i)
		return -ENOMEM;

	SM_I(sbi)->sit_info = sit_i;

	sit_i-&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值