F2FS文件系统二 实验分析f2fs文件系统

一、环境准备:

1、ubuntu系统安装f2fs-tools:sudo apt-get install -y f2fs-tools

2、使用系统loop设备进行实践操作:

dd if=/dev/zero of=device bs=4K count=51200 //200M
losetup /dev/loop0 device      //寻址可用的loop设备
mkfs.f2fs -l f2fs /dev/loop0   //格式化此loop设备
mount -t f2fs /dev/loop0 ./f2fs_mp //挂载到f2fs_mp文件夹

  

3、获取挂载初始状态:dd if=/dev/loop0 of=f2fs_test,可以通过UE打开f2fs_test查看。

4、新建如下文件,以及对应的inode:

  root@ubuntu:/home/yinpeng/f2fs_mp# ls -i

  91 1.c     92 2.txt     87 a.txt     93 bio.c

二、磁盘布局分解:

1、superBlock:

  F2FS文件的起始地址向后偏移0x400字节,寻址当前地址为所述超级块SuperBlock的起始地址。

扫描二维码关注公众号,回复: 9144007 查看本文章

在内存的存储方式是小端存储,有两个superblock如下:

对应的结构体信息如下:

struct f2fs_super_block {

__le32 magic;                        /* Magic Number */             

0xF2F52010

__le16 major_ver;                /* Major Version */ 

0x01

__le16 minor_ver;                /* Minor Version */ 

0x0B

__le32 log_sectorsize;                /* log2 sector size in bytes */        

0x09

__le32 log_sectors_per_block;        /* log2 # of sectors per block */  

0x03

__le32 log_blocksize;                /* log2 block size in bytes */        

 0x0C

__le32 log_blocks_per_seg;        /* log2 # of blocks per segment */    

 0x09

__le32 segs_per_sec;                /* # of segments per section */        

0x01

__le32 secs_per_zone;                /* # of sections per zone */          

 0x01

__le32 checksum_offset;                /* checksum offset inside super block */

0x00

__le64 block_count;                /* total # of user blocks */               

0xC800

__le32 section_count;                /* total # of sections */              

0x5C

__le32 segment_count;                /* total # of segments */             

 0x63

__le32 segment_count_ckpt;        /* # of segments for checkpoint */    

 0x02

__le32 segment_count_sit;        /* # of segments for SIT */           

 0x02

__le32 segment_count_nat;        /* # of segments for NAT */           

 0x02

__le32 segment_count_ssa;        /* # of segments for SSA */            

0x01            

__le32 segment_count_main;        /* # of segments for main area */    

0x5C

__le32 segment0_blkaddr;        /* start block address of segment 0 */ 

0x0200

__le32 cp_blkaddr;                /* start block address of checkpoint */    

0x0200

__le32 sit_blkaddr;                /* start block address of SIT */           

0x0600

__le32 nat_blkaddr;                /* start block address of NAT */           

0x0A00

__le32 ssa_blkaddr;                /* start block address of SSA */           

0x0E00

__le32 main_blkaddr;                /* start block address of main area */ 

0x1000

__le32 root_ino;                /* root inode number */                    

0x03

__le32 node_ino;                /* node inode number */                    

0x01

__le32 meta_ino;                /* meta inode number */                    

0x02

__u8 uuid[16];                        /* 128-bit uuid for volume */              

***                    

__le16 volume_name[MAX_VOLUME_NAME];        /* volume name */          

F2FS       

__le32 extension_count;                /* # of extensions below */            

0X0001B   

__u8 extension_list[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN];/* extension array */   

0x00

__le32 cp_payload;                                                  

//0x0

__u8 version[VERSION_LEN];  /* the kernel version */                   

//4.9.117+ #4 SMP PREEMPT Sat May 25 01:40:39 CST 2019

__u8 init_version[VERSION_LEN]; /* the initial kernel version */        

//4.9.117+ #4 SMP PREEMPT Sat May 25 01:40:39 CST 2019

__le32 feature;         /* defined features */        

//0x0

__u8 encryption_level;      /* versioning level for encryption */        

 //0x0

__u8 encrypt_pw_salt[16];   /* Salt used for string2key algorithm */

 //0x0

struct f2fs_device devs[MAX_DEVICES];   /* device list */                

 //0x0

__le32 qf_ino[F2FS_MAX_QUOTAS]; /* quota inode numbers */               

  //0x0

__u8 hot_ext_count;     /* # of hot file extension */                   

  //0x0

__u8 reserved[310];     /* valid reserved region */                       

  //0x0                                                                                  

__le32 crc;         /* checksum of superblock */                        

 //0x0

} __packed;

 

2checkpoint:

checkpoint的数量也有两个:

struct f2fs_checkpoint {

__le64 checkpoint_ver;                /* checkpoint block version number */                                                       

0x1052B10E

__le64 user_block_count;        /* # of user blocks */                     

0x7A00

__le64 valid_block_count;        /* # of valid blocks in main area */       

0x13

__le32 rsvd_segment_count;        /* # of reserved segments for gc */        

0x15

__le32 overprov_segment_count;        /* # of overprovision segments */      

0x1F

__le32 free_segment_count;        /* # of free segments in main area */      

0x56

__le32 cur_node_segno[MAX_ACTIVE_NODE_LOGS];              

 0x0.1.2.0xFFFFFFFF.FFFFFFFF.FFFFFFFF.FFFFFFFF.FFFFFFFF  

__le16 cur_node_blkoff[MAX_ACTIVE_NODE_LOGS];              

0X2F.10.2.0x00. 0x00. 0x00. 0x00. 0x00. 0x00              

__le32 cur_data_segno[MAX_ACTIVE_DATA_LOGS];               

0x03. 0x47. 0x16. FFFFFFFF. FFFFFFFF. FFFFFFFF. FFFFFFFF. FFFFFFFF

__le16 cur_data_blkoff[MAX_ACTIVE_DATA_LOGS];                   

0X85. 0x1AB. 0x00. 0x00. 0x00. 0x00. 0x00. 0x00

 __le32 ckpt_flags;                /* Flags : umount and journal_present */       

0x01C4

__le32 cp_pack_total_block_count;        /* total # of one cp pack */       

0x04

__le32 cp_pack_start_sum;        /* start block number of data summary */   

0x01

__le32 valid_node_count;        /* Total number of valid nodes */          

0x05

__le32 valid_inode_count;        /* Total number of valid inodes */         

0x05

__le32 next_free_nid;                /* Next free node number */               

 0x61

__le32 sit_ver_bitmap_bytesize;        /* Default value 64 */                 

0x40

__le32 nat_ver_bitmap_bytesize; /* Default value 256 */                

0x40

__le32 checksum_offset;                /* checksum offset inside cp block */      

0x0FF

__le64 elapsed_time;                /* mounted time */                         

0x019289

unsigned char alloc_type[MAX_ACTIVE_LOGS];                             

0x00

unsigned char sit_nat_version_bitmap[1];                               

0x00

} __packed;

3、SIT:

0xC01 >> 10 =  3 type

0xC01 & 0x3FF =  1

/*
 * Note that f2fs_sit_entry->vblocks has the following bit-field information.
 * [15:10] : allocation type such as CURSEG_XXXX_TYPE
 * [9:0] : valid block count
 */
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;

dump.f2fs    -s    0~-1    f2fs_test_2

root@ubuntu:/home/yinpeng# cat dump_sit

segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)

 

segno:       0        vblocks:  1        seg_type:3        sit_pack:2

//1segment = 512 block

  00  10  00  00  00  00  00  00  00  00  00  00  00  00  00  00

  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00

  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00

  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00

segno:       1        vblocks:  2        seg_type:4        sit_pack:2

用户层的数据从0x100000开始:

1000000 + 1*2MB(segmet size) + (8*5 + 3) * 4Kb(block size) =

0x1000000 + 0x200000 + 0x2B000 = 0x122B000

0x18 = 0x00011000

  00  00  00  00  00  18  00  00  00  00  00  00  00  00  00  00

  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00

  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00

  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00

segno:       2        vblocks:  0        seg_type:5        sit_pack:2

segno:       3        vblocks:  1        seg_type:0        sit_pack:2

0x1000000 + 3 * 2MB + (14*8 + 4) * 4kb = 74000

0x1000000 + 0x600000 + 74000

0x08 = 0x00001000

  00  00  00  00  00  00  00  00  00  00  00  00  00  00  08  00

  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00

  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00

  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00

segno:       4        vblocks:  0        seg_type:1        sit_pack:2

segno:       5        vblocks:  0        seg_type:1        sit_pack:2
 

从上面的分解,可以看到通过如下流程可以找到DataBlock的地址:

Superblock -> NAT -> inode number  ->  datablock

4.NAT

struct f2fs_nat_entry {
	__u8 version;		/* latest version of cached nat entry */
	__le32 ino;		/* inode number */
	__le32 block_addr;	/* block address */
} __packed;

struct f2fs_nat_block {
	struct f2fs_nat_entry entries[NAT_ENTRY_PER_BLOCK];
} __packed;

dump.f2fs   -n   0~-1    f2fs_test_2

root@ubuntu:/home/yinpeng# cat dump_nat

nid:    3        ino:    3        offset:    0        blkaddr:      4111 //0x122A 000        pack:2

nid:   87        ino:   87        offset:    0        blkaddr:      4651 //0x122B        pack:2

nid:   91        ino:   91        offset:    0        blkaddr:      4652 //0x122C        pack:2

nid:   92        ino:   92        offset:    0        blkaddr:      4653 //0x122D        pack:2

nid:   93        ino:   93        offset:    0        blkaddr:      4654 //0x122E        pack:2

5、DataBlock:


root@ubuntu:/home/yinpeng# dump.f2fs -a 0~-1 f2fs_test_2

root@ubuntu:/home/yinpeng# cat dump_ssa

/* 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 */
			__le16 ofs_in_node;	/* block index in parent node */
		} __packed;
	};
} __packed;

参考博客:

https://blog.csdn.net/SweeNeil/article/details/91897016

作者:frank_zyp
您的支持是对博主最大的鼓励,感谢您的认真阅读。
本文无所谓版权,欢迎转载。

发布了59 篇原创文章 · 获赞 80 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/frank_zyp/article/details/96474245