i-节点的结构特点
Ext3文件系统的i-节点用来存储跟文件相关的除文件名以外的所有信息。
i-节点存储的信息包括指向文件的链接数、文件大小、文件的时间信息、文件所属的用户ID、文件所属的组ID、文件内容存放地址的块指针等,这些重要信息也被称为元数据。
i-节点的结构特点如下:
①Ext3文件系统的每个块组中都有一个自己的i-节点表。i-节点表由很多i-节点组成,每个文件或者目录使用一个i-节点。
②i-节点表起始于i-节点位图所在块的下一个块。
③超级块中记录着文件系统的i-节点总数和每块组包含的i-节点数。
④每个i-节点的基本大小为128字节,但当超级块中4CH~4FH偏移处的“主版本号”被定义为“动态”时,i-节点的实际大小由超级块的58H~59H处定义,i-节点可以被定义为大于128字节的“大i-节点”。
⑤每个i-节点都有一个编号,第一个i-节点的编号为1。
⑥1~10号i-节点被系统保留,所以在超级块中会描述第一个非保留的i-节点,这个值一般是11。
⑦前10个保留的i-节点在i-节点位图中被标示为已分配,其中1号i-节点一般用于描述坏块;2号i-节点被分配给根目录使用;8号i-节点通常用于描述日志。
⑧如果已知一个i-节点号,就可以计算出该i-节点所在块组,计算方法为
(i-节点号−1)DIV 每块组i-节点数
i-节点的结构分析
Ext3文件系统每个块组中i-节点表的起始地址由其块组描述符08H~0BH偏移处描述,每个基本i-节点占用128个字节,具体结构见表7-11。
表7-11 Ext3的i-节点结构
下面对i-节点中的部分参数做进一步解释。
0x00~0x01:文件模式
“文件模式”参数占用两个字节,按照其对应的16位二进制分成三组,第一组为0~8位,描述权限标志;第二组为9~11位,用来定义可执行文件和目录;第三组为12~15位,描述文件类型。下面详细说明:
①权限标志。
16位的“文件模式”参数中0~8位用来描述用户的权限。Linux的用户被分成三类,即属主、同组用户和其他用户。属主是指i-节点中记录的用户ID的所有者;组用户以i-节点中的组ID进行区分;其他用户为除属主、同组用户以外的所有用户。用户的权限分为读、写和执行三种,权限标志中每个位代表的含义见表7-12。
表7-12 权限标志的含义
权限值(二进制) | 权限的含义 | 权限值(二进制) | 权限的含义 |
0000 0000 0000 0001 | 其他用户可执行 | 0000 0000 0010 0000 | 同组用户可读 |
0000 0000 0000 0010 | 其他用户可写 | 0000 0000 0100 0000 | 属主可执行 |
0000 0000 0000 0100 | 其他用户可读 | 0000 0000 1000 0000 | 属主可写 |
0000 0000 0000 1000 | 同组用户可执行 | 0000 0001 0000 0000 | 属主可读 |
0000 0000 0001 0000 | 同组用户可写 |
②定义可执行文件和目录。
16位的“文件模式”参数中9~11位用来定义可执行文件和目录。这三个位设置的值不同:如果是可执行文件,其执行方式就会有所不同;如果是目录,则该目录中的文件会具有特定的属性。具体定义方式见表7-13。
表7-13 可执行文件和目录的定义方式
定义值(二进制) | 定义的含义 |
0000 0010 0000 0000 | 驻留位 |
0000 0100 0000 0000 | SGID(设置组ID) |
0000 1000 0000 0000 | SUID(设置用户ID) |
如果一个可执行文件的“驻留位”设置为“1”,那么该程序关闭后其代码仍然驻留在内存中。
如果一个目录的“驻留位”设置为“1”,那么只有文件的属主才能删除该目录中的文件。
如果一个可执行文件的“SGID”位和“SUID”位设置为“1”,那么该文件的进程就根据组标识和用户标识来决定是否启动,而不由用户决定。
③文件类型。
16位的“文件模式”参数中12~15位用来定义文件类型,文件类型的各种值只能单独使用,不能同时将几个值组合起来使用。文件类型的取值及含义见表7-14。
表7-14 文件类型的取值及含义
类型值(二进制) | 类型的含义 | 类型值(二进制) | 类型的含义 |
0001 0000 0000 0000 | 先进先出(FIFO) | 1000 0000 0000 0000 | 正常文件 |
0010 0000 0000 0000 | 字符设备 | 1010 0000 0000 0000 | 动态链接 |
0100 0000 0000 0000 | 目录 | 1100 0000 0000 0000 | 套接字 |
0110 0000 0000 0000 | 块设备 |
“先进先出”也称为管道,用于两个进程间的数据传送。一个进程可以打开文件接收信息,但这些信息必须是由另一个进程写入的,在这个过程中数据存储在内存中而不是在磁盘上。
“字符设备”也称为裸设备,用于不需要一次读取一个数据块的设备,如键盘。也可以给块设备设置字符设备属性,但在不以块大小为读取和写入单位时会产生错误。i-节点通常会保存某些信息用以说明哪些块已经分配给记录设备标识符的文件。
“块设备”用于只能以块大小为单位进行读取操作的设备,如硬盘。从硬盘读取数据时,一次至少要读取512个字节,即1个扇区。如果一个程序要从块设备中读取少于1个扇区的数据,操作系统也需要读取1个扇区,然后只把需要的数据返回给程序。
“动态链接”是一种指向其他文件或目录的特殊文件,它的“内容”是所指向的目标文件的内容。动态链接其实就是文件或目录的快捷方式。
“套接字”用于进程间的双向通信,如命名管道,这些数据并不写入磁盘。
0x04~0x07:总字节数(低32位)
如果该i-节点是一个文件的i-节点,则“总字节数”是指文件的大小;如果该i-节点是一个目录的i-节点,则“总字节数”是指该目录的下级目录区的大小。
在Ext及Ext2文件系统中,用32位来描述“总字节数”这个参数,能够管理的文件大小最大为4GB;从Ext3开始,文件系统能够支持大文件,也就是用64位存储“总字节数”这个参数,该位置为低32位,高32位在0x6C~0x6F偏移处描述。
0x14~0x17:删除时间
Ext3的i-节点中描述了四个时间信息,包括最后访问时间、i-节点变化时间、最后修改时间及删除时间。
注意:这些时间信息是从1970年1月1日0时算起,并且使用格林威治标准时间,能够描述的时间上限为2038年1月18日。
提示:当新建立一个文件时,最后访问时间、i-节点变化时间、最后修改时间这三个时间值都被设置为文件创建时的当前时间,删除时间则不设置,只有在文件被删除时,才设置文件的删除时间。
0x20~0x23:标志
标志参数用来定义文件的属性,具体定义方式见表7-15。
表7-15 标志参数的含义
标志值(十六进制) | 标志的含义 | 标志值(十六进制) | 标志的含义 |
0000 0001 | 删除源文件(未使用) | 0000 0020 | 只允许增加内容 |
0000 0002 | 删除数据前保留备份(未使用) | 0000 0040 | 禁止对此文件使用“dump”命令 |
0000 0004 | 文件许可(未使用) | 0000 0080 | 不更新最后访问时间 |
0000 0008 | 同步更新,即新数据直接写盘 | 0000 1000 | 目录结构使用hash树 |
0000 0010 | 不可变文件,即内容不能更改 | 0000 2000 | 文件系统包含日志(Ext3) |
0x28~0x63:直接块指针及间接块指针
Ext3文件系统跟UFS文件系统一样,在i-节点中用块指针描述文件内容的存放地址。每个i-节点中有15个块指针,包括12个直接块指针,1个间接块指针,1个二级间接块指针和1个三级间接块指针。
12个直接块指针指向文件内容的前12个数据块地址。如果文件大于12个块,则第13个块指针是一个间接块指针,它指向的块内存放的是直接块指针而不是文件内容。
如果间接块指针指向的块依然存放不下文件所占的块号,就需要二级间接块指针了。第14个块指针是二级间接块指针,它指向的块内存放的是一级间接块指针而不是文件内容。
二级间接块指针如果还是无法满足文件的块号需求,就要用第15个块指针了。这是三级间接块指针,它指向的块内存放的是二级间接块指针而不是文件内容。
下面以一个具体实例讲解如何定位i-节点,然后具体分析i-节点。
在一个Ext3的分区中,文件系统的超级块描述了以下信息:
- 块大小为4096字节;
- 每块组包含的块数为32 768;
- 每块组包含的i-节点数为16 320;
- i-节点大小为128字节。
假设我们要访问61号i-节点,下面对61号i-节点进行定位。
第1步 定位61号i-节点所在块组。
具体算法为:(i-节点号–1)DIV每块组i-节点数=(61–1)DIV 16320=0
所以61号i-节点位于0号块组。
第2步 定位0号块组描述符。
为了确定0号块组的i-节点表起始块号,需要查看块组描述符表内的0号块组描述符。块组描述符表起始于超级块所在块的下一个块,也就是1号块。当前文件系统每块大小为4096字节,所以1号块开始于8号扇区。
用WinHex跳转到8号扇区,其中第一个块组描述符就是0号块组描述符表,其内容如图7-39所示。
图7-39 0号块组描述符
0号块组描述符的具体参数如图7-40所示。
图7-40 0号块组描述符的具体参数
从0号块组描述符中可用看到该块组的i-节点表起始于4号块,因为每块大小为8扇区,所以4号块开始于32号扇区。
第3步 定位61号i-节点。
从第二步中分析出i-节点表开始于32号扇区,32号扇区的0偏移就是1号i-节点的开始。因为每个i-节点大小为128字节,所以61号i-节点在该i-节点表中的偏移量为
(61−1)×128=7680
用WinHex跳转到该i-节点表的7680偏移处,其部分内容如图7-41所示。
图7-41 61号i-节点
61号i-节点中的参数可以通过WinHex的模板进行查看,如图7-42和7-43所示。
图7-42 61号i-节点参数模板第一部分
图7-43 61号i-节点参数模板第二部分
从61号i-节点的块指针可以看到,该文件除了占用12个直接块指针外,还用到了间接块指针。间接块指针指向了8883号块,用WinHex跳转到8883块的起始位置,其内容如图7-44所示。
图7-44 8883块内的块指针
在间接块指针指向的8883号块内存放的不是文件内容,而是直接块指针,这些块指针接在12号直接块指针之后,即从第13个块开始描述。