如何恢复 Linux 上删除的文件-ext4(3)
- UID
- 1066743
|
如何恢复 Linux 上删除的文件-ext4(3)
目录项ext4 文件系统中使用的目录项与 ext2/ext3 并没有太大的区别。所使用的结构定义如下所示:
清单5. 目录项结构定义1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| 737 /*
738 * Structure of a directory entry
739 */
740 #define EXT4_NAME_LEN 255
741
742 struct ext4_dir_entry {
743 __le32 inode; /* Inode number */
744 __le16 rec_len; /* Directory entry length */
745 __le16 name_len; /* Name length */
746 char name[EXT4_NAME_LEN]; /* File name */
747 };
748
749 /*
750 * The new version of the directory entry. Since EXT4 structures are
751 * stored in intel byte order, and the name_len field could never be
752 * bigger than 255 chars, it's safe to reclaim the extra byte for the
753 * file_type field.
754 */
755 struct ext4_dir_entry_2 {
756 __le32 inode; /* Inode number */
757 __le16 rec_len; /* Directory entry length */
758 __u8 name_len; /* Name length */
759 __u8 file_type;
760 char name[EXT4_NAME_LEN]; /* File name */
761 };
|
与 ext2/ext3 类似,当目录项被删除时,也会将该目录项的空间合并到上一个目录项中。与 ext2/ext3 不同的地方在于,在删除目录项时,该目录项中的索引节点号并没有被清空,而是得以保留了下来,这使得在恢复删除文件时,文件名就可以通过查找目录项中匹配的索引节点号得以正确恢复。详细数据如下所示:
清单6. 删除文件前后目录项的变化1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| [root@vmfc8 ext4]# ./read_dir_entry root.block.547.orig 4096
offset | inode number | rec_len | name_len | file_type | name
=================================================================
0: 2 12 1 2 .
12: 2 12 2 2 ..
24: 11 20 10 2 lost+found
44: 12 16 5 1 hello
60: 13 32 12 1 testfile.35K
80: 14 12 4 1 hole
92: 15 4004 4 1 home
[root@vmfc8 ext4]# ./read_dir_entry root.block.547.deleted 4096
offset | inode number | rec_len | name_len | file_type | name
=================================================================
0: 2 12 1 2 .
12: 2 12 2 2 ..
24: 11 36 10 2 lost+found
44: 12 16 5 1 hello
60: 13 32 12 1 testfile.35K
80: 14 12 4 1 hole
92: 15 4004 4 1 home
|
上面给出了保存根目录的数据块(547)在删除 hello 文件前后的变化,从中我们可以看出,唯一的区别在于 hello 所使用的 16 个字节的空间后来被合并到 lost+found 目录项所使用的空间中了,而索引节点号等信息都得以完整地保留了下来。清单中使用的 read_dir_entry 程序用来显示目录项中的数据,其源码可以在本文下载部分中获得。有关如何抓取保存目录数据的数据块的方法,请参看本系列文章第 2 部分的介绍。
在 ext2/3 文件系统中,一个目录下面最多可以包含 32,000 个子目录,这对于大型的企业应用来说显然是不够的。ext4 决定将其上限扩充到可以支持任意多个子目录。然而对于这种链表式的存储结构来说,目录项的查找和删除需要遍历整个目录的所有目录项,效率显然是相当低的。实际上,从 ext2 开始,文件系统的设计者引入了一棵 H-树来对目录项的 hash 值进行索引,速度可以提高 50 - 100 倍。相关内容已经超出了本文的范围,感兴趣的读者可自行参考 Linux 内核源代码中的相关实现。 |
|
|
|
|
|