F2FS源码分析系列文章
主目录
一、文件系统布局以及元数据结构
二、文件数据的存储以及读写
三、文件与目录的创建以及删除(未完成)
四、垃圾回收机制
五、数据恢复机制
六、重要数据结构或者函数的分析
- f2fs_summary的作用
- f2fs_journal的作用
- f2fs_map_block的作用
- get_dnode_of_data的作用
- get_node_page的作用(未完成)
f2fs_summary的作用
从第二章第一节F2FS文件组织结构可以知道,一个文件是如何通过node找到对应的data的物理地址。但是一些场合会反过来,需要通过data的物理地址找到保存这个地址的node的信息。例如GC的时候,F2FS会找到一个segment进行GC,将数据块迁移到新的segment中。此时系统要根据segment里面的block的物理地址,反过来找到node的信息,然后将新的数据块物理地址重新更新的node的对应位置,更具体可以参考垃圾回收章节。
因此SSA的主要作用是提供系统通过数据块物理地址找到所属的node的信息的能力。我们可以直接分析f2fs_summary
的源码:
struct f2fs_summary {
__le32 nid; /* parent node id */
union {
__u8 reserved[3];
struct {
__u8 version; /* node version number */
__le16 ofs_in_node; /* block index in parent node */
} __packed;
};
} __packed;
系统中每一个数据块的物理地址,都对应了一个f2fs_summary
,系统可以通过物理地址找到对应的f2fs_summary
。f2fs_summary
的nid
变量表示当前的数据块所属的node的nid。而ofs_in_node
则表示当前的数据块位于这个node的第几个block,即f2fs_inode->i_addr[ofs_in_node]
或者direct_node->addr[ofs_in_node]
,可以参考F2FS文件组织结构这一节。
f2fs_summary
保存在f2fs_summary_block
中,而每一个f2fs_summary_block
都保存了512个f2fs_summary
,对应一个segment保存的数据块的数目,因此一个segment对应一个f2fs_summary_block
,系统可以通过segment number(segno)找到对应的f2fs_summary_block
,然后再找到对应的f2fs_summary
。
从f2fs_summary_block
的定义可以发现,除了f2fs_summary
以外,还保存了f2fs_journal
以及summary_footer
。summary_footer
的type
变量表明当前的f2fs_summary_block
是保存了node数据还是data数据。f2fs_journal
用于缓存一些当前的对SIT和NAT的一些改动,避免频繁读写NAT和SIT区域的数据,可以参考f2fs_journal的作用这一节。
struct f2fs_summary_block {
struct f2fs_summary entries[ENTRIES_IN_SUM]; // ENTRIES_IN_SUM=512
struct f2fs_journal journal;
struct summary_footer footer;
} __packed;
struct summary_footer {
unsigned char entry_type; /* SUM_TYPE_XXX */
__le32 check_sum; /* summary checksum */
} __packed;