深入代码细节看f2fs在磁盘上的组织方式

文摘   2024-08-23 13:12   陕西  

       

 

    

一、前言

《抛开代码细节看文件系统组织方式》一文中,主要从UFS上数据入手,通过对比大小不同的两个文件系统,以及一些常见的文件操作,对F2FS在磁盘上分布有了基础的了解。

本篇文章就深入到代码细节,深入分析一下F2FS各个区域中保存内容的细节。

         

 

二、superblock相关结构体

2.1 Superblock相关结构体定义    

         

 

2.2 superblock相关结构体注释说明

2.2.1 struct f2fs_super_block

定义

示例值

注释说明

__le32 magic

0xF2F52010

Magic Number F2FS固定值0xf2f52010

__le16 major_ver

1

                 

 

__le16 minor_ver

16

                 

 

__le32 log_sectorsize

9

                 

 

__le32 log_sectors_per_block

3

                 

 

__le32 log_blocksize

12

                 

 

__le32 log_blocks_per_seg

9

                 

 

__le32 segs_per_sec

1

每个section包含多少个segment,1表示每个section包含1个segment

__le32 secs_per_zone

1

每个zone包含多少个section,1表示每个zone包含1个section        

__le32 checksum_offset

0

                 

 

__le64 block_count

25600

block数量,每个block的size为4K,25600*4K=100MB,包括superblock/CP/SIT/NAT/SSA/MA区域

__le32 section_count

42

MA区section数量                  
42=50-1(sb)-2(cp)-2(sit)-2(nat)-1(ssa)

__le32 segment_count

49

segment数量,不包含superblock(2MB)                  
49*2MB=98MB=100MB-2MB

__le32 segment_count_ckpt

2

check point的segment数量,固定为2MB

__le32 segment_count_sit

2

SIT区segment数量,固定为2MB

__le32 segment_count_nat

2

NAT区segment数量,会随分区大小变化而变化

__le32 segment_count_ssa

1

SSA区segment数量

__le32 segment_count_main

42

MA区segment数量

__le32 segment0_blkaddr

512

segment0的blkaddr地址(不包含superblock)                  
512*4K=2MB开始计算

__le32 cp_blkaddr

512

CP区起始blkaddr地址                  
512*4K=2MB

__le32 sit_blkaddr

1536

SIT区起始blkaddr地址                  
1536*4K=6MB=2MB(superblock)+2*2MB(cp)

__le32 nat_blkaddr

2560

NAT区起始blkaddr地址                  
2560*4K=10MB=2MB(superblock)+2*2MB(cp)+2*2MB(SIT)

__le32 ssa_blkaddr

3584

SSA区起始blkaddr地址                  
3584*4K=14MB=2MB(superblock)+2*2MB(cp)+2*2MB(SIT)+2*2MB(NAT)

__le32 main_blkaddr

4096

MA区起始blkaddr地址                  
4096*4K=16MB=2MB(superblock)+2*2MB(cp)+2*2MB(SIT)+2*2MB(NAT)+1*2MB(SSA)

__le32 root_ino

3

root inode number

__le32 node_ino

1

node inode number

__le32 meta_ino

2

meta inode number

__u8 uuid[16]

0x11,0xB3,0xA9,0x1D,0x83,0xA3,0x46,0xAB,0x8A,0xC3,0x5D,0xE7,0x44,0xC5,0x8A,0x0F

uuid

__le16 volume_name[MAX_VOLUME_NAME]

                 

 

                 

 

__le32 extension_count

36

                 

 

__u8 extension_list[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]        

"mp", "wm", "og", "jp", "avi", "m4v", "m4p", "mkv", "mov", "webm", "wav", "m4a", "3gp", "opus", "flac", "gif", "png", "svg", "webp", "jar", "deb", "iso", "gz", "xz", "zst", "pdf", "pyc", "ttc", "ttf", "exe

                 

 

__le32 cp_payload

0x0

                 

 

__u8 version[VERSION_LEN]

5.15.123-android13-8-o-gdad242538aa2

执行fsck或挂载等操作后文件系统的内核信息

__u8 init_version[VERSION_LEN]

5.15.123-android13-8-o-gdad242538aa2

初始化创建文件系统时的内核信息

__le32 feature

0x2499

文件系统特定feature,每一个表示一个feature

__u8 encryption_level

                 

 

                 

 

__u8 encrypt_pw_salt[16]

                 

 

                 

 

struct f2fs_device devs[MAX_DEVICES]

                 

 

                 

 

__le32 qf_ino[F2FS_MAX_QUOTAS]

                 

 

                 

 

__u8 hot_ext_count

                 

 

                 

 

__le16  s_encoding

                 

 

                 

 

__le16  s_encoding_flags

                 

 

                 

 

__u8 s_stop_reason[MAX_STOP_REASON]

                 

 

                 

 

__u8 reserved[274]

                 

 

                 

 

__le32 crc

                 

 

                 

 


三、SIT相关结构体

3.1 SIT 关键结构体定义    

3.2 SIT关键结构体注释说明

3.2.1 struct f2fs_sit_block结构体

定义

注释说明

struct f2fs_sit_entry entries[SIT_ENTRY_PER_BLOCK];

结构体占用空间为4K,由55个f2fs_sit_entry结构体组成

        

 

3.2.2 struct f2fs_sit_entry

定义

注释说明

__le16 vblocks;

vblocks[9:0]表示当前segment有多少个有效的block,vblocks[15:10]表示segment的类型,类型有(hot/warn/cold)*(data/node)这些类型

__u8 valid_map[SIT_VBLOCK_MAP_SIZE];

8*64=512 bit,512位的位图表示一个segment中block的使用情况,一个segment大小为2MB,包含512个block。                 
512*4K=2MB,所以512个bit表示block使用请

__le64 mtime;

segment最后一次GC时间,用于GC相关流程

       

 

3.3 图解SIT关键结构体

SIT区域中的block(4K)存放的f2fs_sit_block类型的数据结构。每个f2fs_sit_block中由55个f2fs_sit_entry结构体数组组成,每个f2fs_sit_entry管理一个segment。对应的磁盘上的布局结构如下。          

 

四、NAT相关结构体注释说明

4.1 NAT关键结构体定义

         

 

4.2 NAT关键结构体注释说明    

4.2.1 struct f2fs_nat_block

定义

注释说明

struct f2fs_nat_entry entries[NAT_ENTRY_PER_BLOCK];

结构体占用空间为4K,由455个f2fs_nat_entry结构体组成

         

 

4.2.2 struct f2fs_nat_entry

定义

注释说明

__u8 version;

                 

 

__le32 ino;

inode number,也就是文件inode的编号

__le32 block_addr;

blk地址

         

 

4.3图解NAT关键结构体

NAT区域的block(4K)存放的是struct f2fs_nat_block结构体,

五、SSA相关结构体

5.1 SSA关键结构体定义    

   

5.2 SSA关键结构体注释说明

5.2.1 struct f2fs_summary_block

定义

注释说明

struct f2fs_summary entries[ENTRIES_IN_SUM];

每个f2fs_summary管理一个block,所以共512个f2fs_summary结构体

struct f2fs_journal journal;

NAT/SIT 操作日志,或拓展信息

struct summary_footer footer;

segment类型以及当前结构体的校验和

         

 

5.2.2 struct f2fs_summary

定义

注释说明

__le32 nid;

当前block属于哪个node id

__u8 version;

                 

 

__le16 ofs_in_node;

node 的offset编号,后面章节分析文件布局时可以看到相关介绍

       

 

5.2.3 struct f2fs_journal      

 

5.2.4 summary_footer

定义

注释

unsigned char entry_type;

summary 管理的segment类型                  
#define SUM_TYPE_NODE  (1)                  
#define SUM_TYPE_DATA  (0)

__le32 check_sum

校验和

         

 

5.3 图解SSA关键结构体    

六、MA相关结构体

MA区域(主存储区)主要分为两大类,一类是node类型,另外一类是data类型。node保存的管理数据,data保存的就是通常理解的文件数据。我们重点分析一下node类型的关键结构体,之后再展示一下文件相关的结构体及组织方式。         

 

6.1 node关键数据结构

         

 

   

6.1.1 struct f2fs_inode关键定义

6.1.2 struct direct_node关键数据结构

direct_node结构体保存blk地址    

         

 

6.1.3 struct indirect_node关键数据结构

Indirect_node类型结构体,主要使用数组保存nid

                

 

6.2图解f2fs_node关键数据结构     

 

6.2.1 f2fs_inode类型的f2fs_node

f2fs_inode类型的数据主要有三部分组成

元数据:保存文件的大小,修改时间,文件名等

i_addr:共932个地址,指向当前文件data数据保存的block地址

i_nid:共5个,它指向的是f2fs_node类型的nid,根据使用方法,有分为2个direct类型的node,2个indirect类型的node,1个double-indirect类型的node    

         

 

6.2.2 direct_node类型的f2fs_node

direct_node类型的f2fs_node,有一个1018个长度的数组,每个元素可以保存一个block地址    

6.2.3 indirect_node类型的f2fs_node

indirect_node类型的f2fs_node与direct_node类似,不过indirect_node保存的nid,所以它保存的是对应node的地址。而direct_node保存的是data block的地址。    

6.3文件相关结构体及组织方式总览

从上面的介绍,我们总体看一下文件的组织方式。根据文件的大小,这里的direct_node或indirect_node并不是每个文件都需要

         

 

   

另外当文件较小,为了节约存储空间,文件可能还会使用inline保存。也就是将data数据直接保存到f2fs_inode中,如下图

Linux内核之旅
Linux内核之旅
 最新文章