为了我自己的学习,我一直在尝试创建带有文件孔的文件。我创建了一个 util,它只是从 stdin 读取并写入文件,但在写入文件之前,它使用 lseek 超出文件末尾多个字节。
fh -b 20000 testfile
hello
there
启动此过程后,可以输入输入(“hello”),并将其写入测试文件,但在此之前,它会在文件末尾查找 20000 个字节。然后在写入之前,它会在写入“there”之前再次寻找文件末尾另外 20000 个字节。
我不清楚的是分配给新创建的文件的块数。如果我做
ls -ls testfile
它显示分配了 8 个块,文件大小为 40013(这是预期的)。
一个 13 字节的新文件(但没有文件洞)根据 分配 4 个块ls -ls
。我发现这实际上意味着 1 个块(一个块 2048 字节),但报告的块可以被 512 字节整除。因此,假设这是真的,则数学不会计算带有文件漏洞的文件。为什么分配了 8 个块,既然物理文件大小只有 13 个字节(而不是逻辑大小 40013),那么它不应该仍然只有 4 个吗?
我不确定我是否正确读取了块大小,其次,考虑到没有文件孔的类似大小的文件只有 4,我不明白为什么块大小是 8。
我在 ext4 文件系统上运行 Ubuntu 11.10。
答案1
Ext4可以使用1kB、2kB或4kB作为块大小;据我所知,Ubuntu 上的默认值是 4kB。请注意,这里的块是文件块的大小,对于给定的文件系统来说它是恒定的。您描述的文件有两个非零块:一个包含hello
(被一堆零包围 - 前面是 3616,后面是 474),另一个包含here
(前面是一堆零,仅包含 3148 个字节,后面是已到达文件末尾)。总共是两个 4kB 的块。
在ls
输出中,块是命令选择的任意单位ls
,默认为 1kB。有 2 个 4kB 的块分配用于包含文件数据,因此文件的分配大小为 8kB。
您的困惑可能是由于两件事造成的。首先,一个块的 2048 字节的数字是可能的,但这不是 Ubuntu(或大多数现代发行版)下的默认值,而且它显然不是您系统上的值。您可以通过运行检查块大小tune2fs -l /dev/sdz42
(使用文件系统设备的实际路径)。
其次,稀疏文件不存储完全由零组成的块。如果一个块(必须在块大小边界上对齐,至少对于包括 ext4 在内的大多数文件系统)包含零和其他内容,则整个块将存储在磁盘上。因此,在那个 40012 字节文件中(顺便说一句,你是如何得到 40013 字节的),有 4 个全零非存储块,然后是一个包含被hello
零包围的存储块,然后是另外 4 个全零非存储块。块,以及包含零和 的最终部分块there
。
请注意,您的实用程序可以用标准 shell 命令编写:
n=20000
while IFS= read -r line; do
dd bs=1 seek=$n </dev/null
echo "$line"
done >testfile