恢复Ext3/Ext4中已彻底删除文件的方法
技术领域
本发明属于数据恢复领域,具体涉及一种恢复Ext3/Ext4中已彻底删除文件的方法。
背景技术
对于ext3、ext4文件系统来说,彻底删除一个文件后,由于存储文件的节点信息被破坏,使其无法通过常规方式进行恢复。Ext3\Ext4文件系统是一种日志型文件系统,对文件系统的写操作,都会通过日志文件进行预写,因此,通过日志文件,就有极大的几率恢复彻底执行删除操作的文件。目前,部分专门针对ext3,ext4文件系统的恢复技术,其删除文件的恢复率普遍都不高,且存在着以下弊端:
1.采用上下文的节点信息进行类比,使用小范围的Raw扫描方式,使得恢复的文件不确定因素增多,成功率极低。
2.采用基于.Journal的方式进行恢复,但只对完整的事务支持,被覆盖的事务无法进行数据块定位,使得恢复的成功率底下。
3.对于已被其它文件占用的节点,显得束手无策。
发明内容
本发明针对现有技术的不足,提供了一种恢复Ext3/Ext4中已彻底删除文件的方法,能够解决现有技术恢复Ext4中已彻底删除的文件成功率低的问题。
为解决以上问题,本发明采用的技术方案如下:一种恢复Ext3/Ext4中已彻底删除文件的方法,包括以下步骤:
101-根据节点号,计算节点所在的块号以及块内偏移,并读取该节点的信息,获取节点属性、节点UUID、GID、创建时间、文件版本及文件大小;
102-判断.Journal文件是否已解析完成,如果数据块链非为空,则执行104;否则,执行103;
103-解析.Journal文件,并输出.Journal中所有的数据块,输出的数据块分为两种,一种是带有逻辑块号的数据块,另一种是不带逻辑块号的数据块,输出的数据块的结构定义为【数据逻辑块号,journal文件中的相对块号,是否有逻辑块号标记】;
104-依次遍历输出的数据块链,判断输出的数据块链中,是否存在下一个带有逻辑块号的数据块,如果是,取出该数据块,执行105;否则,执行109;
105-将104取出的块号与101计算得到的块号进行比较,如果相等,执行106;否则执行104;
106-根据journal文件中的相对块号读出该数据块,并根据101中计算的节点偏移量,定位Journal中的节点信息,然后和101中的节点信息进行匹配,如果匹配成功,则执行107;如果匹配失败,则执行104;
107-根据Journal中匹配得到的节点,读取该节点中含有的文件块链,如果读取成功,执行108;否则执行104;
108-检查所有读取到的块是否都是空闲块,将不是空闲块的块号,从文件块链中去除,然后输出文件块链并结束;
109-依次遍历输出的数据块链,判断输出的数据块链中,是否存在下一个不带逻辑块号的数据块,如果是,取出该数据块,执行106;否则,结束。
作为优选,103的具体步骤如下:
301-.journal文件的节点号为8,读取8号节点中的文件块链,并将所有块的数据加载至内存,此处可一次性解析.Journal文件,读取.Journal文件的第一块,此块为.Journal文件的超级块,从超级块中获取.Journal文件的总块数,块大小,V2或V3校验和方式,是否支持64位的块号;
302-检查.Journal的游标指针是否已到.Journal文件的尾部,以判断.Journal文件是否遍历完成,如果遍历完成,执行310,如果未遍历完成执行303;
303-将游标指针下移一个块,读取下一个块的内容;
304-检查块头标记是否为0Xc03b2998,且块类型标记是否为2;如果是,代表该块为日志提交块执行302;否则,执行305;
305-检查块头标记是否为0Xc03b2998,且块类型标记是否为1;如果是,代表该块为日志描述块,执行309;否则,执行306;
306-检查块头标记是否为0Xc03b2998,且块类型标记是否为5;如果是,代表该块为日志回滚块,执行309;否则,执行307;
307-检查块头标记是否为0Xc03b2998,如果是,代表该块为日志特殊类型的块,执行302;否则,执行308;
308-标记当前数据块,设置当前数据块结构为【0,.Journal中的相对块号,false】,并将该结构插入待输出的数据块链,然后执行302;
309-根据日志描述块或回滚块中描述的原数据块号,以及当前数据块在日志中的相对位置,设置当前数据块结构为【原数据块块号,.Journal中的相对块号,true】,并将该结构插入待输出的数据块链,然后执行302;
作为优选,309的具体步骤如下:
3091-根据描述块或回滚块的结构,初始化其信息,提取该事务的事务ID,以及所包含的数据块块号;
3092-根据当前事务所包含的数据块的个数x,该个数为描述块或回滚块中提取所包含数据块的块数,其范围为1到101的整数,读取从当前块跳转到(x+1)个块后的那个块的块内容,如果该块是一个日志提交块,且日志提交块中的事务ID等于3091中获取的事务ID,则初步判断该事务是一个完整的事务,执行3093,否则,结束;
3093-将游标指针下移一个块,读取下一个块的内容;
3094-如果该块的前4个字节为.Journal块标记0Xc03b2998,则表明从该块开始,到当前事务日志提交块之前的所有数据块已遭破坏,直接结束;如果不是块标记,代表它是当前事务的数据块,执行3095;
3095-根据顺序对应的原数据块号,以及当前数据块在日志中的相对位置,设置当前数据块结构为【原数据块块号,.Journal中的相对块号,true】,并将该结构插入待输出的数据块链,然后执行3096;
3096-判断包含的原数据块号是否都按顺序遍历完成,如果完成,则结束;如果未完成,执行3093。
作为优选,106的具体步骤如下:
601-根据节点在块内偏移,从当前游标指针所指向的块中读取待比较节点的信息,获取节点属性、节点UUID、GID、创建时间、文件版本信息;
602-如果601获取的节点信息中,节点的文件大小为0且硬件链接数为0且数据块指针被清零,且对应的节点位图为空闲位则说明该节点是删除节点,即为不可用的恢复节点,返回false,执行610;如果是一个可用的恢复节点,则执行603;
603-判断101中获取的已知节点是否为已被占用的节点,如果已被占用,执行608;如果未被占用,执行604;
604-比较当前获取的节点信息中的文件版本是否与已知节点相同,如果是,执行605;如果否,返回false,执行610;
605-比较当前获取的节点信息中的创建时间是否与已知节点相同,如果是,执行606;如果否,返回false,执行610;
606-比较当前获取的节点信息中的UUID是否与已知节点相同,如果是,执行607;如果否,返回false,执行610;
607-比较当前获取的节点信息中的GID是否与已知节点相同,如果是,返回true,执行610;如果否,返回false,执行610;
608-比较当前获取的节点信息中的文件版本是否与已知节点相同,如果是,代表当前节点信息与已占用的节点信息相同,并非先前删除的节点信息,返回false,执行610;如果否,执行609;
609-比较当前获取的节点信息中的创建时间是否比已知节点的创建时间早,如果是,代表当前节点信息可能是先前删除的节点信息,返回true,执行610;如果否,返回false,执行610;
610-得到上述某一个条件分支的布尔值结果,返回该布尔值并结束。
本发明的有益效果如下:
1.对于.Journal文件,采用先查找所有事务提交的数据块的方式,以大大提高恢复的效率;
2.支持完整事务和已被覆盖事务中数据块的查找,使得参考数据块的基数大大增加,从而大大提高恢复成功率;
3.对于已被其它文件占用的节点,采用以创建时间筛选的方式,定位到之前的删除节点,使得删除文件节点被占用时,恢复该删除文件成为可能。
附图说明
图1为Ext4删除文件恢复的主流程图;
图2为103解析.Journal文件的详细流程图;
图3为309获取带原数据块号的数据块的详细流程图;
图4为106节点信息匹配的详细流程图。
具体实施方式
为使本发明的目的、技术方案及优点更加清楚明白,以下参照附图并举实施例,对本发明做进一步详细说明。
101-根据节点号,计算节点所在的块号以及块内偏移,并读取该节点的信息,获取节点属性、节点UUID、GID、创建时间、文件版本等,供后续步骤作为已知节点使用。另外,如果已知节点的文件大小为0且硬件链接数为0且数据块指针被清零,且对应的节点位图为空闲位,则说明该节点是删除节点,未被占用;否则该节点做占用处理。
102-判断.Journal文件是否已解析完成。主要是判断数据块链是否为空,如果非空,执行104;否则,执行103。
103-解析.Journal文件,并输出.Journal中所有的数据块。注意输出的数据块分为两种,一种是带有逻辑块号的数据块,另一种是不带逻辑块号的数据块。其结构定义为【数据逻辑块号,journal文件中的相对块号,是否有逻辑块号标记】,详细步骤参见图2。
104-依次遍历输出的数据块链(表),判断输出的数据块链中,是否存在下一个带有逻辑块号的数据块,如果是,取出该数据块,执行105;否则,执行109。
105-将104取出的块号与101计算得到的块号进行比较,如果相等,执行106;否则执行104。
106-根据journal文件中的相对块号读出该数据块,并根据101中计算的节点偏移量,定位Journal中的节点信息,然后和101中的节点信息进行匹配,如果匹配成功,则执行107;如果匹配失败,则执行104。详细流程参见图3.
107-根据Journal中匹配得到的节点,读取该节点中含有的文件块链,如果读取成功,执行108;否则执行104。
108-检查所有读取到的块是否都是空闲块,将不是空闲块的块号,从文件块链中去除,然后输出文件块链并结束。
109-依次遍历输出的数据块链,判断输出的数据块链中,是否存在下一个不带逻辑块号的数据块,如果是,取出该数据块,执行106;否则,结束。
103的具体步骤如下:
301-.journal文件的节点号为8,读取8号节点中的文件块链,并将所有块的数据加载至内存,此处可一次性解析.Journal文件,提高效率。读取.Journal文件的第一块,此块为.Journal文件的超级块,从超级块中获取.Journal文件的总块数,块大小,V2或V3校验和方式,是否支持64位的块号等信息。
302-检查.Journal的游标指针是否已到.Journal文件的尾部,以判断.Journal文件是否遍历完成,如果遍历完成,执行310,如果未遍历完成执行303。
303-将游标指针下移一个块,读取下一个块的内容。
304-检查块头标记是否为0Xc03b2998,且块类型标记是否为2。如果是,代表该块为日志提交块,且是一个孤立的日志提交块,此块毫无意义,因此执行302;如果不是,执行305。
305-检查块头标记是否为0Xc03b2998,且块类型标记是否为1。如果是,代表该块为日志描述块,该块一定含有一个事务包含的数据块信息,因此执行309;如果不是,执行306。
306-检查块头标记是否为0Xc03b2998,且块类型标记是否为5。如果是,代表该块为日志回滚块,该块可能含有一个回滚事务包含的数据块信息,因此执行309;如果不是,执行307。
307-检查块头标记是否为0Xc03b2998,如果是,代表该块为日志特殊类型的块,且是一个孤立的日志块,此块毫无意义,因此执行302;如果不是,执行308。
308-标记当前数据块,只知道在日志里的相对位置,但无法计算原数据块号,因此,设置当前数据块结构为【0,.Journal中的相对块号,false】,并将该结构插入待输出的数据块链。然后执行302。
309-根据日志描述块或回滚块中描述的原数据块号,以及当前数据块在日志中的相对位置,设置当前数据块结构为【原数据块块号,.Journal中的相对块号,true】,并将该结构插入待输出的数据块链。然后执行302。详细步骤详见图3。
3091-根据描述块或回滚块的结构,初始化其信息,提取该事务的事务ID,以及所包含的数据块块号。
3092-根据当前事务所包含的数据块的个数1,读取从当前块跳转到2个块后的那个块的块内容。如果该块是一个日志提交块,且日志提交块中的事务ID等于3091中获取的事务ID,则初步判断该事务是一个完整的事务,执行3093,否则,结束。
3093-将游标指针下移一个块,读取下一个块的内容。
3094-如果该块的块头4字节为.Journal块标记0Xc03b2998,则表明从该块开始,到当前事务日志提交块之前的所有数据块已遭破坏,因此结束;如果不是块标记,代表它是当前事务的数据块,因此执行3095。
3095-根据顺序对应的原数据块号,以及当前数据块在日志中的相对位置,设置当前数据块结构为【原数据块块号,.Journal中的相对块号,true】,并将该结构插入待输出的数据块链。然后执行3096。
3096-判断包含的原数据块号是否都按顺序遍历完成,如果完成,则结束;如果未完成,执行3093。
106的具体步骤如下:
601-根据节点在块内偏移,从当前游标指针所指向的块中读取待比较节点的信息,获取节点属性、节点UUID、GID、创建时间、文件版本等。
602-如果601获取的节点信息中,节点的文件大小为0且硬件链接数为0且数据块指针被清零,则说明该节点是删除节点,即为不可用的恢复节点,因此返回false,执行610;如果是一个可用的恢复节点,则执行603。
603-判断101中获取的已知节点是否为已被占用的节点。如果已被占用,执行608;如果未被占用,执行604。
604-比较当前获取的节点信息中的文件版本是否与已知节点相同,如果是,执行605;如果否,返回false,执行610。
605-比较当前获取的节点信息中的创建时间是否与已知节点相同,如果是,执行606;如果否,返回false,执行610。
606-比较当前获取的节点信息中的UUID是否与已知节点相同,如果是,执行607;如果否,返回false,执行610。
607-比较当前获取的节点信息中的GID是否与已知节点相同,如果是,返回true,执行610;如果否,返回false,执行610。
608-比较当前获取的节点信息中的文件版本是否与已知节点相同,如果是,代表当前节点信息与已占用的节点信息相同,并非先前删除的节点信息,返回false,执行610;如果否,执行609。
609-比较当前获取的节点信息中的创建时间是否比已知节点的创建时间早,如果是,代表当前节点信息可能是先前删除的节点信息,返回true,执行610;如果否,返回false,执行610。
610-得到上述某一个条件分支的布尔值结果,返回该布尔值并结束。
本领域的普通技术人员将会意识到,这里所述的实施例是为了帮助读者理解本发明的实施方法,应被理解为本发明的保护范围并不局限于这样的特别陈述和实施例。本领域的普通技术人员可以根据本发明公开的这些技术启示做出各种不脱离本发明实质的其它各种具体变形和组合,这些变形和组合仍然在本发明的保护范围内。