Linux ext2, ext3, ext4 文件系统解读[3]

时间:2020-11-27 19:36:11


mke2fs.conf 配置文件说明以及格式化:

mke2fs.conf文件位于/etc/mke2fs.conf(不同系统位置可能有区别,这里以CentOS 6.5为例),我们看一下其中的内容:

[defaults]

base_features = sparse_super,filetype,resize_inode,dir_index,ext_attr

enable_periodic_fsck = 1

blocksize = 4096

inode_size = 256

inode_ratio = 16384

 

[fs_types]

ext3 = {

features = has_journal

}

ext4 = {

features = has_journal,extent,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize

inode_size = 256

}

ext4dev = {

features = has_journal,extent,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize

inode_size = 256

options = test_fs=1

}

small = {

blocksize = 1024

inode_size = 128

inode_ratio = 4096

}

floppy = {

blocksize = 1024

inode_size = 128

inode_ratio = 8192

}

news = {

inode_ratio = 4096

}

largefile = {

inode_ratio = 1048576

blocksize = -1

}

largefile4 = {

inode_ratio = 4194304

blocksize = -1

}

hurd = {

     blocksize = 4096

     inode_size = 128

}

当我们使用使用mke2fs为磁盘创建文件系统时,未指定的参数就会从这个配置文件中读取相应的参数值。

这个配置文件采用一种类似INI文件的样式进行书写通过中括号来定义各个“小节”,在每个小节中,通过等号将等号右侧的值赋值给左侧的标签,通过大括号可以进一步定义子一级标签,通过分号(;)或者井号(#)来定义注释,例如:

# This line is a comment

[section1]

       tag1 = value_a

       tag1 = value_b

       tag2 = value_c

[section 2]

       tag3 = {

               subtag1 = subtag_value_a

               subtag1 = subtag_value_b

               subtag2 = subtag_value_c

       }

       tag1 = value_d

       tag2 = value_e

继续看上面的配置文件,[default]小节中定义了默认的参数,默认参数中的参数值可以被[fs_types]小节中定义的参数值覆盖,或者如果在格式化的时候指定了对应的参数,也可以覆盖掉默认参数。

default小节中的参数说明:

base_features:定义了创建文件系统时需要启用的功能

enable_periodic_fsck:指明是否需要启用定期强制自检,如果启用,则每个180天或固定每隔若干次Mount后会强制自检,可以通过mke2fs命令的-i-c参数来指定天数或Mount次数

blocksizeBlock的划分大小

inode_ratioInode的密度,即每隔多少字节会划分一个Inode

inode_sizeInode的大小

fs_types小节的重要参数说明:

在格式化的时候,可以使用-T来调用[fs_types]中定义的类型。如果未指定类型,则会根据mke2fs程序的后缀名来判断类型,例如mke2fs.ext4默认会使用ext4类型。

features:定义了一组需要启用或者禁用的功能(基于base_features),对于需要禁用的功能,在功能名称前面添加符号^,例如如果要禁用base_features中的resize_inode,则可以定义features = ^resize_inode

block_size:如果指定为负数,则mke2f会通过探索性地尝试来计算合适的Block大小

mke2fs常用参数说明:

-b:指定Block大小

-c:检测磁盘坏道,如果指定twice,则会进行读和写双重检测

-E:扩展选项,有很多可选项,具体可以参考man mke2fs

-f:指定fragment的大小

-g:每个Block Group中的Block数量

-GBlock Group的数量

-iinode_ratio的大小

-IInode的大小

-j:启用ext3 journal日志

-Jjournal日志的扩展参数,具体可以参考man mke2fs

-m:为超级用户预留出的Block数量,默认为5%

-n:如果加了这个参数,mke2fs只会计算一下文件系统创建后的各个参数,并不会实际创建文件系统(类似于预览)

-NInode数量

-O:指定文件系统要启用的功能(features),常见功能如下:

dir_index:使用经过哈希的二叉树来加速长目录的访问

extent:使用extents字段而非Block Pointer来访问Block,对大文件访问有加速作用

filetype:在目录入口(dentry结构中)存放文件类型的信息

flex_bg:允许将Block Group的元数据(BitmapInode Table)存放在Block Group中的任意位置而非按顺序排列

has_journal:类似-j参数,启用ext3 journal日志

large_file:允许文件大小超过2GB

resize_inode:为Block Group Descriptor Table预留空间,以便后续对文件系统的划分进行调整(resize2fs

sparse_super:为Super BlockGroup Descriptor建立更少的备份

uninit_bg:创建文件系统,但是并不初始化好全部的Block Group

-r:为文件系统指定revision

-t:指定fs-type,例如ext2ext3等等

-T:选择mke2fs.conf[fs_type]小节中定义的类型

-U:指定UUID

-v:指定结果输出级别为verbose

-V:打印mke2fs的版本

 

了解了上面的结构之后,我们看一下使用mkfs.ext2 -T largefile格式化一块1023GB的磁盘的输出:

[root@DanCentOS65 daniel]# mkfs.ext2 -T largefile /dev/sdd1

mke2fs 1.41.12 (17-May-2010)

Filesystem label=

OS type: Linux

Block size=4096 (log=2)

Fragment size=4096 (log=2)

Stride=0 blocks, Stripe width=0 blocks

1047552 inodes, 268173037 blocks

13408651 blocks (5.00%) reserved for the super user

First data block=0

Maximum filesystem blocks=4294967296

8184 block groups

32768 blocks per group, 32768 fragments per group

128 inodes per group

Superblock backups stored on blocks:

32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,

4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,

102400000, 214990848

 

Writing inode tables: done                           

Writing superblocks and filesystem accounting information: done

 

This filesystem will be automatically checked every 31 mounts or

180 days, whichever comes first. Use tune2fs -c or -i to override.

可以看到Block size=4096字节,一共划分了1027552Inodelargefile中定义的inode_ratio1048576,磁盘大小为1023GBInode数量:1023*1024*1024*1024/1048576=1027552),268173037Block(理论上应该划分1023*1024*1024*1024/4096=268173312Block才对,但是按照实际情况算下来,磁盘空间中有(268173312 -268173037)* 4096=1126400字节的空间并没有划分到文件系统中,查阅了很多资料,并没有得出这部分空间的去向,猜想有可能是磁盘结构划分的时候占用了,或者是由于磁盘cylinder的计算精度导致的),一共有8184Block Group,每个Group32768Block128Inode,一共有13408651Block被预留出来(预留出的5%Block的作用具体可以参考https://www.redhat.com/archives/ext3-users/2009-January/msg00026.html),除了这些信息之外,由于我们使用了sparse_super参数(默认参数),所以并不是每个Block Group都备份了Super BlockGroupDescriptor,而只有编号等于3/5/7的幂次的Group才进行了备份,Group的编号范围为0~8183,这其中符合条件的Group编号为:1 3 5 7 9 25 27 49 81 125 243 343 625729 2187 2401 3125 6561,我们将他们乘以32768Block Per Group),就得到了:

32768(1),98304(3)163840(5)229376(7)294912(9)819200(25)884736(27)1605632(49)2654208(81)4096000(125)7962624(243)11239424(343)20480000(625)23887872(729)71663616(2187)78675968(2401)102400000(3125)214990848(6561)

使用dumpe2fs具体可以看一下每个Group中的Block数量:

……

Group 0: (Blocks 0-32767)

 Primary superblock at 0, Group descriptors at 1-64

 Reserved GDT blocks at 65-1024

 Block bitmap at 1025 (+1025), Inode bitmap at 1026 (+1026)

 Inode table at 1027-1034 (+1027)

 31726 free blocks, 116 free inodes, 2 directories

 Free blocks: 1041-4095, 4097-32767

 Free inodes: 13-128

Group 1: (Blocks 32768-65535)

 Backup superblock at 32768, Group descriptors at 32769-32832

 Reserved GDT blocks at 32833-33792

 Block bitmap at 33793 (+1025), Inode bitmap at 33794 (+1026)

 Inode table at 33795-33802 (+1027)

 31733 free blocks, 128 free inodes, 0 directories

 Free blocks: 33803-65535

 Free inodes: 129-256

Group 2: (Blocks 65536-98303)

 Block bitmap at 65536 (+0), Inode bitmap at 65537 (+1)

 Inode table at 65538-65545 (+2)

 32758 free blocks, 128 free inodes, 0 directories

 Free blocks: 65546-98303

 Free inodes: 257-384

……

Group 8182: (Blocks 268107776-268140543)

 Block bitmap at 268107776 (+0), Inode bitmap at 268107777 (+1)

 Inode table at 268107778-268107785 (+2)

 32758 free blocks, 128 free inodes, 0 directories

 Free blocks: 268107786-268140543

 Free inodes: 1047297-1047424

Group 8183: (Blocks 268140544-268173036)

 Block bitmap at 268140544 (+0), Inode bitmap at 268140545 (+1)

 Inode table at 268140546-268140553 (+2)

 32483 free blocks, 128 free inodes, 0 directories

 Free blocks: 268140554-268173036

 Free inodes: 1047425-1047552

可以看到,除了最后一个Block Group之外,其他的Group都有32768Block,最后一个Group32493Block,所以一共有8183*32768+32493=268173037Block,数量和之前的总数对应。具体在看一下Group中的内容,可以看到Group 0和其他所有备份Super BlockGroup中都有1Block存放Super Block,从前面的Group Descriptor结构中可以看到每个Descriptor的结构占32字节,全部Group Descriptor一共占32*8184/4096=63.9375,即64Block,看Group 0Group 1,每个Group确实分配了64Block来存放Group Descriptor,但是还会为GDTGroup Descriptor Table)额外保留一些Block,一共加起来占1024Block(预留的Block是为了后续调整文件系统结构的时候扩展GDT使用,例如使用resize2fs调整大小等等)。此外,每个Group中还有1Block存放Data Block Bitmap,一个Block存放Inode Bitmap,以及8Block存放Inode Table8*4096/256=128)。