Checkpoint维护了f2fs的数据一致性,例如segment、node、active segment的状态等。

F2FS在满足一定的条件的情况下,会将当前系统的分配状态写入到Checkpoint中,万一系统出现突然宕机,可以从Checkpoint中恢复到上次回写时的状态。

F2FS维护了两个Checkpoint结构,其中一个是当前正在使用的Checkpoint。另外一个上次回写的稳定的cp。

如果系统出现了宕机,就恢复到上次的稳定cp中。

CP的盘上结构

CP占用2个segment大小(4M)。

有资料说CP区域就是两个struct f2fs_checkpoint。但是还有资料说还包含orphan node和active segments。

暂且认为盘上的cp区域由两套f2fs_checkpoint+orphan node+active segment组成。

F2FS使用数据结构f2fs_checkpoint表示Checkpoint结构,它保存在磁盘中f2fs_super_block之后区域中,数据结构如下。

需要特别注意的是cur_node_segnocur_node_blkoffcur_data_segnocur_data_blkoff

struct f2fs_checkpoint {
	__le64 checkpoint_ver;		/* CP版本,用于比较新旧版本进行恢复 */
	__le64 user_block_count;	/* # of user blocks */
	__le64 valid_block_count;	/* # of valid blocks in main area */
	__le32 rsvd_segment_count;	/* # of reserved segments for gc */
	__le32 overprov_segment_count;	/* # of overprovision segments */
	__le32 free_segment_count;	/* # of free segments in main area */

	/* information of current node segments */
	__le32 cur_node_segno[MAX_ACTIVE_NODE_LOGS];
	__le16 cur_node_blkoff[MAX_ACTIVE_NODE_LOGS];
	/* information of current data segments */
	__le32 cur_data_segno[MAX_ACTIVE_DATA_LOGS];
	__le16 cur_data_blkoff[MAX_ACTIVE_DATA_LOGS];
	
	__le32 ckpt_flags;		/* Flags : umount and journal_present */
	__le32 cp_pack_total_block_count;	/* total # of one cp pack */
	__le32 cp_pack_start_sum;	/* start block number of data summary */
	__le32 valid_node_count;	/* Total number of valid nodes */
	__le32 valid_inode_count;	/* Total number of valid inodes */
	__le32 next_free_nid;		/* Next free node number */
	__le32 sit_ver_bitmap_bytesize;	/* Default value 64 */
	__le32 nat_ver_bitmap_bytesize; /* Default value 256 */
	__le32 checksum_offset;		/* checksum offset inside cp block */
	__le64 elapsed_time;		/* mounted time */
	/* allocation type of current segment */
	unsigned char alloc_type[MAX_ACTIVE_LOGS];

	/* SIT and NAT version bitmap */
	unsigned char sit_nat_version_bitmap[1];
} __packed;

为了维护数据一致性还有其他结构,如orphan node和active segment

image.png

orphan node区域保存orphan node list。这个区域是动态的,不一定有。

active segment(或CURSEG)区域正在分配数据的log对应的segment。一共有6个。