所以我的设置是这样的。
$ truncate -s 1T volume
$ losetup -f --show volume
/dev/loop0
$ mkfs.ext4 /dev/loop0
$ ls -sh volume
1.1G volume
$ mount /dev/loop0 /mnt/loop
正如预期的那样,现在我有一个 1.1TB 的卷。ext4 的开销将稀疏文件扩展为 1.1G,但这很好。现在添加一个文件。
$ dd if=/dev/urandom of=/mnt/loop/file bs=1M count=10240
$ ls -sh volume
12G volume
酷,现在我不想要这个文件了。
$ rm /mnt/loop/file
$ ls -sh volume
12G volume
正如预期的那样,可用空间仍在占用空间,并$ fallocate -d volume
释放了 1gb。
我的问题是,如何在不将卷扩展到完整大小的情况下将此处的可用空间归零?$ dd if=/dev/zero
会将其扩展为完整大小,并conv=sparse
使其在卷内创建一个无用的稀疏文件。
TL;DR:有没有办法losetup
忽略将空块写入空扇区,同时允许其他所有内容?
要在不再使用数据块时自动丢弃它们,请使用
mount -o discard ...
. 或者您可以手动运行fstrim
.这个特性显然是在 Linux 3.2 中添加到循环设备中的。 https://outflux.net/blog/archives/2012/02/15/discard-hole-punching-and-trim/
在一般情况下,
mount -o discard
不保证有效,因为某些类型的设备在忙时被允许忽略丢弃请求。不过,这与稀疏文件的大小无关。在这种一般情况下 - 例如,如果您还想向底层物理设备发送丢弃请求 - 最可靠的方法是
fstrim
定期运行。不是使用内置工具的解决方案,但我编写了一个 python 脚本来做我想做的事。如果它可以帮助任何人,那就是这里。仍在寻找内置解决方案,如果有的话。