在分析文件删除后文件系统中各个管理结构发生的变化之前,我们再总结一下Ext3文件系统对文件的管理方式。
Ext3文件系统首先被分为若干个块组,并通过块组描述符描述这些块组,所有块组描述符组成块组描述符表,块组描述符表位于超级块的下一个块中。
文件以块为单位进行分配,每个文件都有自己的一个i-节点和目录项。i-节点中记录文件的大小、时间信息、分配地址(块指针)等信息,而目录项中则记录文件的i-节点号、文件名等信息。将目录项和i-节点结合起来分析,就能获得某个具体文件的所有信息并通过块指针定位到其数据存放的地址,块指针所指向的块内就是文件的数据。
综上所述,Ext3文件系统对文件的管理可以用一幅图来描述,如图7-52所示。
下面以Red Hat Linux系统的Ext3文件系统中一个具体文件为例,讲解其删除前和删除后的底层变化。
目标文件名为“RedHat.gif”,它是Linux系统中的一个图片文件,也是Red Hat Linux系统的Logo,该文件具体存放路径为“/etc/sysconfig/ha/web/RedHat.gif”。下面按照文件系统的管理方式定位该文件。
第1步 读取超级块和块组描述符的参数。
超级块位于文件系统的2号扇区,从超级块中获得如下参数:
块组描述符表起始于1号块,即8号扇区,从0号块组描述符中获得如下参数:
第2步 读取i-节点表。
为了读取文件“RedHat.gif”,要从根目录入手。根目录的节点为2号i-节点,2号i-节点位于0号块组的i-节点表中,该i-节点表起始0号块组的4号块,即32号扇区。跳转到32号扇区,2号i-节点的内容如图7-53所示。
用WinHex的模板查看2号i-节点的参数,如图7-54所示。
从图7-54的参数中可以看到该节点的文件类型为目录,也就是根目录;硬链接数为21,说明有21个文件指向该节点;该i-节点只用了一个直接块指针,指向514号块,对应4112扇区。
第3步 读取根目录区。
根目录的i-节点指向514号块,也即4112扇区,跳转到该扇区,就是根目录区了,里面是根目录下的文件及文件夹的目录项,如图7-55所示。
我们的目标文件路径是“/etc/sysconfig/ha/web/RedHat.gif”,所以应该找到“etc”目录的目录项,即图7-55中的阴影部分。用WinHex模板查看其具体内容,如图7-56所示。
从图7-56的参数中可以看到“etc”目录的i-节点号为195 841。
第4步 读取“etc”目录的i-节点。
“etc”目录的i-节点号为195 841,超级块中显示每个块组包含的i-节点数为16 320,所以195841号i-节点所在块组的计算方法为
(195841–1)DIV 16320=12
计算结果等于12,说明195 841号i-节点位于12号块组的i-节点表内。
那么195 841号i-节点是12号块组的i-节点表内的几号i-节点呢,可以用下面的公式计算:
[(195841–1)MOD 16320]+1=1
说明195 841号i-节点是12号块组的i-节点表内的1号i-节点。
再跳转到8号扇区的块组描述符表,读取12号块组描述符,其中记录了12号块组的i-节点表起始于393 218号块,如图7-57所示。
393 218号块对应3 145 744号扇区,跳转到3 145 744号扇区。该i-节点表内的第一个i-节点就是“etc”目录指向的195 841号i-节点,其内容如图7-58所示。
用WinHex的模板查看“etc”目录i-节点的参数,如图7-59所示。
从图7-59的参数中可以看到“etc”目录的i-节点用了两个直接块指针,指向393 728和14 591号块,其中393 728号块对应3 149 824号扇区。
第5步 读取“etc”目录的目录区。
“etc”目录的i-节点指向393 728号块,也即3 149 824号扇区,跳转到该扇区,就是“etc”目录区了,里面是“etc”目录下的文件及文件夹的目录项,如图7-60所示。
在该目录区的“.”目录项和“..”目录项之后,就是“sysconfig”目录的目录项了。用WinHex模板查看“sysconfig”目录项的具体内容,如图7-61所示。
从图7-61的参数中可以看到“sysconfig”目录的i-节点号为212 161。
第6步 读取“sysconfig”目录的i-节点。
“sysconfig”目录的i-节点号为212 161,超级块中显示每个块组包含的i-节点数为16 320,所以212 161号i-节点所在块组的计算方法为:
(212161–1)DIV 16320=13
计算结果等于13,说明212 161号i-节点位于13号块组的i-节点表内。
接下来再计算212 161号i-节点在13号块组的i-节点表内的i-节点号,可以用下面的公式计算:
[(212161–1) MOD 16320]+1=1
说明212 161号i-节点是13号块组的i-节点表内的1号i-节点。
再跳转到8号扇区的块组描述符表,读取13号块组描述符,其中记录了13号块组的i-节点表起始于425 986号块,如图7-62所示。
425 986号块对应3 407 888号扇区,跳转到3 407 888号扇区,该i-节点表内的第一个i-节点就是“sysconfig”目录指向的212 161号i-节点,其内容如图7-63所示。
用WinHex的模板查看“sysconfig”目录i-节点的参数,如图7-64所示。
从图7-64的参数中可以看到“sysconfig”目录的i-节点只用了一个直接块指针,指向426 496号块,对应3 411 968号扇区。
第7步 读取“sysconfig”目录的目录区。
“sysconfig”目录的i-节点指向426 496号块,也即3 411 968号扇区。跳转到该扇区,就是“sysconfig”目录区了,里面是“sysconfig”目录下的文件及文件夹的目录项,如图7-65所示。
“sysconfig”目录下有很多文件及目录,所以目录项很多。我们的目标文件路径是“/etc/sysconfig/ha/web/RedHat.gif”,那么应该找到“sysconfig”的下级目录“ha”的目录项,即图7-65中的阴影部分。用WinHex模板查看其具体内容,如图7-66所示。
从图7-66的参数中可以看到“ha”目录的i-节点号为312 093。
第8步 读取“ha”目录的i-节点。
“ha”目录的i-节点号为312 093,超级块中显示每个块组包含的i-节点数为16 320,所以312 093号i-节点所在块组的计算方法为
(312093–1) DIV 16320=19
计算结果等于19,说明312 093号i-节点位于19号块组的i-节点表内。
接下来再计算312 093号i-节点在19号块组的i-节点表内的i-节点号,可以用下面的公式计算:
[(312093–1) MOD 16320]+1=2013
说明312 093号i-节点是19号块组的i-节点表内的2013号i-节点。
再跳转到8号扇区的块组描述符表,读取19号块组描述符,其中记录了19号块组的i-节点表起始于622 594号块,如图7-67所示。
622 594号块对应4 980 752号扇区。跳转到4 980 752号扇区,该i-节点表内的2013号i-节点才是“ha”目录指向的312093号i-节点。因为每个i-节点大小为128字节,所以2013号i-节点在该i-节点表内的偏移量为(2013−1)×128=257536。用WinHex跳转到该i-节点表的257 536偏移处,其内容如图7-68所示。
用WinHex的模板查看“ha”目录i-节点的参数,如图7-69所示。
从图7-69的参数中可以看到“ha”目录的i-节点只用了一个直接块指针,指向633 534号块,对应5 068 272号扇区。
第9步 读取“ha”目录的目录区。
“ha”目录的i-节点指向633 534号块,也即5 068 272号扇区,跳转到该扇区,就是“ha”目录区了。里面是“ha”目录下的文件及文件夹的目录项,如图7-70所示。
“ha”目录下有很多文件及目录,所以目录项比较多。我们的目标文件路径是“/etc/ sysconfig/ha/web/RedHat.gif”,那么应该找到“ha”的下级目录“web”的目录项,即图7-70中的阴影部分。用WinHex模板查看其具体内容,如图7-71所示。
从图7-71的参数中可以看到“web”目录的i-节点号为312 099。
第10步 读取“web”目录的i-节点。
“web”目录的i-节点号为312 099,超级块中显示每个块组包含的i-节点数为16 320,所以312 099号i-节点所在块组的计算方法为:
(312099–1)DIV 16320=19
计算结果等于19,说明312 099号i-节点位于19号块组的i-节点表内。
接下来再计算312 099号i-节点在19号块组的i-节点表内的i-节点号,可以用下面的公式计算:
[(312099–1) MOD 16320]+1=2019
说明312 099号i-节点是19号块组的i-节点表内的2019号i-节点。
在前文读取过19号块组描述符,其中记录了19号块组的i-节点表起始于622 594号块,对应4 980 752号扇区。跳转到4 980 752号扇区,该i-节点表内的2019号i-节点才是“web”目录指向的312 099号i-节点。因为每个i-节点大小为128字节,所以2019号i-节点在该i-节点表内的偏移量为(2019−1)×128=258304。用WinHex跳转到该i-节点表的258 304偏移处,其内容如图7-72所示。
用WinHex的模板查看“web”目录i-节点的参数,如图7-73所示。
从图7-73的参数中可以看到“web”目录的i-节点只用了一个直接块指针,指向633 538号块,对应5 068 304号扇区。
第11步 读取“web”目录的目录区。
“web”目录的i-节点指向633 538号块,也即5 068 304扇区。跳转到该扇区,就是“web”目录区了,里面是“web”目录下的文件及文件夹的目录项,如图7-74所示。
“web”目录下有很多目录项。我们的目标文件路径是“/etc/sysconfig/ha/web/ RedHat.gif”,那么应该找到“web”的下级文件“RedHat.gif”的目录项,即图7-74中的阴影部分。用WinHex模板查看其具体内容,如图7-75所示。
从图7-75的参数中可以看到“RedHat.gif”文件的i-节点号为312 100。
第12步 读取“RedHat.gif”文件的i-节点。
“RedHat.gif”文件的i-节点号为312 100,超级块中显示每个块组包含的i-节点数为16 320,所以312 100号i-节点所在块组的计算方法为
(312100–1) DIV 16320=19
计算结果等于19,说明312 100号i-节点位于19号块组的i-节点表内。
接下来再计算312 100号i-节点在19号块组的i-节点表内的i-节点号,可以用下面的公式计算:
[(312100–1) MOD 16320]+1=2020
说明312 100号i-节点是19号块组的i-节点表内的2020号i-节点。
在前文读取过19号块组描述符,其中记录了19号块组的i-节点表起始于622 594号块,对应4 980 752号扇区。跳转到4 980 752扇区,该i-节点表内的2020号i-节点才是“RedHat.gif”文件指向的312 100号i-节点。因为每个i-节点大小为128字节,所以2020号i-节点在该i-节点表内的偏移量为(2020−1)×128=258432。用WinHex跳转到该i-节点表的258 432偏移处,其内容如图7-76所示。
用WinHex的模板查看“RedHat.gif”文件i-节点的参数,如图7-77所示。
从图7-77的参数中可以看到“RedHat.gif”文件的i-节点只用了一个直接块指针,指向633 539号块,从其i-节点的参数中还能看到文件大小为969字节。
第13步 读取“RedHat.gif”文件的数据。
“RedHat.gif”文件的数据存储在633 539号块中,对应5 068 312号扇区,该文件系统每个块大小为8个扇区,而“RedHat.gif”文件的大小为969字节,只用了633 539号块的不到两个扇区的空间。
用WinHex跳转到633 539号块,选中该块内0~968字节,并另外保存到Windows环境下的分区中,文件名就保存为“RedHat.gif”。保存后的文件如图7-78所示。
因为“RedHat.gif”文件是一个图片格式的文件,Windows环境也支持这种图片格式,所以在Windows环境中能够看到该图片的预览,也能打开该图片。
到此,Red Hat Linux系统中的“/etc/sysconfig/ha/web/RedHat.gif”文件就分析完了。
在Linux系统中将“/etc/sysconfig/ha/web/”路径下的“RedHat.gif”文件删除。删除后文件系统底层的变化分析如下:
①目录项的变化。
“RedHat.gif”文件被删除后,其目录项所占的空间会被收回。收回的方式是把“RedHat.gif”文件目录项的长度值添加到上一个目录项的报告长度当中,这样系统就会忽略对“RedHat.gif”文件目录项的读取。具体内容如图7-79所示。
图7-79中阴影部分是“about_login.php”文件的目录项,目录项中的描述长度为30H个字节,而实际上该目录项只用了1CH个字节,后面的14H个字节其实就是“RedHat.gif”文件的目录项,该目录项的长度为14H个字节,现在这个长度值被加入上一个文件“about_login.php”的目录项长度值中。
从目录项中可以看到,“RedHat.gif”文件删除后其目录项中的i-节点号并没有改变,文件名也没有改变,所以还可以根据这些信息定位到“RedHat.gif”文件的i-节点。
另外,“RedHat.gif”文件删除后,其上级目录的i-节点变化时间和修改时间都会发生相应改变。
②i-节点的变化。
“RedHat.gif”文件删除后,其i-节点的“链接数”将减1,如果链接数成为0,意味着必须回收这个i-节点;文件大小和文件的块指针也全部清零,同时将文件删除时间记录下来,如图7-80所示。
用WinHex的模板查看其具体参数,如图7-81所示。
从图7-81中可以看到,文件大小、链接数及原来的直接块指针都被清零了。
③位图的变化。
“RedHat.gif”文件删除后,其i-节点位图中的相应位设置为0以回收该i-节点,然后更新块组描述符和超级块中的空闲i-节点数。
“RedHat.gif”文件原先占用的块也需要回收,将块位图中的相应位设置为0,说明它所对应的块为空闲,同时也需要更新块组描述符和超级块中的空闲块数。
通过前文对Linux系统下Ext3文件系统中的一个文件的删除分析可以知道,文件被删除后,其目录项中的文件名和i-节点号还存在。通过这两个信息可以找到文件的i-节点,但是i-节点中的文件大小和块指针都被清零,虽然数据块不会清零,但要找到文件的存储位置是很难的,所以Ext3文件系统下文件删除后是比较难恢复的。我们可以考虑按照文件类型进行恢复,但如果文件占用的块比较多,文件不连续存储的可能性比较大,也就给恢复带来了麻烦。
提示:因为Ext3文件系统有日志功能,日志中可能会有新近删除文件的i-节点信息的备份。利用这个备份,有机会将删除的文件成功恢复。