相关链接:ext2/ext3文件系统原理
漫谈Linux标准的文件系统(Ext2/Ext3/Ext4)
首先通过创建一个64M虚拟磁盘,在对该虚拟磁盘格式化成ext3文件系统,分析里面的数据
dd if=/dev/zero of=./test.img bs=1M count=64
将虚拟磁盘绑定在/dev/loop1设备上
将磁盘格式化为block size=1024,卷标为“HelloFs”,ext3文件系统
mkfs.ext3 -L HelloFs -b 1024 /dev/loop1
通过which mkfs.ext3和rpm -qf /usr/sbin/mkfs.ext3命令可查找mkfs.ext3命令在哪个软件包里面,其他命令也可以通过同样方法得知在哪个软件包下面:
根据软件包信息,下载源代码
通过file /usr/sbin/mkfs.ext3命令得到以下信息,是一个可执行文件
通过tune2fs -l /dev/loop1 命令读取磁盘信息
ext2/ext3文件系统的存储布局如下图所示:
dumpe2fs /dev/loop1命令可查看更详细的磁盘信息,具体到每个组的里面的信息,与上图的存储布局情况一致
block0 :存放MBR信息
通过以下命令读取磁盘block0的数据并显示出来
dd if=/dev/loop1 bs=1024 count=1 skip=0 | xxd | less
读取到block0的数据全是0,因为这是一个虚拟磁盘,所以读到的是全0
如果读取真实磁盘,就可以读到数据
从Group0的信息中可知:
Primary superblock在block1
Group 0 的组描述信息在block2
...
通过以下命令读取block1中的数据:
dd if=/dev/loop1 bs=1024 count=1 skip=1 | xxd | less
结合 ext3_super_block 结构体分析super block数据
inode_count = 0x4000 =16384
block_count=010000=65536
与通过dumpe2fs /dev/loop1 命令得到的
Inode count: 16384
Block count: 65536
是一致的:
Blocksize=1<<(s_log_block_size+10) = 1<<(1+10)=1024Byte
Group N = (s_blocks_count-s_first_data_block-1)/s_blocks_per_group+1 = (65536-1-1)/8192+1=7+1=8
同样方法分析其他字段数据。
group描述信息ext3_group_desc -> block 2
0x0102=258
0x0103=259
0x0104=260
block_bimap ->block 258
inode bitmap ->block 259 ,前面11个Inode已被使用,所以前11个Inode对应的bit被置“1”
Inode table at 260-515 (+259),其实块号为260
inode结构中,__le32 i_block[EXT3_N_BLOCKS]记录了该inode对应文件数据所在的所有块号的信息。但是inode的大小只有128bytes或256bytes(ext4),如果一个文件太大,block数量很有可能会超过inode可记录的数量,为此,inode记录block号码的区域被设计为12个直接、一个间接、一个双间接、一个三间接记录区。所谓的间接就是拿一个block来作为block号码记录区,只有最后一个间接才会真正用来记录block号码,其他的间接层,都只是依次引用。
计算单文件最大容量
每个block号码为数字,需要占据4bytes。
-
假设block的单位容量为1K,每个block能记录的block号码为1k/4=256。
- 12个直接容量 = 12 * 1k =12k
- 单间接容量 = 256 * 1k = 256k
- 双间接容量 = 256 * 256 * 1k = 65536k
- 三间接容量 = 256 * 256 * 256 * 1k = 16777216k
- 单文件最大总量 = 12个直接容量 + 单间接容量 + 双间接容量 + 三间接容量 = (12 + 256 + 65536 + 16777216) / (1024 * 1024) = 16.06G
-
假设block的单位容量为2K,每个block能记录的block号码为2k/4=512。
- 12个直接容量 = 12 * 2k =24k
- 单间接容量 = 512 * 2k = 1024k
- 双间接容量 = 512 * 512 * 2k = 524288k
- 三间接容量 = 512 * 512 * 512 * 2k = 268435456k
- 单文件最大总量 = 12个直接容量 + 单间接容量 + 双间接容量 + 三间接容量 = (24 + 1024 + 524288 + 268435456) / (1024 * 1024) = 256.50G
-
假设block的单位容量为4K,每个block能记录的block号码为4k/4=1024。
- 同理,单文件最大总量 = 12个直接容量 + 单间接容量 + 双间接容量 + 三间接容量 = 4.00T
Linux标准的文件系统限制表
但是使用debugfs 工具查看到"."和“..”的inode值都是2,而mount之后,"."和“..”的inode值为什么不一样?
对着block260数据,inode 2的数据才是有效的
0x0204=516 ,对应根目录的数据,根目录下的文件名在这里都能看到
添加一个文件后再读取inode 2对应的数据信息:
这里目录下的文件名又是如何组织的?与struct ext2_dir_entry_2对照起来,只有第一个文件信息能与struct ext2_dir_entry_2结构对应上,后面的文件都对应不上该结构。希望有清楚这块的朋友帮忙解答下!!!
0x0401=1025
是写入到testFile中的数据
在根目录下创建一个目录dir1,对应的inode号为6145
对照 dumpe2fs /dev/loop1 命令查到的文件系统信息,可知inode号6145分配在group 3中
inode号6145对应的Inode表在24836块上
0x6204=25092
在dir1目录下创建2个文件f1和f2
再看Inode表信息
0x6405=25605
block 25605中的数据是刚刚写入到f1文件的数据
0x6406=25606