前言linux文件系统构成文件式的文件结构Linux的一个具体文件系统对文件的访问方式Linux系统的删除方式shred与rm的区别rm删除文件的恢复
闲来无事复习了下Linux文件系统的基本构成,做下记录。主要涉及的内容有: Ext文件系统的记录方式; Linux文件系统的访问方式; rm删除的原理以及恢复方案。
现在一般使用的是Ext4格式的文件系统, 由最初的Ext2发展而来。 对于Ext2和Ext3文件系统的描述, 请见:
初窥Linux 之 ext2/ext3文件系统浅谈Linux下的EXT3文件系统Linux将文件系统抽象为一个树形结构,可以在系统内挂载多个磁盘。 Linux里面所有数据都是文件,文件夹也是文件。 文件由如下内容构成:
目录项(即文件名与Inode的映射)Inode(文件基本信息与数据块 DataBlock 索引)DataBlock以文件 /root/File 为例:
# pwd/root# stat /root/ File: `/root/' Size: 4096 Blocks: 8 IO Block: 4096 directoryDevice: fd01h/64769d Inode: 2315 Links: 14access: (0550/dr-xr-x---) Uid: ( 0/ root) Gid: ( 0/ root)Access: 2017-02-08 16:09:51.510593179 +0800Modify: 2017-02-08 16:09:45.789604414 +0800Change: 2017-02-08 16:09:45.789604414 +0800# stat File File: `File' Size: 23496 Blocks: 48 IO Block: 4096 regular fileDevice: fd01h/64769d Inode: 57115 Links: 1Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)Access: 2017-02-08 16:06:52.739596489 +0800Modify: 2017-02-08 16:06:52.739596489 +0800Change: 2017-02-08 16:06:52.739596489 +0800当前操作系统持有的磁盘, 0~1号扇区为引导扇区, 2号扇区归”/”使用。
# stat / File: `/' Size: 4096 Blocks: 8 IO Block: 4096 directoryDevice: fd01h/64769d Inode: 2 Links: 30Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)Access: 2017-02-08 13:21:03.821594978 +0800Modify: 2016-07-31 03:53:01.651715290 +0800Change: 2016-07-31 03:53:01.651715290 +0800其包含:
Innode: 通过上级目录项的Innode序列’2’找到InnodeInnode中的DataBlock又是一个目录项,其中有root -> 2315
的映射由此层层找到了/root/File
这个文件。该文件依然包含:
Innode(大小共128B):
DataBlock(文件具体内容)其中DataBlock的计算方式为:
十五个索引的大小都是4B, 共60B。前十二个直接索引直接索引到Block, Linux支持的Block大小有1K,2K, 4K间接索引就是索引的索引。可以索引 (Block大小 / 4B) * Block大小数据双间接索引是间接索引的索引,三间接索引是双间接索引的索引设置为1KB Block大小的文件系统的最大单个文件支持量16G。
Block大小设1KB为,则间接为(1KB / 4B) * 1KB = 256KB。
总空间= 直接+ 间接+ 双间接+ 三间接 总空间= 12K + 256K + 256 * 256K + 256 * 256 *256K = 16G.
其余:
Block大小 | 最大单一文件限制 |
---|---|
1KB | 16GB |
2KB | 256GB |
4KB | 2TB |
文件和文件夹的一个区别为其DataBlock里面储存的内容不一样。文件夹储存的是当前文件夹下一级所有的文件名与Innode号的映射;而文件则储存的是文件的具体内容。
新建一个空文件 空文件/root/EmptyFile 进行对比
# touch EmptyFile# stat EmptyFile File: `EmptyFile' Size: 0 Blocks: 0 IO Block: 4096 regular empty fileDevice: fd01h/64769d Inode: 57109 Links: 1Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)Access: 2017-02-08 16:09:45.789604414 +0800Modify: 2017-02-08 16:09:45.789604414 +0800Change: 2017-02-08 16:09:45.789604414 +0800它的文件名储存在 /root 的 DataBlock中。即目录项。Innode里面包含了 Inode: 57109 、Links: 1、Access: (0644/-rw-r–r–)等信息数据块大小扇区大小 0.5KB, 8个扇区凑成一个Block,所占Block: 0, Size: 0。该文件无数据。作为对比File
的Blocks: 48, Size: 23496。 一个Block只能属于一个文件。未使用完毕则空置。 每个扇区的大小、Block由多少个扇区组成、Block的大小在系统格式化的时候就已经定好。理论上不能更改。
如上一章节所诉。系统在访问文件的时候必须从根”/”开始逐级通过文件名寻找对应的Innode号,再通过Innode访问到文件的具体数据。
例如访问/home/work/File
在这里面, 每次目录的访问都会对访问用户的权限进行校验,如果没有权限都会报权限错误
了解了文件的储存形式,才能知道怎么删除它。
Linux对每一个文件都设置了两个引用计数器i_count/i_nlink
。这两个计数器是关乎Linux操作系统的,跟文件系统无太大关联。
i_count: 引用计数器,文件被一进程引用,i_count数增加 ,可以认为是当前文件使用者的数量; i_nlink: 硬链接数目(可以理解为磁盘的引用计数器),创建硬链接对应的 i_nlink 就会增加
通过分析rm
的源码得知它是调用了系统函数unlinkat
即rm的时候i_count
加一再减二。 i_nlink
减一(删除目录项中的文件名与Innode号的映射, 即无法再通过这个文件名进行索引)。
如图:
可以看到rm
的删除仅仅是去掉目录项里面的一个值而已
也就可以解释如下两个观点:
当一个进程正在访问文件时,文件依然可以被访问。 进程已经得到了文件的DataBlockls或者cat等操作必须通过文件名,而文件名已经在目录项里面删除了当文件存在其余硬链接时,文件依然可以显示。 硬链接是文件名对Innode号的映射只要映射一直存在,文件一定能访问到(rm
不会抹掉Innode
)shred 在去掉目录项的时候,还会修改Innode以及覆盖DataBlock(3次)。 此外shred还有多种模式,比如补充0,多次抹掉等等。
rm 只是删除了目录项的一个链接。只要删除之后当前数据块没有被操作。 文件是一定可以被恢复的。 见testdisk: How to use TestDisk
还有其它很多的文件恢复软件,其使用原理都是绕过文件系统,直接访问磁盘。每读取到一个Innode就根据其DataBlock索引找到被删除文件。
后续可能会写一个C的单个文件恢复的代码。写好之后贴上来。
我的代码本文若有错误敬请轻拍。
新闻热点
疑难解答