考虑一个稀疏的文件,其中1 s写在文件的一部分上。 我想为这1s回收磁盘上的实际空间,因为我不再需要稀疏文件的那部分。包含这些1的文件的部分应像1s本身一样成为一个“孔”。
要做到这一点,我将该区域清除为0。 这确实是在磁盘上收回块。我如何实际制作稀疏文件,好吧,稀疏?
这个问题与
,但没有接受该问题的答案。考虑以下在库存Linux服务器上运行的事件序列:
$ cat /tmp/test.c
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, char **argv) {
int fd;
char c[1024];
memset(c,argc==1,1024);
fd = open("test",O_CREAT|O_WRONLY,0777);
lseek(fd,10000,SEEK_SET);
write(fd,c,1024);
close(fd);
return 0;
}
$ gcc -o /tmp/test /tmp/test.c
$ /tmp/test
$ hexdump -C ./test
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00002710 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
*
00002b10
$ du -B1 test; du -B1 --apparent-size test
4096 test
11024 test
$ /tmp/test clear
$ hexdump -C ./test
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00002b10
$ du -B1 test; du -B1 --apparent-size test
4096 test
11024 test
# NO CHANGE IN SIZE.... HMM....
Edit-
让我进一步限定我不想重写文件,复制文件等。实际上是否可能。 目前似乎“不,不是”。 我想我正在寻找Linux(我偶然发现的讨论)。
看起来好像Linux在文件中添加了一个名为
sys_punchhole
的syscall,称为“打孔孔”。单个文件系统中的实现似乎集中在使用它来预先分配较大持续数量的块的能力上。
也有一个只专注于后者的呼叫,并且不适合孔打孔。
Edit:看起来XFS支持孔突击。检查thisthread
其他真正扭曲的选项可以是使用
FileSystemDebugger在所有间接块中进行打孔孔,这些块指向文件中的零块(也许您可以脚本脚本)。然后运行FSCK,该FSCK将纠正所有相关的块计数,收集所有孤立的块(归零的块),然后将它们放入Lost+找到的目录中(您可以删除它们以删除空间),然后在文件系统中纠正其他属性。可怕,是吗?
这种方式很便宜,但它有效。 :-p 将所有数据读取所需的孔,将其阅读到内存(或其他文件或其他任何数据)中。
将文件截断到孔的开始(fallocate
是您的朋友)。
寻找孔的尽头。
将数据重新编写。
提供了多种解决方案;但是,它们都涉及在稀疏时安装仅读取(或卸载)的FS;或制作一个新的稀疏文件,然后在原始文件的那些块上复制,然后用新的文件替换原始文件。 确实取决于您的文件系统。我们已经看到NTFS处理了这一点。我认为其他任何文件系统wikipedia列表处理透明的压缩将完全相同 - 毕竟,这相当于透明地压缩文件。
在将文件的某些区域“归零”后,您必须告诉文件系统,该新区域旨在是一个稀疏的区域。因此,在NTF的情况下,您必须再次致电该区域的DeviceIocontrol()。至少我在实用程序中这样做:“ sparse_checker”
对于我来说,更大的问题是如何解开稀疏区域的返回:)。 雷德