文件空洞 File Holes

nxdong August 23, 2022 [linux] #linux

文件空洞是常规文件中包含空字符的一部分,并且不在磁盘的数据块上存储。

翻译自:https://www.halolinux.us/kernel-reference/file-holes.html

空洞文件是个由来已久的Unix文件特性。

举个例子,下面这个命令会创建一个开头字节是空洞的文件。

$ echo -n "X" | dd of=./hole bs=1024 seek=6

注意:

dd命令的bs 指定一次读写的比特数。(默认:512);会覆盖 ibs 和 obs 选项。

seek在输出开始处跳过指定的 obs 大小的块数。

现在,./hole 文件有 6145 个字符(1024*6 + 1)。然而这个文件只占用一个磁盘数据块。

# 查看文件大小
$ ls -B -l -h
Permissions  Size User      Date   Modified Name
.rw-r--r--  6,145 yourname  22 8月  12:01   hole
# 查看文件信息
$ stat hole 
文件:hole
大小:6145            块:8          IO 块:4096   普通文件
Device: 8,32    Inode: 29243374    Links: 1
权限:(0644/-rw-r--r--)  Uid:( 1000/yourname)   Gid:( 1000/yourname)
最近访问:2022-08-22 12:01:38.141803202 +0800
最近更改:2022-08-22 12:01:33.005189365 +0800
最近改动:2022-08-22 12:01:33.005189365 +0800
创建时间:2022-08-22 12:01:33.005189365 +0800
# 一个块大小是512B, IO Block=Blocks×512B   所以块数量是 8

文件空洞是为了避免磁盘空间浪费而引入的。在数据库应用中使用广泛,更一般的,还有需要对文件进行哈希的程序。

Etx2 在动态数据块申请的基础上实现了空洞文件:一个数据块只有在程序需要写数据进去的时候才会实际分配到文件上。

每个inodei_size 字段定义了程序可以看到的文件大小,包括空洞,而i_blocks字段存储了实际绑定在文件上的数据块数量(以512字节为一个块)。

在早先的dd 命令的例子中,假设./hole 文件在一个块大小为4096Ext2 分区上。相应的磁盘i_nodei_size 的值是 6145 , 而 i_blocks 字段的值是8 (因为每个4096字节的块由8个512字节的块组成)。

i_block 数组的第二个元素(相对于有文件块数量为1的块)存储分配的逻辑块的数量,而数组里其他的元素都是null

如图:

img

参考

https://www.halolinux.us/kernel-reference/file-holes.html