ext4文件系统简介和数据内容定位
superblock的主要内容有:文件系统信息、块大小和块组信息、Inode 相关信息、文件系统大小和使用情况、日志相关信息、挂载信息、校验和和备份信息。=K|=K....|00001000索引节点表是是一个核心数据结构,用于存储文件和目录的元数据。每个文件和目录在文件系统中都有一个对应的inode(索引节点),inode表就是存储这些索引节点的地方。一个索引节点的大小为256Byte从 Grou
ext4它突出的特点有:数据分段管理、多块分配、延迟分配、持久预分配、日志校验、支持更大的文件系统和文件大小。
MTD(Memory Technology Devices)子系统是RAW NandFlash的抽象层,它是Linux系统用来管理NandFlash的,它向Linux系统提供了统一的抽象接口,用于读/写/控制NandFlash。
MTD子系统向用户提供的接口如下:
•/dev/mtd0,/dev/mtd1...,这个是字符设备接口,它提供了NandFlash的I/O操作,ioctl操作等
•sysfs文件系统接口,在这个接口中可以获取到MTD设备的更多,更全的信息
•proc文件系统,历史遗留接口,只提供一些基本的MTD设备信息MTD向内核提供了各种API,供内核更高层级的子系统使用,
比如,文件系统,以及后面要提到的UBI子系统。
一、文件系统结构体介绍
1.1 superblock超级块
superblock的主要内容有:
文件系统信息、块大小和块组信息、Inode 相关信息、文件系统大小和使用情况、日志相关信息、挂载信息、校验和和备份信息。
root@OpenWrt:/# hexdump -s 0 -n 4096 -C /dev/block/user_data
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000400 00 eb 0d 00 f0 9c 37 00 d8 c7 02 00 42 53 36 00 |......7.....BS6.|
00000410 43 ea 0d 00 00 00 00 00 02 00 00 00 02 00 00 00 |C...............|
00000420 00 80 00 00 00 80 00 00 d0 1f 00 00 12 3b 3d 4b |.............;=K|
00000430 87 b6 41 64 34 00 ff ff 53 ef 01 00 01 00 00 00 |..Ad4...S.......|
00000440 12 3b 3d 4b 00 00 00 00 00 00 00 00 01 00 00 00 |.;=K............|
00000450 00 00 00 00 0b 00 00 00 00 01 00 00 3c 00 00 00 |............<...|
00000460 c2 02 00 00 6b 04 00 00 d9 30 1d ef b3 77 42 b0 |....k....0...wB.|
00000470 99 d4 2f 79 04 52 17 5e 00 00 00 00 00 00 00 00 |../y.R.^........|
00000480 00 00 00 00 00 00 00 00 2f 64 61 74 61 00 00 00 |......../data...|
00000490 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000004c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 |................|
000004d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000004e0 08 00 00 00 00 00 00 00 00 00 00 00 e2 2b 56 ed |.............+V.|
000004f0 fb c1 4e 22 8b cb c0 dc ce e6 e0 10 01 01 40 00 |..N"..........@.|
00000500 0c 00 00 00 00 00 00 00 12 3b 3d 4b 0a f3 01 00 |.........;=K....|
00000510 04 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 |.............@..|
00000520 03 84 18 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 |................|
00000550 00 00 00 00 00 00 00 00 00 00 00 00 20 00 20 00 |............ . .|
00000560 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000570 00 00 00 00 04 01 00 00 29 1d 00 00 00 00 00 00 |........).......|
00000580 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000007f0 00 00 00 00 00 00 00 00 00 00 00 00 1a 69 2a 09 |.............i*.|
00000800 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001000
1.2 Group descriptors组描述
在 ext4 文件系统中,Group Descriptor(块组描述符),用于描述和管理文件系统的块组(Block Group)。。Group Descriptor(块组描述符),每个块组包含文件系统中的一部分数据块和 inode,包含了block_bitmap和inode_bitmap和inode_table等
/*
* 块组描述符的结构
*/
struct ext4_group_desc
{
__le32 bg_block_bitmap_lo; /* 块位图块 */
__le32 bg_inode_bitmap_lo; /* inode 位图块 */
__le32 bg_inode_table_lo; /* inode 表块 */
__le16 bg_free_blocks_count_lo;/* 空闲块数量 */
__le16 bg_free_inodes_count_lo;/* 空闲 inode 数量 */
__le16 bg_used_dirs_count_lo; /* 目录数量 */
__le16 bg_flags; /* EXT4_BG_flags(INODE_UNINIT 等) */
__le32 bg_exclude_bitmap_lo; /* 快照排除位图 */
__le16 bg_block_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bbitmap) LE */
__le16 bg_inode_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+ibitmap) LE */
__le16 bg_itable_unused_lo; /* 未使用的 inode 数量 */
__le16 bg_checksum; /* crc16(sb_uuid+group+desc) */
__le32 bg_block_bitmap_hi; /* 块位图块 MSB */
__le32 bg_inode_bitmap_hi; /* inode 位图块 MSB */
__le32 bg_inode_table_hi; /* inode 表块 MSB */
__le16 bg_free_blocks_count_hi;/* 空闲块数量 MSB */
__le16 bg_free_inodes_count_hi;/* 空闲 inode 数量 MSB */
__le16 bg_used_dirs_count_hi; /* 目录数量 MSB */
__le16 bg_itable_unused_hi; /* 未使用的 inode 数量 MSB */
__le32 bg_exclude_bitmap_hi; /* 排除位图块 MSB */
__le16 bg_block_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+bbitmap) BE */
__le16 bg_inode_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+ibitmap) BE */
__u32 bg_reserved; /* 保留 */
};
group 0 中 Group descriptors 的数据如下:
root@OpenWrt:/# hexdump -s 4096 -n 4096 -C /dev/block/user_data
00001000 03 04 00 00 13 04 00 00 23 04 00 00 07 5c c4 1f |........#....\..|
00001010 02 00 04 00 00 00 00 00 47 e8 09 8d c4 1f 5c f5 |........G.....\.|
00001020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001030 00 00 00 00 00 00 00 00 02 02 08 06 00 00 00 00 |................|
00001040 04 04 00 00 14 04 00 00 20 06 00 00 fc 7b d0 1f |........ ....{..|
00001050 00 00 05 00 00 00 00 00 40 78 00 00 d0 1f 2f 0f |........@x..../.|
00001060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001070 00 00 00 00 00 00 00 00 1b 87 00 00 00 00 00 00 |................|
00001080 05 04 00 00 15 04 00 00 1d 08 00 00 00 80 d0 1f |................|
00001090 00 00 07 00 00 00 00 00 00 00 00 00 d0 1f eb 94 |................|
000010a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000010c0 06 04 00 00 16 04 00 00 1a 0a 00 00 fd 7b d0 1f |.............{..|
000010d0 00 00 07 00 00 00 00 00 00 00 00 00 d0 1f 95 e2 |................|
000010e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001100 07 04 00 00 17 04 00 00 17 0c 00 00 00 80 d0 1f |................|
00001110 00 00 07 00 00 00 00 00 00 00 00 00 d0 1f a5 b7 |................|
00001120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
bg_block_bitmap_lo 03 04 00 00 /* Blocks bitmap block */
bg_inode_bitmap_lo 13 04 00 00 /* Inodes bitmap block */
bg_inode_table_lo 23 04 00 00 /* Inodes table block */
1.3 Block bitmap块位图
Block bitmap 块位图用于管理块组(Block Group)中的数据块,用于跟踪和管理块组内数据块使用情况的重要数据结构。块位图是文件系统的一部分,用于记录文件系统中的每一个数据块是否已经被分配给文件或目录。
bg_block_bitmap_lo 00000403->403000 4206592
查看Block bitmap中的数据
root@OpenWrt:/# hexdump -s 4206592 -n 4096 -C /dev/block/user_data
00403000 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00403470 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 01 |................|
00403480 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00404000
root@OpenWrt:/#
1.4 Inode bitmap索引节点位图
Inode bitmap 是用于管理块组(Block Group)中的inode。用于管理和跟踪块组中inode(索引节点)分配情况的一种关键数据结构。inode是文件系统中用于存储文件和目录元数据的数据结构,包括文件的权限、所有者、大小、修改时间等信息。
bg_inode_bitmap_lo 13 04 00 00 -> 00 00 04 13 413000 4272128
root@OpenWrt:/# hexdump -s 4272128 -n 4096 -C /dev/block/user_data
00413000 ff 0f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00413010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
004133f0 00 00 00 00 00 00 00 00 00 00 ff ff ff ff ff ff |................|
00413400 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00414000
root@OpenWrt:/#
1.5 Inode table索引节点表
1.5.1 索引节点介绍
索引节点表是是一个核心数据结构,用于存储文件和目录的元数据。每个文件和目录在文件系统中都有一个对应的inode(索引节点),inode表就是存储这些索引节点的地方。
bg_inode_table_lo 23 04 00 00 -》1059
Inode size: 256:
Inode table at 1059-1567 (+1059)
- 一个索引节点的大小为256Byte
- 从 Group 0信息中可以知道Group 0 的索引表位置在1059 块的位置
1.5.2 inode.i_block介绍
inode.i_block 是 ext4 文件系统中 inode 结构的一个重要字段,用于存储文件数据块的指针。它支持直接块和间接块,允许文件系统高效地管理文件的数据位置,支持从小文件到大文件的存储需求。通过 i_block,文件系统能够准确地定位文件数据块,从而实现高效的数据读写操作。
二、通过inode定位到文件block
2.1 查看文件系统信息
其实使用dumpe2fs命令查看的ext4文件系统信息就是从superblock上的数据解析而来。
从dumpe2fs看:
root@OpenWrt:/# ./dumpe2fs /dev/block/user_data
dumpe2fs 1.45.6 (20-Mar-2020)
Filesystem volume name: <none>
Last mounted on: /data
Filesystem UUID: d9301def-b377-42b0-99d4-2f790452175e
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent 64bit flex_bg sparse_super large_file huge_file dir_nlink extra_isize metadata_csum
Filesystem flags: unsigned_directory_hash
Default mount options: user_xattr acl
Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 912128
Block count: 3644656
Reserved block count: 182232
Free blocks: 3560258
Free inodes: 911939
First block: 0
Block size: 4096
Fragment size: 4096
Group descriptor size: 64
Reserved GDT blocks: 1024
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 8144
Inode blocks per group: 509
Flex block group size: 16
Filesystem created: Fri Jan 1 00:00:18 2010
Last mount time: Fri Jan 1 00:00:18 2010
Last write time: Thu Apr 20 22:02:47 2023
Mount count: 52
Maximum mount count: -1
Last checked: Fri Jan 1 00:00:18 2010
Check interval: 0 (<none>)
Lifetime writes: 7465 kB
Reserved blocks uid: 0 (user root)
Reserved blocks gid: 0 (group root)
First inode: 11
Inode size: 256
Required extra isize: 32
Desired extra isize: 32
Journal inode: 8
Default directory hash: half_md4
Directory Hash Seed: e22b56ed-fbc1-4e22-8bcb-c0dccee6e010
Journal backup: inode blocks
Checksum type: crc32c
Checksum: 0x092a691a
Journal features: journal_incompat_revoke journal_64bit journal_checksum_v3
Journal size: 64M
Journal length: 16384
Journal sequence: 0x000001ad
Journal start: 0
Journal checksum type: crc32c
Journal checksum: 0x5ce2968d
Group 0: (Blocks 0-32767) csum 0xf55c [ITABLE_ZEROED]
Primary superblock at 0, Group descriptors at 1-2
Reserved GDT blocks at 3-1026
Block bitmap at 1027 (+1027), csum 0x0202e847
Inode bitmap at 1043 (+1043), csum 0x06088d09
Inode table at 1059-1567 (+1059)
23559 free blocks, 8132 free inodes, 2 directories, 8132 unused inodes
Free blocks: 9209-32767
Free inodes: 13-8144
Group 1: (Blocks 32768-65535) csum 0x0f2f [INODE_UNINIT, ITABLE_ZEROED]
Backup superblock at 32768, Group descriptors at 32769-32770
Reserved GDT blocks at 32771-33794
Block bitmap at 1028 (bg #0 + 1028), csum 0x871b7840
Inode bitmap at 1044 (bg #0 + 1044), csum 0x00000000
Inode table at 1568-2076 (bg #0 + 1568)
31740 free blocks, 8144 free inodes, 0 directories, 8144 unused inodes
Free blocks: 33796-65535
Free inodes: 8145-16288
该工具通过读取super block获取到各种信息。
2.2 查看索引节点信息
Inode size: 256
Group 0:
Block bitmap at 1027 (+1027), csum 0x0202e847
Inode bitmap at 1043 (+1043), csum 0x06088d09
Inode table at 1059-1567 (+1059)
- 一个索引节点的大小为256Byte
- 从 Group 0信息中可以知道Group 0 的索引表位置在1059-1567 块的位置
查看索引节点信息:
1059*4096=4337664
root@OpenWrt:/# hexdump -s 4337664 -n 4096 -C /dev/block/user_data
00423000 00 00 00 00 00 00 00 00 12 3b 3d 4b 12 3b 3d 4b |.........;=K.;=K|
00423010 12 3b 3d 4b 00 00 00 00 00 00 00 00 00 00 00 00 |.;=K............|
00423020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423070 00 00 00 00 00 00 00 00 00 00 00 00 93 0e 00 00 |................|
00423080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423100 ed 41 00 00 00 10 00 00 25 b6 79 66 fa cb 78 66 |.A......%.yf..xf|
00423110 fa cb 78 66 00 00 00 00 00 00 09 00 08 00 00 00 |..xf............|
00423120 00 00 08 00 0b 00 00 00 0a f3 01 00 04 00 00 00 |................|
00423130 00 00 00 00 00 00 00 00 01 00 00 00 f3 23 00 00 |.............#..|
00423140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423170 00 00 00 00 00 00 00 00 00 00 00 00 71 69 00 00 |............qi..|
00423180 20 00 ce 62 bc ff be 80 bc ff be 80 60 d8 e4 a6 | ..b........`...|
00423190 12 3b 3d 4b 00 00 00 00 00 00 00 00 00 00 00 00 |.;=K............|
004231a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423270 00 00 00 00 00 00 00 00 00 00 00 00 ec 54 00 00 |.............T..|
00423280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423370 00 00 00 00 00 00 00 00 00 00 00 00 06 f3 00 00 |................|
00423380 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423470 00 00 00 00 00 00 00 00 00 00 00 00 48 c9 00 00 |............H...|
00423480 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423570 00 00 00 00 00 00 00 00 00 00 00 00 9a 87 00 00 |................|
00423580 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423600 80 81 00 00 00 c0 40 00 12 3b 3d 4b 12 3b 3d 4b |......@..;=K.;=K|
00423610 12 3b 3d 4b 00 00 00 00 00 00 01 00 08 40 01 00 |.;=K.........@..|
00423620 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423650 00 00 00 00 00 00 00 00 00 00 00 00 f8 23 00 00 |.............#..|
00423660 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................|
00423670 00 00 00 00 00 00 00 00 00 00 00 00 f6 11 00 00 |................|
00423680 20 00 02 cd 00 00 00 00 00 00 00 00 00 00 00 00 | ...............|
00423690 12 3b 3d 4b 00 00 00 00 00 00 00 00 00 00 00 00 |.;=K............|
004236a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423700 80 81 00 00 00 00 00 04 13 3b 3d 4b 12 3b 3d 4b |.........;=K.;=K|
00423710 12 3b 3d 4b 00 00 00 00 00 00 01 00 00 00 02 00 |.;=K............|
00423720 00 00 08 00 00 00 00 00 0a f3 01 00 04 00 00 00 |................|
00423730 00 00 00 00 00 00 00 00 00 40 00 00 03 84 18 00 |.........@......|
00423740 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423770 00 00 00 00 00 00 00 00 00 00 00 00 f7 39 00 00 |.............9..|
00423780 20 00 e0 4c 00 00 00 00 00 00 00 00 00 00 00 00 | ..L............|
00423790 13 3b 3d 4b 00 00 00 00 00 00 00 00 00 00 00 00 |.;=K............|
004237a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423870 00 00 00 00 00 00 00 00 00 00 00 00 00 f2 00 00 |................|
00423880 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423970 00 00 00 00 00 00 00 00 00 00 00 00 d2 bc 00 00 |................|
00423980 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423a00 c0 41 00 00 00 40 00 00 25 b6 79 66 12 3b 3d 4b |.A...@..%.yf.;=K|
00423a10 12 3b 3d 4b 00 00 00 00 00 00 02 00 20 00 00 00 |.;=K........ ...|
00423a20 00 00 08 00 00 00 00 00 0a f3 01 00 04 00 00 00 |................|
00423a30 00 00 00 00 00 00 00 00 04 00 00 00 f4 23 00 00 |.............#..|
00423a40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423a70 00 00 00 00 00 00 00 00 00 00 00 00 1c aa 00 00 |................|
00423a80 20 00 7c 1f 00 00 00 00 00 00 00 00 60 d8 e4 a6 | .|.........`...|
00423a90 12 3b 3d 4b 00 00 00 00 00 00 00 00 00 00 00 00 |.;=K............|
00423aa0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423b00 a4 81 00 00 d6 00 00 00 fa cb 78 66 04 cc 78 66 |..........xf..xf|
00423b10 04 cc 78 66 00 00 00 00 00 00 01 00 08 00 00 00 |..xf............|
00423b20 00 00 08 00 01 00 00 00 0a f3 01 00 04 00 00 00 |................|
00423b30 00 00 00 00 00 00 00 00 01 00 00 00 03 84 00 00 |................|
00423b40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423b60 00 00 00 00 86 4e 1d 8f 00 00 00 00 00 00 00 00 |.....N..........|
00423b70 00 00 00 00 00 00 00 00 00 00 00 00 15 3c 00 00 |.............<..|
00423b80 20 00 7e 18 bc e1 39 1a bc e1 39 1a bc ff be 80 | .~...9...9.....|
00423b90 fa cb 78 66 bc ff be 80 00 00 00 00 00 00 00 00 |..xf............|
00423ba0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00424000
root@OpenWrt:/#
root@OpenWrt:/data# ls -li
130305 drwx------ 2 root root 4096 Jan 1 2010 ccci_cfg
521217 drwxrwxr-x 2 root root 4096 Apr 21 21:35 connsyslog
651521 drwxrwxr-x 3 root root 4096 Apr 17 13:15 debuglog
13 -rw-r--r-- 1 root root 23 Apr 21 21:37 hello_heath.txt
260609 drwxr-xr-x 2 root root 4096 Apr 17 13:15 lbs
130306 drwxr-xr-x 3 root root 4096 Apr 17 13:17 log
12 -rw-r--r-- 1 root root 214 Jun 24 2024 log.pcap
11 drwx------ 2 root root 16384 Jan 1 2010 lost+found
651522 drwxrwxr-x 3 root root 4096 Apr 17 13:15 mdlog
root@OpenWrt:/data#
如果是其他目录要经过计算找到对应的Group组,要知道Group的size,.然后除以size,得到就是Group 号,
然后在对应的里找对应inode table
一个文件系统中某个 inode(索引节点)所在的块组 (block group) 以及 inode 在块组中的索引
group = (inode_number - 1) / inodes_per_group
在 Ext2/Ext3/Ext4 文件系统中,数据和元数据(包括 inode)被划分为若干块组。每个块组包含一定数量的 inode 和数据块。将 inode 组织成块组可以提高文件系统的性能和管理效率。
inode_number: inode 是存储文件元数据的结构体,每个文件或目录都由一个 inode 表示。inode_number是某个文件或目录的 inode 编号。inodes_per_group: 每个块组中包含的 inode 数量。group: 表示 inode 所在的块组编号。
公式解释
块组计算公式:
- group = (inode_number - 1) / inodes_per_group
这个公式用于确定给定的 inode 编号属于哪个块组。
块组内的 inode 索引计算:
- inode_index=(inode_number−1)%inodes_per_group
这个公式用于确定 inode 在块组内的索引位置。
hello_heath.txt文件的Inode号为13
group=12/8144≈0
inode_index=(13−1)%8144 =12
这表明 inode 编号 13 位于第 0 个块组,并且是该块组中的第 13 个 inode(因为索引从 0 开始,所以 12 表示第 13 个 inode)。
计算地址:
1059 * 4096 +(13-1)*256 = 4,337,664 + 3072 = 4340736 = 0x423C00
2.3 定位ext4_inode位置
在 Unix 和 Linux 系统中,当使用 ls -li 命令时,列出的 inode 号是从 1 开始的,而不是从 0 开始。这是因为:
- Inode 编号从 1 开始: 文件系统中第一个有效的 inode 通常编号为 1。Inode 0 通常被保留并且不用于普通文件或目录的存储。因此,当你看到
ls -li输出时,所有列出的 inode 编号都是从 1 开始的。
定位到索引ext4_inode所在的位置:
1059 * 4096 +(13-1)*256 = 4,337,664 + 3072 = 4340736 = 0x423C00
root@OpenWrt:/data# hexdump -s 4340736 -n 4096 -C /dev/block/user_data
00423c00 a4 81 00 00 17 00 00 00 10 02 43 64 1a 02 43 64 |..........Cd..Cd|
00423c10 1a 02 43 64 00 00 00 00 00 00 01 00 08 00 00 00 |..Cd............|
00423c20 00 00 08 00 01 00 00 00 0a f3 01 00 04 00 00 00 |................|
00423c30 00 00 00 00 00 00 00 00 01 00 00 00 01 86 00 00 |................|
00423c40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423c60 00 00 00 00 7a b0 de 61 00 00 00 00 00 00 00 00 |....z..a........|
00423c70 00 00 00 00 00 00 00 00 00 00 00 00 a2 70 00 00 |.............p..|
00423c80 20 00 3c 32 1c c4 22 64 1c c4 22 64 18 c4 22 64 | .<2.."d.."d.."d|
00423c90 10 02 43 64 18 c4 22 64 00 00 00 00 00 00 00 00 |..Cd.."d........|
00423ca0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423d00 a4 81 00 00 00 00 00 00 12 02 43 64 21 02 43 64 |..........Cd!.Cd|
00423d10 21 02 43 64 21 02 43 64 00 00 00 00 00 00 00 00 |!.Cd!.Cd........|
00423d20 00 00 08 00 01 00 00 00 0a f3 00 00 04 00 00 00 |................|
00423d30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00423d60 00 00 00 00 7a 7f b6 04 00 00 00 00 00 00 00 00 |....z...........|
00423d70 00 00 00 00 00 00 00 00 00 00 00 00 cc b9 00 00 |................|
00423d80 20 00 7a de 20 ee 97 79 20 ee 97 79 1c b2 ba dd | .z. ..y ..y....|
00423d90 12 02 43 64 1c b2 ba dd 00 00 00 00 00 00 00 00 |..Cd............|
00423da0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00424c00
2.4 i_block的数据解析
fs/ext4/ext4_extents.h
quectel/ext_kernel-5.4/fs/ext4/ext4.h
ext4_inode成员i_block
struct ext4_inode {
__le16 i_mode; /* File mode */
__le16 i_uid; /* Low 16 bits of Owner Uid */
__le32 i_size_lo; /* Size in bytes */
__le32 i_atime; /* Access time */
__le32 i_ctime; /* Inode Change time */
__le32 i_mtime; /* Modification time */
__le32 i_dtime; /* Deletion Time */
__le16 i_gid; /* Low 16 bits of Group Id */
__le16 i_links_count; /* Links count */
__le32 i_blocks_lo; /* Blocks count */
__le32 i_flags; /* File flags */
union {
struct {
__le32 l_i_version;
} linux1;
struct {
__u32 h_i_translator;
} hurd1;
struct {
__u32 m_i_reserved1;
} masix1;
} osd1; /* OS dependent 1 */
__le32 i_block[EXT4_N_BLOCKS];/* Pointers to blocks */
__le32 i_generation; /* File version (for NFS) */
__le32 i_file_acl_lo; /* File ACL */
__le32 i_size_high;
__le32 i_obso_faddr; /* Obsoleted fragment address */
union {
struct {
__le16 l_i_blocks_high; /* were l_i_reserved1 */
__le16 l_i_file_acl_high;
__le16 l_i_uid_high; /* these 2 fields */
__le16 l_i_gid_high; /* were reserved2[0] */
__le16 l_i_checksum_lo;/* crc32c(uuid+inum+inode) LE */
__le16 l_i_reserved;
} linux2;
struct {
__le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
__u16 h_i_mode_high;
__u16 h_i_uid_high;
__u16 h_i_gid_high;
__u32 h_i_author;
} hurd2;
struct {
__le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
__le16 m_i_file_acl_high;
__u32 m_i_reserved2[2];
} masix2;
} osd2; /* OS dependent 2 */
__le16 i_extra_isize;
__le16 i_checksum_hi; /* crc32c(uuid+inum+inode) BE */
__le32 i_ctime_extra; /* extra Change time (nsec << 2 | epoch) */
__le32 i_mtime_extra; /* extra Modification time(nsec << 2 | epoch) */
__le32 i_atime_extra; /* extra Access time (nsec << 2 | epoch) */
__le32 i_crtime; /* File Creation time */
__le32 i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */
__le32 i_version_hi; /* high 32 bits for 64-bit version */
__le32 i_projid; /* Project ID */
};
i_block 对ext4_inode的偏移量是0x28(十进制40 可以从ext4_inode结构看出),对i_block的数据进行解析:
/*
* ext4_inode has i_block array (60 bytes total).
* The first 12 bytes store ext4_extent_header;
* the remainder stores an array of ext4_extent.
* For non-inode extent blocks, ext4_extent_tail
* follows the array.
*/
/*
* ext4_inode 有一个 i_block 数组(总共 60 字节)。
* 前 12 字节存储 ext4_extent_header;
* 其余部分存储一个 ext4_extent 数组。
* 对于非 inode 的 extent 块,ext4_extent_tail
* 跟在数组后面。
*/
/*
* Each block (leaves and indexes), even inode-stored has header.
*/
struct ext4_extent_header {
__le16 eh_magic; /* 魔数,可能用于支持不同的格式 */
__le16 eh_entries; /* 有效条目的数量 */
__le16 eh_max; /* 条目存储的容量 */
__le16 eh_depth; /* 表示是否有实际底层块 */
__le32 eh_generation; /* 树的代数 */
};

4x2+4=12往下偏移12 即ext4_extent.结构体,该结构体比较重要,物理块地址是找到存数据内容的关键。
struct ext4_extent {
__le32 ee_block; /* 该 extent 覆盖的第一个逻辑块 */
__le16 ee_len; /* 该 extent 覆盖的块数 */
__le16 ee_start_hi; /* 物理块地址的高 16 位 */
__le32 ee_start_lo; /* 物理块地址的低 32 位 */
};

ext4_extent 第一个逻辑块映射的物理块地址(即是数据内容)
0a f3 -> F3 0A >
offset 数据
0x0C ee_block 00 00 00 00
0x10 ee_len 00 01
0x12 ee_start_hi 00 00
0x14 ee_start_lo 01 86 00 00 00 00 86 01
0X8601 34305 34305 *4096=140513280 8601000
f1 1f 08 00 00081FF1 532465*4096=2180976640
2.5 比较数据
第一个逻辑块映射的物理块地址ee_start_lo(即是数据内容):
root@OpenWrt:/data# hexdump -s 140513280 -n 4096 -C /dev/block/user_data
08601000 68 65 6c 6c 6f 20 68 65 61 74 68 20 74 65 73 74 |hello heath test|
08601010 20 65 78 74 34 21 0a 00 00 00 00 00 00 00 00 00 | ext4!..........|
08601020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
08602000
root@OpenWrt:/data#
原始文件数据:
root@OpenWrt:/data# hexdump -s 0 -n 4096 -C hello_heath.txt
00000000 68 65 6c 6c 6f 20 68 65 61 74 68 20 74 65 73 74 |hello heath test|
00000010 20 65 78 74 34 21 0a | ext4!.|
00000017
root@OpenWrt:/data#
2.6 根目录查询
根目录的inode是2
如果是其他目录要经过计算找到对应的Group组,要知道Group的size,.然后除以size,得到就是Group 号,然后在对应的里找对应inode table。一个文件系统中某个 inode(索引节点)所在的块组 (block group) 以及 inode 在块组中的索引
group = (inode_number - 1) / inodes_per_group
在 Ext2/Ext3/Ext4 文件系统中,数据和元数据(包括 inode)被划分为若干块组。每个块组包含一定数量的 inode 和数据块。将 inode 组织成块组可以提高文件系统的性能和管理效率。
inode_number: inode 是存储文件元数据的结构体,每个文件或目录都由一个 inode 表示。inode_number是某个文件或目录的 inode 编号。inodes_per_group: 每个块组中包含的 inode 数量。group: 表示 inode 所在的块组编号。
公式解释
块组计算公式:
- group = (inode_number - 1) / inodes_per_group
这个公式用于确定给定的 inode 编号属于哪个块组。
块组内的 inode 索引计算:
- inode_index=(inode_number−1)%inodes_per_group
这个公式用于确定 inode 在块组内的索引位置。
Inodes per group: 8144
130306 drwxr-xr-x 3 root root 4096 Apr 17 13:17 log
/*下面分析log目录*/
group = (inode_number - 1) / inodes_per_group
16=(130306-1)/8144
(130306-1)%8144=1
这表示 inode 编号 130306 是第 16 个块组的第 2 个 inode(因为索引从 0 开始)。
Group 16: (Blocks 524288-557055) csum 0xa61e [ITABLE_ZEROED]
Block bitmap at 524288 (+0), csum 0x4fcbcb33
Inode bitmap at 524304 (+16), csum 0x30b7abd7
Inode table at 524320-524828 (+32)
24584 free blocks, 8124 free inodes, 8 directories, 8090 unused inodes
Free blocks: 532467-532468, 532474-557055
Free inodes: 130308, 130310, 130312, 130317-130342, 130346-130347, 130350, 130353, 130356, 130359-138448
/****************/
ext4_inode
524320*4096+1*256=2147614976
root@OpenWrt:/# hexdump -s 2147614976 -n 256 -C /dev/block/user_data
80020100 ed 41 00 00 00 10 00 00 25 b6 79 66 fe 46 3d 64 |.A......%.yf.F=d|
80020110 fe 46 3d 64 00 00 00 00 00 00 03 00 08 00 00 00 |.F=d............|
80020120 00 00 08 00 02 00 00 00 0a f3 01 00 04 00 00 00 |................|
80020130 00 00 00 00 00 00 00 00 01 00 00 00 f1 1f 08 00 |................|
80020140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
80020160 00 00 00 00 a9 54 0e 43 00 00 00 00 00 00 00 00 |.....T.C........|
80020170 00 00 00 00 00 00 00 00 00 00 00 00 51 e8 00 00 |............Q...|
80020180 20 00 6e bb 14 7a 1e c1 14 7a 1e c1 60 d8 e4 a6 | .n..z...z..`...|
80020190 fe 46 3d 64 14 7a 1e c1 00 00 00 00 00 00 00 00 |.F=d.z..........|
800201a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
80020200
root@OpenWrt:/#
/****************/
ext4_extent->ee_start_lo
f1 1f 08 00->00081FF1
532465x4096=2180976640
root@OpenWrt:/# hexdump -s 2180976640 -n 256 -C /dev/block/user_data
81ff1000 02 fd 01 00 0c 00 01 02 2e 00 00 00 02 00 00 00 |................|
81ff1010 0c 00 02 02 2e 2e 00 00 03 fd 01 00 dc 0f 07 02 |................|
81ff1020 61 65 65 5f 65 78 70 00 00 00 00 00 00 00 00 00 |aee_exp.........|
81ff1030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
81ff1100
root@OpenWrt:/#
root@OpenWrt:/# cd data/log/
root@OpenWrt:/data/log# ls
aee_exp
root@OpenWrt:/data/log#
三、制作ext4文件系统镜像
3.1 ext4文件系统镜像
3.1.1 生成一个空的512MiB文件
dd if=/dev/zero of=rootfs.ext4 bs=1024 count=524288 (指定每一块大小为1024字节,一共有524288块,那么就是524288 * 1024 B = 512MiB)
3.1.2 对生成的文件进行格式化
mkfs.ext4 rootfs.ext4
3.1.3 挂载此空镜像
mount -o loop rootfs.ext4 /mnt/rootfs
3.1.4 向挂载好的文件系统中写入需要加入的文件
cp everyfile /mnt/rootfs
3.1.5 卸载根文件系统
umount /mnt/rootfs
3.1.6 将镜像写入sd卡的某个分区中
dd if=rootfs.ext4 of=/dev/mmcblk0p3
3.1.7 此时挂载一下某分区即可在发现刚才复制进去的文件
如果你需要将一个预先配置好的文件系统镜像写入设备,dd 是合适的选择。如果你需要一个新的空文件系统,mkfs.ext4 是合适的选择。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)