Então minha configuração é assim.
$ 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
Agora eu tenho um volume de 1,1 TB, como esperado. A sobrecarga do ext4 expandiu o arquivo esparso para 1,1 G, mas tudo bem. Agora para adicionar um arquivo.
$ dd if=/dev/urandom of=/mnt/loop/file bs=1M count=10240
$ ls -sh volume
12G volume
Legal, agora eu não quero o arquivo.
$ rm /mnt/loop/file
$ ls -sh volume
12G volume
O espaço livre ainda está ocupando espaço, como esperado, e $ fallocate -d volume
libera 1 gb.
Minha pergunta é: como posso zerar o espaço livre aqui sem expandir o volume para o tamanho total? $ dd if=/dev/zero
irá expandi-lo para o tamanho completo e, com conv=sparse
isso, criar um arquivo esparso inútil dentro do volume.
TL; DR: Existe uma maneira de losetup
ignorar gravações de blocos nulos em setores nulos, permitindo todo o resto?
Para descartar automaticamente os blocos de dados quando eles não forem mais usados, use
mount -o discard ...
. Ou você pode executar manualmentefstrim
.Esse recurso foi aparentemente adicionado ao dispositivo de loop no Linux 3.2. https://outflux.net/blog/archives/2012/02/15/discard-hole-punching-and-trim/
No caso geral,
mount -o discard
não é garantido que seja eficaz, porque alguns tipos de dispositivos podem ignorar solicitações de descarte quando estão ocupados. Isso não seria uma preocupação para o tamanho do seu arquivo esparso.Nesse caso geral - por exemplo, se você também deseja enviar solicitações de descarte para um dispositivo físico subjacente - o método mais robusto é executar
fstrim
em intervalos regulares.Não é uma solução usando ferramentas internas, mas criei um script python para fazer o que quero. Aqui está se ajudar alguém. Ainda procurando uma solução integrada, se houver.