f2fs学习笔记 - 3. F2FS文件系统布局
目錄
- 1.前言
- 2.F2FS布局說(shuō)明
- 2.1. super block(block 0x0 ~ block 0x1ff)
- 2.2 CP(block 0x200 ~ block 0x5ff)
- cp page1
- nat journal
- sit journal
- data summary
- current hot node summary
- current warm node summary
- current cold node summary
- cp page2
- 2nd checkpoint
- 2.3 SIT(block 0x600 ~ block 0x9ff)
- 2.4 NAT(block 0xa00~0xdff)
- 2.5 SSA(block 0xe00 ~ block 0xfff)
- 2.6 main area(block 0x1000 ~)
- data block
- node block
- 3. 調(diào)試
- 3.1 查看文件的inode號(hào)
- 3.2 根據(jù)文件的inode號(hào)找到文件的data塊
- 3.3 查看inode狀態(tài)
- 3.4 查看block
- 參考文檔
1.前言
本文采用F2FS初始版本為例說(shuō)明F2FS的文件系統(tǒng)布局,并通過(guò)f2fs-tools來(lái)探究如何通過(guò)文件的inode號(hào)來(lái)獲取文件的內(nèi)容。
采用如下的方法制作f2fs鏡像,大小為128M
分別創(chuàng)建了如下幾個(gè)文件
ubuntu@VM-0-9-ubuntu:/mnt$ ls -i 5 a.c 6 b.jpg 7 c.txt 4 fstab版本號(hào):
F2FS: 上傳kernel3.7主線(xiàn)內(nèi)核的初始版本(包含前16個(gè)patch)
F2FS-tools: mkfs.f2fs Ver: 1.1.0 (2013-10-17)
2.F2FS布局說(shuō)明
如上為f2fs文件系統(tǒng)總體布局圖。
2.1. super block(block 0x0 ~ block 0x1ff)
super block主要定義segment, sector, block的大小及數(shù)目,以及各個(gè)區(qū)域(CP, SIT, NAT, SSA,MAIN)的偏移地址和大小, 同時(shí)定義了root inode
super block偏移為0x400 (1024),也就是從0x400的位置開(kāi)始存放1st super block的內(nèi)容,從0x1400開(kāi)始存放2nd super block的內(nèi)容
如下為所制作的f2fs.img鏡像super block各成員變量的打印:
- magic:0xf2f52010
- major_ver:0x1
- minor_ver:0x1
- log_sectorsize:0x9
每個(gè)sector大小為512B,sector相當(dāng)于閃存flash中一個(gè)page的大小 - log_sectors_per_block:0x3
每個(gè)block有8個(gè)sector - log_blocksize:0xc(12)
每個(gè)block的大小為4k, block相當(dāng)于閃存flash中一個(gè)block的大小 - log_blocks_per_seg:0x9
每個(gè)segment的有512個(gè)block - segs_per_sec:0x1
- secs_per_zone:0x1
- checksum_offset:0x0
- block_count:32768
也就是32K個(gè)block,每個(gè)blck為4k, 一共是128M
通過(guò)制作的鏡像大小為128M, 也就是0x7FFFFFF個(gè)字節(jié),與此處的block_count完全吻合,說(shuō)明f2fs對(duì)block_count的統(tǒng)計(jì)不僅包含了main area,還包含了元數(shù)據(jù)部分 - section_count:0x38(56)
統(tǒng)計(jì)section的數(shù)目,只包含main區(qū)域,為56 * 512個(gè)block, 每個(gè)block大小為4k
因此大小為112M,而鏡像為128M,說(shuō)明有一部分是沒(méi)有統(tǒng)計(jì)進(jìn)section count的,之所以比segment count的數(shù)目少7個(gè)segment,是因?yàn)闆](méi)有統(tǒng)計(jì)cp,sit,nat,ssa,而只統(tǒng)計(jì)了main area區(qū)域 - segment_count:0x3f(63)
統(tǒng)計(jì)secment的數(shù)目,沒(méi)有統(tǒng)計(jì)sb區(qū)域,為63 * 512個(gè)block, 每個(gè)block大小為4K
因此大小為126M,而鏡像為128M,與鏡像大小相差2M,,說(shuō)明有一個(gè)segment沒(méi)有統(tǒng)計(jì)進(jìn)segment count的, 從下面的cp_blkaddr為0x200可以得出相差的這1個(gè)segment正是superblock的大小. 與 section_count的統(tǒng)計(jì)數(shù)相比多了7個(gè)segment,這7個(gè)segment分別是如下的cp, sit, nat, ssa所占用的segment,說(shuō)明segment count統(tǒng)計(jì)時(shí)連這些區(qū)域也統(tǒng)計(jì)進(jìn)入了 - segment_count_ckpt:2
checkpoint占用2個(gè)segment - segment_count_sit:2
sit占用了兩個(gè)segment - segment_count_nat:2
nat占用了兩個(gè)segment - segment_count_ssa:1
ssa占用了1個(gè)segment - segment_count_main:0x38(56)
main area的segment數(shù)目 - segment0_blkaddr:0x200
第一個(gè)segment的地址,第一個(gè)segment為CP區(qū)域的第一個(gè)segment - cp_blkaddr:0x200
cp區(qū)域的第一個(gè)block的地址,從這里可以看出super block占用了1個(gè)segment,也就是512個(gè)block, 5124k1024=0x200000 - sit_blkaddr:0x600
- nat_blkaddr:0xa00
- ssa_blkaddr:0xe00
- main_blkaddr:0x1000
- root_ino:3
- node_ino:1
- meta_ino:2
- uuid:
- volume_name:
- extension_count:0x17
2.2 CP(block 0x200 ~ block 0x5ff)
如上為cp block的總體布局,分為兩種:nomal mode和compact mode.通過(guò)鏡像可知,本文創(chuàng)建的鏡像的CP為compact mode
ckpt_flags的值是5,通過(guò)ckpt_flags & CP_COMPACT_SUM_FLAG的值也可以知道,它就是compact mode.
cp區(qū)域主要包含兩個(gè)cp pack,每個(gè)cp pack占據(jù)一個(gè)segment。
cp page1
如上即為第一個(gè)cp page1,相關(guān)打印如下,主要描述了main area的可用的block總數(shù),有效block數(shù)目,over provision segment預(yù)留數(shù)目,以及其它的cp元數(shù)據(jù)總體信息。
===information of raw checkpoint=
-
checkpoint_ver:66
-
user_block_count:4096
4096/512=8個(gè)segment,而main area有56個(gè)segment,其它48個(gè)segment為overprovision segment -
valid_block_count:6
-
rsvd_segment_count:0x30(48)
保留了48個(gè)segment -
overprov_segment_count:0x30(48)
-
free_segment_count:0x32(50)
-
----cur_node_segno----
0x00000037
0x00000036
0x00000035 -
----cur_node_blkoff----
0x00000006
0x0000000C
0x00000000 -
----cur_data_segno----
0x00000034
0x00000001
0x00000000| -
----cur_data_blkoff----
0x00000005
0x00000003
0x00000001 -
ckpt_flags:0x5
-
cp_pack_total_block_count:0x6
-
cp_pack_start_sum:0x1
-
valid_node_count:0x5
-
valid_inode_count:0x5
-
next_free_nid:0x8
-
sit_ver_bitmap_bytesize:0x40
-
nat_ver_bitmap_bytesize:0x40
-
checksum_offset:0xffc
-
elapsed_time:40
-
allocation type of current segment
0x00000000|0x00000000|0x00000000|0x00000000|0x00000000|0x00000000|0x00000000|
0x00000000|0x00000000|0x00000000|0x00000000|0x00000000|0x00000000|0x00000000|
0x00000000|0x00000000| -
sit_nat_version_bitmap:0x0
nat journal
主要保存了每個(gè)文件的node address table entry
如上為cp的nat journal區(qū)域,主要保存了每個(gè)文件的nat entry,nat entry的結(jié)構(gòu)如下所示:
可以看到創(chuàng)建的a.c,b.jpg, c.txt,fstab幾個(gè)文件的nat entry信息就位于此區(qū)域,而沒(méi)有位于NAT區(qū)。
ubuntu@VM-0-9-ubuntu:~/qemu/rootfs$dump.f2fs -n 0~-1 f2fs.img ubuntu@VM-0-9-ubuntu:~/qemu/rootfs$ cat dump_nat nid: 3 ino: 3 offset: 0 blkaddr: 32261 pack:1 nid: 4 ino: 4 offset: 0 blkaddr: 31751 pack:1 nid: 5 ino: 5 offset: 0 blkaddr: 31753 pack:1 nid: 6 ino: 6 offset: 0 blkaddr: 31754 pack:1 nid: 7 ino: 7 offset: 0 blkaddr: 31755 pack:1sit journal
保存了每個(gè)segment
如上為cp的sit journal區(qū)域, sit entry的結(jié)構(gòu)如下:
data summary
見(jiàn)第二個(gè)checkpoint的data summary
current hot node summary
current warm node summary
current cold node summary
cp page2
2nd checkpoint
data summary主要描述了current data segment 的每一個(gè)block, 相關(guān)數(shù)據(jù)結(jié)構(gòu)如下:
/* a summary entry for a 4KB-sized block in a segment */ struct f2fs_summary {__le32 nid; /* parent node id */union {__u8 reserved[3];struct {__u8 version; /* node version number *//* 所描述的data block地址位于node block的索引 */__le16 ofs_in_node; /* block index in parent node */} __packed;}; } __packed;2.3 SIT(block 0x600 ~ block 0x9ff)
struct f2fs_sit_entry {__le16 vblocks; /* reference above */__u8 valid_map[SIT_VBLOCK_MAP_SIZE]; /* bitmap for valid blocks */__le64 mtime; /* segment age for cleaning */ } __packed; ubuntu@VM-0-9-ubuntu:~/qemu/rootfs$ cat dump_sit segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)segno: 0 vblocks: 1 seg_type:2 sit_pack:280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 segno: 1 vblocks: 3 seg_type:1 sit_pack:2e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 segno: 2 vblocks: 0 seg_type:0 sit_pack:2 segno: 3 vblocks: 0 seg_type:0 sit_pack:2 segno: 4 vblocks: 0 seg_type:0 sit_pack:2 segno: 5 vblocks: 0 seg_type:0 sit_pack:2 segno: 6 vblocks: 0 seg_type:0 sit_pack:2 segno: 7 vblocks: 0 seg_type:0 sit_pack:2 segno: 8 vblocks: 0 seg_type:0 sit_pack:2 segno: 9 vblocks: 0 seg_type:0 sit_pack:2 segno: 10 vblocks: 0 seg_type:0 sit_pack:2 segno: 11 vblocks: 0 seg_type:0 sit_pack:2 segno: 12 vblocks: 0 seg_type:0 sit_pack:2 segno: 13 vblocks: 0 seg_type:0 sit_pack:2 segno: 14 vblocks: 0 seg_type:0 sit_pack:2 segno: 15 vblocks: 0 seg_type:0 sit_pack:2 segno: 16 vblocks: 0 seg_type:0 sit_pack:2 segno: 17 vblocks: 0 seg_type:0 sit_pack:2 segno: 18 vblocks: 0 seg_type:0 sit_pack:2 segno: 19 vblocks: 0 seg_type:0 sit_pack:2 segno: 20 vblocks: 0 seg_type:0 sit_pack:2 segno: 21 vblocks: 0 seg_type:0 sit_pack:2 segno: 22 vblocks: 0 seg_type:0 sit_pack:2 segno: 23 vblocks: 0 seg_type:0 sit_pack:2 segno: 24 vblocks: 0 seg_type:0 sit_pack:2 segno: 25 vblocks: 0 seg_type:0 sit_pack:2 segno: 26 vblocks: 0 seg_type:0 sit_pack:2 segno: 27 vblocks: 0 seg_type:0 sit_pack:2 segno: 28 vblocks: 0 seg_type:0 sit_pack:2 segno: 29 vblocks: 0 seg_type:0 sit_pack:2 segno: 30 vblocks: 0 seg_type:0 sit_pack:2 segno: 31 vblocks: 0 seg_type:0 sit_pack:2 segno: 32 vblocks: 0 seg_type:0 sit_pack:2 segno: 33 vblocks: 0 seg_type:0 sit_pack:2 segno: 34 vblocks: 0 seg_type:0 sit_pack:2 segno: 35 vblocks: 0 seg_type:0 sit_pack:2 segno: 36 vblocks: 0 seg_type:0 sit_pack:2 segno: 37 vblocks: 0 seg_type:0 sit_pack:2 segno: 38 vblocks: 0 seg_type:0 sit_pack:2 segno: 39 vblocks: 0 seg_type:0 sit_pack:2 segno: 40 vblocks: 0 seg_type:0 sit_pack:2 segno: 41 vblocks: 0 seg_type:0 sit_pack:2 segno: 42 vblocks: 0 seg_type:0 sit_pack:2 segno: 43 vblocks: 0 seg_type:0 sit_pack:2 segno: 44 vblocks: 0 seg_type:0 sit_pack:2 segno: 45 vblocks: 0 seg_type:0 sit_pack:2 segno: 46 vblocks: 0 seg_type:0 sit_pack:2 segno: 47 vblocks: 0 seg_type:0 sit_pack:2 segno: 48 vblocks: 0 seg_type:0 sit_pack:2 segno: 49 vblocks: 0 seg_type:0 sit_pack:2 segno: 50 vblocks: 0 seg_type:0 sit_pack:2 segno: 51 vblocks: 0 seg_type:0 sit_pack:2 segno: 52 vblocks: 1 seg_type:0 sit_pack:208 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 segno: 53 vblocks: 0 seg_type:5 sit_pack:2 segno: 54 vblocks: 4 seg_type:4 sit_pack:201 70 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 segno: 55 vblocks: 1 seg_type:3 sit_pack:204 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00valid_blocks:[0xa] valid_segs:5 free_segs:512.4 NAT(block 0xa00~0xdff)
struct f2fs_nat_entry { __u8 version; /* latest version of cached nat entry */ __le32 ino; /* inode number */__le32 block_addr; /* block address */ } __packed;2.5 SSA(block 0xe00 ~ block 0xfff)
ubuntu@VM-0-9-ubuntu:~/test$ dump.f2fs -a 0~-1 f2fs.img ubuntu@VM-0-9-ubuntu:~/test$ cat dump_ssa可以打印出每個(gè)segment中每個(gè)block所屬的node id
2.6 main area(block 0x1000 ~)
data block
node block
以fstab文件的node 4為例
從下面的inode信息中可以看出1122的ino號(hào)對(duì)應(yīng)的i_addr為0x1000~0x100a,正是上面的內(nèi)容
3. 調(diào)試
3.1 查看文件的inode號(hào)
ubuntu@VM-0-9-ubuntu:/mnt$ ls -i 5 a.c 6 b.jpg 7 c.txt 4 fstab以fstab為例,如何找到它的inode號(hào)?
由superblock的如下打印信息:
root_ino:3
node_ino:1
meta_ino:2
可知root目錄的inode號(hào)為3,通過(guò)CP的nat journal區(qū)可知其位于node block的塊號(hào)為0x7e05(32261)
找到0x7e05的root node block,找到其i_addr[0]
其中存儲(chǔ)的就是root目錄的data block塊號(hào)0x7804
通過(guò)相應(yīng)的hash算法就可以查到文件名fstab對(duì)應(yīng)的inode號(hào)為4
3.2 根據(jù)文件的inode號(hào)找到文件的data塊
通過(guò)3.1可以找到文件名對(duì)應(yīng)的inode號(hào)4,然后通過(guò)查CP的nat journal區(qū)域可以知道其位于node block塊號(hào)為0x7c07
繼續(xù)查看node block0x7c07, 找到i_addr[0],其中存儲(chǔ)的就是data block塊號(hào)
0x1200塊號(hào)的內(nèi)容為:
3.3 查看inode狀態(tài)
以ino=4(fstab)為例,通過(guò)如下命令可以查看inode的狀態(tài)
ubuntu@VM-0-9-ubuntu:~/qemu/rootfs$ sudo dump.f2fs -i 4 f2fs.img Info: Segments per section = 1 Info: Sections per zone = 1 Info: sector size = 512 Info: total sectors = 262144 (128 MB) Info: MKFS version"" Info: FSCK versionfrom "Linux version 4.15.0-88-generic (buildd@lgw01-amd64-036) (gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)) #88-Ubuntu SMP Tue Feb 11 20:11:34 UTC 2020"to "Linux version 4.15.0-88-generic (buildd@lgw01-amd64-036) (gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)) #88-Ubuntu SMP Tue Feb 11 20:11:34 UTC 2020" Info: superblock features = 0 : Info: superblock encrypt level = 0, salt = 00000000000000000000000000000000 Info: total FS sectors = 262144 (128 MB) Info: CKPT version = 3 [print_node_info: 276] Node ID [0x4:4] is inode i_mode [0x 81a4 : 33188] i_advise [0x 0 : 0] i_uid [0x 0 : 0] i_gid [0x 0 : 0] i_links [0x 1 : 1] i_size [0x 127 : 295] i_blocks [0x 2 : 2] i_atime [0x5efc3b84 : 1593588612] i_atime_nsec [0x 1312d00 : 20000000] i_ctime [0x5efc3b84 : 1593588612] i_ctime_nsec [0x 2625a00 : 40000000] i_mtime [0x5efc3b84 : 1593588612] i_mtime_nsec [0x 2625a00 : 40000000] i_generation [0xb5863313 : 3045470995] i_current_depth [0x 1 : 1] i_xattr_nid [0x 0 : 0] i_flags [0x 0 : 0] i_inline [0x 0 : 0] i_pino [0x 3 : 3] i_dir_level [0x 0 : 0] i_namelen [0x 5 : 5] i_name [fstab] i_ext: fofs:0 blkaddr:1200 len:1 i_addr[ofs] [0x 1200 : 4608] i_addr[ofs + 1] [0x 0 : 0] i_addr[ofs + 2] [0x 0 : 0] i_addr[ofs + 3] [0x 0 : 0] i_nid[0] [0x 0 : 0] i_nid[1] [0x 0 : 0] i_nid[2] [0x 0 : 0] i_nid[3] [0x 0 : 0] i_nid[4] [0x 0 : 0]Do you want to dump this file into ./lost_found/? [Y/N] Y Info: checkpoint state = 5 : compacted_summary unmountDone.Do you want to dump this file into ./lost_found/? [Y/N]提示是否dump這個(gè)文件,選擇Y會(huì)在./lost_found目錄看到這個(gè)文件的內(nèi)容
4的ino號(hào)對(duì)應(yīng)的i_addr為0x1200,正是上面fstab文件的內(nèi)容,通過(guò)
dump.f2fs -b 0x1200 f2fs.img 可以查看,直接查看鏡像的0x1200塊號(hào)也可以查看到
3.4 查看block
查看上節(jié)中的fstab的0x1200的 block
ubuntu@VM-0-9-ubuntu:~/qemu/rootfs$ sudo dump.f2fs -b 0x1200 f2fs.img == Dump data from block address ==FS Userdata Area: Data block from 0x1200- Direct node block : id = 0x4 from 0x7c07- Inode block : id = 0x4 from 0x7c07- File name : fstab- File size : 295 (bytes)- Data offset : 0x0 (4KB), 0 (bytes) Info: checkpoint state = 5 : compacted_summary unmountDone.查看0x1200 block的信息,可以看到它就是fstab的信息
參考文檔
F2FS文件系統(tǒng)二 實(shí)驗(yàn)分析f2fs文件系統(tǒng)
F2FS源碼分析-1.3 [F2FS 元數(shù)據(jù)布局部分] Checkpoint結(jié)構(gòu)
附錄
總結(jié)
以上是生活随笔為你收集整理的f2fs学习笔记 - 3. F2FS文件系统布局的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 我的世界 java错误_我的世界erro
- 下一篇: CTCS列控系统原理--详细学习笔记