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

一、前言

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

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

4bf14de18aa518daa6a65fb4f73cd23c.png

二、superblock相关结构体

2.1 Superblock相关结构体定义    

a971704a8f649fa02b2e40989ebbf914.png

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 关键结构体定义    

fbcdb8facd59d654baa727902d9cff78.png

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。对应的磁盘上的布局结构如下。          

bbb25bcf1f8002e75ad5c398c2607a88.png

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

4.1 NAT关键结构体定义

e03e2acdf413ec1577b8c98781840db8.png         

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结构体,

8be76d6011668dd1b28cd5139d843928.png

五、SSA相关结构体

5.1 SSA关键结构体定义    

b0625a4e6ca1d8dd6788e9c57ae156ee.png    

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关键结构体    

f18bbae23fbdf9ff39ec0b3368104e5a.png

六、MA相关结构体

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

6.1 node关键数据结构

b4457e7a3733378b0eac9bbe49ce6717.png

6.1.1 struct f2fs_inode关键定义

8e43387ae93a0c462d2d909fc1420ee8.png

6.1.2 struct direct_node关键数据结构

direct_node结构体保存blk地址    

c069e081410fba22537e46952bb54a90.png

6.1.3 struct indirect_node关键数据结构

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

b7aa15587977ecf1127569cbd8ef3501.png                

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    

759c6f8bda520674cc9888954a2e7309.png

6.2.2 direct_node类型的f2fs_node

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

cf04fe03d5cba801fad7d49ff71ad4b8.png

6.2.3 indirect_node类型的f2fs_node

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

e032ffda3bc8177638be5a6b3c477883.png

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

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

e42168074035f9720e46dca8286b0ccb.png

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

393b4e3f7f76beca76afd2b20858e572.png

全方位剖析内核抢占机制

Linux V4L2子系统与视频编解码设备介绍

内核调度客制化利器:SCHED_EXT

9b6a3dd71802fb52963445ae1f723690.gif

长按关注内核工匠微信

Linux内核黑科技| 技术文章| 精选教程

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
F2FS是Flash-Friendly File System的简称,是专门为闪存设备设计的文件系统。它采用了一些新的设计思路和数据结构,能够更好地充分利用闪存设备的性能和寿命。F2FS代码架构可以分为以下几个部分: 1. F2FS核心模块:F2FS核心模块负责管理整个文件系统的元数据,包括超级块、inode、数据块、日志等。它也是整个F2FS文件系统的入口,提供了文件系统的操作接口。 2. Checkpoint模块:Checkpoint模块负责管理F2FS的日志和检查点机制。在F2FS中,所有的写操作都是先写入日志,然后再同步到数据块中。Checkpoint模块会定期将日志和数据同步到检查点中,以保证文件系统的一致性和可靠性。 3. GC模块:GC模块负责管理F2FS的垃圾回收机制。由于闪存设备的写入操作是有限制的,因此需要定期进行垃圾回收以释放已经不再使用的空间。 4. Compression模块:Compression模块负责对数据进行压缩和解压缩,以节省存储空间和提高读写性能。 5. Encryption模块:Encryption模块负责对文件和数据进行加密和解密,以保护用户数据的安全性。 6. Mount模块:Mount模块负责F2FS文件系统的挂载和卸载操作,以及文件系统的格式化和初始化等操作。 总之,F2FS代码架构设计得非常清晰和模块化,各个模块之间相互独立,并且有很好的扩展性和灵活性。这也是F2FS能够在闪存设备中发挥出色性能和可靠性的重要原因之一。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

内核工匠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值