如何恢复 Linux 上删除的文件-ext4(4)
- UID
- 1066743
|
如何恢复 Linux 上删除的文件-ext4(4)
ext4 文件系统的使用目前,ext4 文件系统仍然处于非常活跃的状态,因此内核在相应的地方都加上了 DEV 标志。在编译内核时,需要在内核的 .config 文件中启用 EXT4DEV_FS 选项才能编译出最终使用的内核模块 ext4dev.ko。
由于 ext4 内部采用的关键数据结构与 ext3 并没有什么关键区别,因此在创建文件系统时依然是使用 mkfs.ext3 命令,如下所示:
清单7. 创建 ext4 文件系统,目前与创建 ext3 文件系统没什么两样1
| [root@vmfc8 ~]# mkfs.ext3 /dev/sda3
|
为了保持向前兼容性,现有的 ext3 文件系统也可以当作 ext4 文件系统进行加载,命令如下所示:
清单8. 挂载 ext4 文件系统
[root@vmfc8 ~]# mount -t ext4dev -o extents /dev/sda3 /tmp/test
-o extents 选项就是指定要启用 extent 特性。如果不在这个文件系统中执行任何写入操作,以后这个文件系统也依然可以按照 ext3 或 ext4 格式正常挂载。但是一旦在这个文件系统中写入文件之后,文件系统所使用的特性中就包含了 extent 特性,因此以后再也不能按照 ext3 格式进行挂载了,如下所示:
清单9. 写入文件前后 ext4 文件系统特性的变化据1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| [root@vmfc8 ext4]# umount /tmp/test; mount -t ext4dev -o extents /dev/sda3 /tmp/test; \
dumpe2fs /dev/sda3 > sda3.ext4_1
[root@vmfc8 ext4]# umount /tmp/test; mount -t ext4dev -o extents /dev/sda3 /tmp/test; \
echo hello > /tmp/test/hello; dumpe2fs /dev/sda3 > sda3.ext4_2
[root@vmfc8 ext4]# diff sda3.ext4_1 sda3.ext4_2
6c6
< Filesystem features: has_journal resize_inode dir_index filetype \
needs_recovery sparse_super large_file
---
> Filesystem features: has_journal resize_inode dir_index filetype \
needs_recovery extents sparse_super large_file
…
[root@vmfc8 ext4]# umount /tmp/test; mount -t ext3 /dev/sda3 /tmp/test
mount: wrong fs type, bad option, bad superblock on /dev/sda3,
missing codepage or helper program, or other error
In some cases useful info is found in syslog - try
dmesg | tail or so
e2fsprogs 工具的支持在本系列前面的文章中,我们已经初步体验了 e2fsprogs 包中提供的诸如 debugfs、dumpe2fs 之类的工具对于深入理解文件系统和磁盘数据来说是如何方便。作为一种新生的文件系统,ext4 文件系统要想得到广泛应用,相关工具的支持也非常重要。从 1.39 版本开始,e2fsprogs 已经逐渐开始加入对 ext4 文件系统的支持,例如创建文件系统使用的 mkfs.ext3 命令以后会被一个新的命令 mkfs.ext4 所取代。但是截止到本文撰写时为止,e2fsprogs 的最新版本(1.40.7)对于 ext4 的支持尚不完善,下面的例子给出了 debugfs 查看 hello 文件时的结果:
清单10. debugfs 命令对 ext4 文件系统的支持尚不完善1
2
3
4
5
6
7
8
9
10
11
12
13
14
| [root@vmfc8 ext4]# echo "hello world" > /tmp/test/hello
[root@vmfc8 ext4]# debugfs /dev/sda3
debugfs 1.40.2 (12-Jul-2007)
debugfs: stat hello
Inode: 12 Type: regular Mode: 0644 Flags: 0x80000 Generation: 827135866
User: 0 Group: 0 Size: 12
File ACL: 0 Directory ACL: 0
Links: 1 Blockcount: 8
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x47ced460 -- Thu Mar 6 01:12:00 2008
atime: 0x47ced460 -- Thu Mar 6 01:12:00 2008
mtime: 0x47ced460 -- Thu Mar 6 01:12:00 2008
BLOCKS0):127754, (1):4, (4):1, (5):28672
TOTAL: 4
|
从上面的输出结果中我们可以看出,尽管这个索引节点的 i_flags 字段值为 0x80000,表示使用 extent 方式来存储数据,而不是原有的直接/间接索引模式来存储数据(此时 i_flags 字段值为 0),但是对 i_block 数组中内容的显示却依然沿用了原有的模式。如果文件占用多个 extent 进行存储,会发现 debugfs 依然尝试将 i_block[12]、i_block[13]、i_block[14] 分别作为一级、二级和三级间接索引使用,显然从中读出的数据也是毫无意义的。
索引节点中使用的 i_flags 值是在内核源代码的 /include/linux/ext4_fs.h 中定义的,如下所示:
清单11. i_flags 值定义节选1
| #define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
|
|
|
|
|
|
|
|