目录项结构分析
目录项用来存放文件及目录的名字,它们存储在分配给目录的块中。目录项中包含文件及目录的i-节点号、目录项的长度、文件名等信息。
UFS文件系统目录项的结构见表5-41。
表5-41 UFS文件系统目录项的结构
字节偏移 | 字段长度(字节) | 字段名和定义 |
0x00~0x03 | 4 | i-节点号 |
0x04~0x05 | 2 | 目录项长度 |
0x06~0x06 | 1 | 文件类型(具体见表5-42) |
0x07~0x07 | 1 | 名字长度 |
0x08~ | 变长 | 名字 |
目录项中“文件类型”的具体分类见表5-42。
表5-42 目录项中“文件类型”的具体分类
类型值 | 类型含义 | 类型值 | 类型含义 |
0x00 | 未知 | 0x08 | 常规文件 |
0x01 | 先入先出 | 0x10 | 符号链接 |
0x02 | 字符设备 | 0x12 | 套接字 |
0x04 | 目录 | 0x14 | Whiteout |
0x06 | 块设备 |
UFS的目录项有如下特点:
①目录项的长度不是固定的,随着文件名长度的不同而不同,文件名最长为255个字符,并且使用ASCII码进行存储。
②UFS的目录项长度虽然不固定,但一定是4字节的倍数,每个目录项以4个字节为边界进行排列,即每个目录项的起始字节必须是位于目录内可被4整除的相对偏移字节处。
③另外,UFS的目录项一定需要以空字节结束。如果文件名的结束位置已经是4字节的边界,那么也需要在文件名后加一个空字节,然后再填充3个字节以达到4字节的边界。
④目录区中的前两个目录项一定是“.”和“. .”目录。“.”目录表示当前目录,“. .”目录表示父目录。
⑤每个目录项中有一个长度值指向下一个目录项,最后一个目录项的长度则指向本块的结尾处。
下面通过一个实例具体说明。
这里以一个Sparc架构的Solaris系统为例,首先看看如何定位根目录区。
第1步 定位i-节点表。
该Solaris使用UFS1文件系统,其超级块位于其切片的16号扇区。跳转到16号扇区,获得如下信息:
- 每个段的扇区数为2;
- i-节点表相对于柱面组参考位置的偏移量为32段。
我们就以第一个柱面组为例,根据以上两个参数就可以算出在第一个柱面组中i-节点表的起始扇区是32×2=64。
第2步 定位根目录区。
跳转到64号扇区就是i-节点表的开始了,其中第一个i-节点(0号i-节点)是保留的,1号i-节点为坏块i-节点,2号i-节点就是根目录的i-节点,2号i-节点的内容如图5-51所示。
图5-51 2号i-节点的内容
用模板查看一下2号i-节点的具体参数,如图5-52所示。
图5-52 2号i-节点的具体参数
从模板中可以看到,根目录目前只占用1个块,就是第一个直接块指针中记录的“848”号块。注意这里所说的“块”其实是“段”,也就是说根目录区开始于848段,换算为扇区等于1696,跳转到1696扇区,其内容如图5-53所示。
图5-53 根目录区
图5-53的根目录区中就都是根目录下的文件及文件夹的目录项了,阴影部分是前三个目录项,分别为“.”目录的目录项,“..”目录的目录项和“lost+found”目录的目录项。这三个目录项的具体含义及数值见表5-43、表5-44、表5-45。
表5-43 “.”目录项的具体含义及数值
字节偏移(相对偏移) | 字段长度(字节) | 字段名和定义 | 数值 |
0x00~0x03 | 4 | i-节点号 | 2 |
0x04~0x05 | 2 | 目录项长度 | 12 |
0x06~0x06 | 1 | 文件类型 | 0 |
0x07~0x07 | 1 | 名字长度 | 1 |
0x08~0x08 | 1 | 名字 | . |
0x09~0x0B | 3 | 填充 | 00 00 00 |
表5-44 “..”目录项的具体含义及数值
字节偏移(相对偏移) | 字段长度(字节) | 字段名和定义 | 数值 |
0x00~0x03 | 4 | i-节点号 | 2 |
0x04~0x05 | 2 | 目录项长度 | 12 |
0x06~0x06 | 1 | 文件类型 | 0 |
0x07~0x07 | 1 | 名字长度 | 2 |
0x08~0x09 | 2 | 名字 | .. |
0x0A~0x0B | 2 | 填充 | 00 00 |
表5-45 “lost+found”目录项的具体含义及数值
字节偏移(相对偏移) | 字段长度(字节) | 字段名和定义 | 数值 |
0x00~0x03 | 4 | i-节点号 | 3 |
0x04~0x05 | 2 | 目录项长度 | 20 |
0x06~0x06 | 1 | 文件类型 | 0 |
0x07~0x07 | 1 | 名字长度 | 10 |
0x08~0x11 | 10 | 名字 | lost+found |
0x12~0x13 | 2 | 填充 | 00 00 |
也可以通过WinHex的模板查看这三个目录项的参数,如图5-54、图5-55、图5-56所示。
图5-54 “.”目录项的模板
图5-55 “..”目录项的模板
图5-56 “lost+found”目录项的模板
链接和挂载点
链接
硬链接是文件或目录在同一个文件系统内的另一个名字。当建立硬链接时,将会建立一个新的目录项,它指向原始文件的i-节点,i-节点中的“链接数”也相应地增加。
软链接是一种动态链接,也是文件或目录的第二个名字,但它可以跨越不同的卷。操作系统使用一种特殊的动态链接类型文件创建软链接,在链接文件中保存目的文件或目录的完整路径。一个动态链接使用段或者60个字节的块指针保存目标文件的路径。UFS2使用64位指针代替32位指针,所以可以用120个字节保存路径。
UFS既支持软链接也支持硬链接,所以一个文件或目录可能会有多个名字。
在所有的链接没有全部被删除前,文件不会被真正删除。
每个目录区中的“.”和“..”目录项分别为当前目录和它的父目录的硬链接,因此一个目录的链接数至少是它所含有的子目录数再加2。
挂载点
在UNIX中,目录即可以用于存储文件也可以作为卷的挂载点。假设一个被命名为FS1的文件系统中有一个目录dir1,如果将文件系统FS2挂载到dir1目录,当一个用户进入dir1查看时,将会看到文件系统FS2的内容。虽然dir1目录在FS1中有属于自己的文件,但FS2挂载到dir1后,原dir1中的文件将会被屏蔽而不再显示。
但有些BSD系统能够支持“合并挂载”,当一个目录被作为挂载点后,目录中原有的文件依然可见。操作系统将挂载目录中的文件合并到被挂载卷的根目录,所以看起来就像是一个卷。
当一个文件系统以“合并挂载”方式挂载后,如果有两个文件具有同一个文件名,则在目录项中设置“whiteout”类型作为文件副本的标志,操作系统并不将其显示给用户。