个人随笔 (Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)
参考资料
参考:https://www.nongnu.org/ext2-doc/ext2.pdf
参考:https://developer.aliyun.com/article/297657
参考:https://www.bilibili.com/read/cv17345430/
参考:https://github.com/torvalds/linux/blob/master/fs/ext2/ext2.h
参考:https://baike.baidu.com/item/e2fsprogs/6202376?fr=ge_ala
参考:https://www.easeus.com/partition-master/ext2-ext3-ext4-file-system-format-and-difference.html
1. 引言
对于ext2文件系统,我们大多数会有所耳闻的,那我们是否知道,该文件系统的内部存储结构是什么样的?
另外对于一个制定大小的文件系统,它的存储大小和文件数有约束吗?
一个10MB的ext2文件系统中:
能支持建立多少个文件?能建立1000个?10000个?和什么有关系?
能最大存储多大的内容,是满10MB吗?还是9MB?由什么来确定的?

这些问题,我们可以借助dump2fs命令的使用,来做一个初步的探究。
2. dumpe2fs查看信息
创建出loop device之后,使用命令如下,来查看ext2设备的信息。
创建loop device的方法,参考文章下面附录中方法。
            
            
              shell
              
              
            
          
          [root@ls_CxhK1nVN ~]# dumpe2fs /dev/loop0
[root@ls_CxhK1nVN ~]# dumpe2fs /dev/loop1下面是一个新创建的10MB的loop deivce的信息:
10MB的内容如下:
            
            
              shell
              
              
            
          
          [root@ls_CxhK1nVN ~]# dumpe2fs /dev/loop1
dumpe2fs 1.45.6 (20-Mar-2020)
Filesystem volume name:   <none>
Last mounted on:          /root/mongodir
Filesystem UUID:          10f36aab-aa44-4d96-8733-ee31bd6bed5f
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      ext_attr resize_inode dir_index filetype sparse_super large_file
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl
Filesystem state:         not clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              2560
Block count:              10240
Reserved block count:     512
Free blocks:              9819
Free inodes:              2549
First block:              1
Block size:               1024
Fragment size:            1024
Reserved GDT blocks:      39
Blocks per group:         8192
Fragments per group:      8192
Inodes per group:         1280
Inode blocks per group:   160
Filesystem created:       Thu Mar 14 15:11:03 2024
Last mount time:          Thu Mar 14 15:11:48 2024
Last write time:          Thu Mar 14 15:11:48 2024
Mount count:              1
Maximum mount count:      -1
Last checked:             Thu Mar 14 15:11:03 2024
Check interval:           0 (<none>)
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:               128
Default directory hash:   half_md4
Directory Hash Seed:      3bd0f015-62fe-4eb2-b815-0fed1e1ebf11
Group 0: (Blocks 1-8192)
  Primary superblock at 1, Group descriptors at 2-2
  Reserved GDT blocks at 3-41
  Block bitmap at 42 (+41)
  Inode bitmap at 43 (+42)
  Inode table at 44-203 (+43)
  7975 free blocks, 1269 free inodes, 2 directories
  Free blocks: 218-8192
  Free inodes: 12-1280
Group 1: (Blocks 8193-10239)
  Backup superblock at 8193, Group descriptors at 8194-8194
  Reserved GDT blocks at 8195-8233
  Block bitmap at 8234 (+41)
  Inode bitmap at 8235 (+42)
  Inode table at 8236-8395 (+43)
  1844 free blocks, 1280 free inodes, 0 directories
  Free blocks: 8396-10239
  Free inodes: 1281-25603. 信息解析
通过上述信息,我们关注到:
- 
Block总量,Block count * Block size = 10MB,正好是一个block1KB,10240个block。 Block count: 10240 Block size: 1024 
- 
Inode节点数量,Inode count * Inode size = 320 * 1024; 将会占用320个block,正好有2个Group,1个Group存储160个,和下面的信息相互印证了。 Inode count: 2560 Inode size: 128 Inode blocks per group: 160 Group 0: (Blocks 1-8192) Inode table at 44-203 (+43) Group 1: (Blocks 8193-10239) Inode table at 8236-8395 (+43) 
- 
关注初始创建后的空闲block数量,空闲inode数量 空闲block数量将决定存储容量的门限:9819 * 1024 = 9819KB,比10240少421个Blocks。 空闲inodes数量将决定可创建文件数量的门限:2549个文件 Free blocks: 9819 Free inodes: 2549 
- 
关注Block count / Inode count比值 = 4,不考虑文件系统占用情况下,每4KB会支持建立一个文件; 推算得出:基于10MB是2560个文件,那么1GB就是256,000, 1TB就是256,000,000个文件,支持的文件数量还是非常多的。 Block count: 10240 Block size: 1024 Inode count: 2560 
- 
Group Table的大小与Bitmap关系,Blocks per group * 1024 = 8MB。 每个Group大小是8MB;当前总大小10MB,拆分处了一个8MB,一个约2MB的group。 为什么Group大小采用8MB,这个和Bitmap有关系吗?是有关系的,Bitmap占据一个block,也就是1024字节,也是1024*8=8192比特。 Bitmap最多能指示8192个block的使用情况,而Group Table也正式采用的8192个block组成,刚好Bitmap可以全部指示出来。 Blocks per group: 8192 Block size: 1024 Group 0: (Blocks 1-8192) Group 1: (Blocks 8193-10239) 
4. 总体结构解析
基于上面的分析,侧面也可以佐证,ext2文件系统的layout结构信息

对于上面10MB的信息结构解析如下:
- filesystem boot header
 开头的1024字节,也即block 0,作为boot预留字节,通常是全0值。
| Block Offset | Length | Description | 
|---|---|---|
| byte 0 | byte 512 | boot record (if present) | 
| 512 bytes | byte 512 | additional boot record data (if present) | 
- block group 0, blocks 1 to 8192
 第0个table group,空间充足情况下,每个table group都有8192个block组成。
 地0个table group的第一个block放的是superblock,之后是block group desciptor table。
| Block Offset | Length | Description | 
|---|---|---|
| byte 1024 | 1024 bytes | superblock | 
| block 2 | 1 block | block group descriptor table | 
| block 3 | 39 block | Reserved GDT blocks | 
| block 42 | 1 block | block bitmap | 
| block 43 | 1 block | inode bitmap | 
| block 44 | 160 blocks | inode table | 
| block 204 | 7989 blocks | data blocks | 
- block group 1, blocks 8193 to 10239
 第1个table group,空间不充情况下,剩余的block组成最后一个table group。
 第1, 3, 5, 7,以及3, 5, 7的幂中会放入backup super block以及后续的block group desciptor;
 非这些的剩余group中,直接放的是block bitmap及剩余的信息,这点可以参见30MB时的第2个group的信息。
| Block Offset | Length | Description | 
|---|---|---|
| block 8193 | 1024 bytes | Backup superblock | 
| block 8194 | 1 block | block group descriptor table | 
| block 8195 | 39 block | Reserved GDT blocks | 
| block 8234 | 1 block | block bitmap | 
| block 8235 | 1 block | inode bitmap | 
| block 8236 | 160 blocks | inode table | 
| block 8396 | 1844 blocks | data blocks | 
5. 附录:对照一个30MB的文件dumpe2fs信息
下面是使用dump2fs命令,来查看一个30MB的loop device内容,可以作为和上面信息的对比参考。
30MB的内容如下:
            
            
              shell
              
              
            
          
          [root@ls_CxhK1nVN ~]# dumpe2fs /dev/loop2
dumpe2fs 1.45.6 (20-Mar-2020)
Filesystem volume name:   <none>
Last mounted on:          /root/appledir
Filesystem UUID:          66ccabd0-1809-4cae-a1d4-503fd0c5bb42
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      ext_attr resize_inode dir_index filetype sparse_super large_file
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl
Filesystem state:         not clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              7680
Block count:              30720
Reserved block count:     1536
Free blocks:              29374
Free inodes:              7669
First block:              1
Block size:               1024
Fragment size:            1024
Reserved GDT blocks:      119
Blocks per group:         8192
Fragments per group:      8192
Inodes per group:         1920
Inode blocks per group:   240
Filesystem created:       Fri Mar 15 11:40:10 2024
Last mount time:          Fri Mar 15 11:40:15 2024
Last write time:          Fri Mar 15 11:40:15 2024
Mount count:              1
Maximum mount count:      -1
Last checked:             Fri Mar 15 11:40:10 2024
Check interval:           0 (<none>)
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:               128
Default directory hash:   half_md4
Directory Hash Seed:      e5834267-fbd0-4b52-a1ea-a1ae4418bb95
Group 0: (Blocks 1-8192)
  Primary superblock at 1, Group descriptors at 2-2
  Reserved GDT blocks at 3-121
  Block bitmap at 122 (+121)
  Inode bitmap at 123 (+122)
  Inode table at 124-363 (+123)
  7815 free blocks, 1909 free inodes, 2 directories
  Free blocks: 378-8192
  Free inodes: 12-1920
Group 1: (Blocks 8193-16384)
  Backup superblock at 8193, Group descriptors at 8194-8194
  Reserved GDT blocks at 8195-8313
  Block bitmap at 8314 (+121)
  Inode bitmap at 8315 (+122)
  Inode table at 8316-8555 (+123)
  7829 free blocks, 1920 free inodes, 0 directories
  Free blocks: 8556-16384
  Free inodes: 1921-3840
Group 2: (Blocks 16385-24576)
  Block bitmap at 16385 (+0)
  Inode bitmap at 16386 (+1)
  Inode table at 16387-16626 (+2)
  7950 free blocks, 1920 free inodes, 0 directories
  Free blocks: 16627-24576
  Free inodes: 3841-5760
Group 3: (Blocks 24577-30719)
  Backup superblock at 24577, Group descriptors at 24578-24578
  Reserved GDT blocks at 24579-24697
  Block bitmap at 24698 (+121)
  Inode bitmap at 24699 (+122)
  Inode table at 24700-24939 (+123)
  5780 free blocks, 1920 free inodes, 0 directories
  Free blocks: 24940-30719
  Free inodes: 5761-76805. 附录:如何创建一个10MB的loop device
如何创建一个10MB的loop device,方法如下:
            
            
              shell
              
              
            
          
          [root@ls_CxhK1nVN ~]# dd if=/dev/zero of=./mongo bs=1K count=10240
10240+0 records in
10240+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.0155913 s, 673 MB/s
[root@ls_CxhK1nVN ~]# losetup /dev/loop1 ./mongo
[root@ls_CxhK1nVN ~]# losetup -a
/dev/loop1: [64769]:395659 (/root/mongo)
/dev/loop0: [64769]:395656 (/bean)
[root@ls_CxhK1nVN ~]# mke2fs /dev/loop1
mke2fs 1.45.4 (23-Sep-2019)
Discarding device blocks: done                            
Creating filesystem with 10240 1k blocks and 2560 inodes
Filesystem UUID: 10f36aab-aa44-4d96-8733-ee31bd6bed5f
Superblock backups stored on blocks: 
        8193
Allocating group tables: done                            
Writing inode tables: done                            
Writing superblocks and filesystem accounting information: done
[root@ls_CxhK1nVN ~]# mkdir mongodir 
[root@ls_CxhK1nVN ~]# mount -t ext2 /dev/loop1 mongodir
[root@ls_CxhK1nVN ~]# dumpe2fs /dev/loop16. 附录:如何写一个脚本来验证创建文件的个数限制:
创建文件的shell脚本如下,执行该脚本,创建文件测试文件的支持数量;
当创建文件失败时,会报错:
touch: cannot touch 'files/file_2548.txt': No space left on device
使用chatgpt输出的脚本;
            
            
              shell
              
              
            
          
          [root@ls_CxhK1nVN mongodir]# cat createfile.sh 
#!/bin/bash
# 指定文件夹路径
folder="files"
# 创建文件夹
mkdir -p "$folder"
# 循环创建1000个文件
for ((i=1; i<=2549; i++))
do
    # 生成文件名
    filename="$folder/file_$i.txt"
    
    # 创建文件
    touch "$filename"
    
    # 输出创建的文件名
    echo "Created file: $filename"
done个人随笔 (Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)