Lostupをスパースファイルとして効率的に作成できますか?

Lostupをスパースファイルとして効率的に作成できますか?

だから私の設定はこんな感じです。

$ 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 volume1GBが確保されています。

私の質問は、ボリュームをフルサイズに拡張せずに空きスペースをゼロにする方法です。$ dd if=/dev/zeroフルサイズに拡張され、conv=sparseボリューム内に無駄なスパースファイルが作成されます。

losetup重要な要約:空のブロックで空のセクタへの書き込みを無視し、他のすべてを許可する方法はありますか?

答え1

データブロックが使用されなくなったときに自動的に削除するには、を使用しますmount -o discard ...。または手動で実行することもできますfstrim

この機能はLinux 3.2のループデバイスに追加されているようです。 https://outflux.net/blog/archives/2012/02/15/discard-hole-punching-and-trim/


通常、mount -o discard一部のタイプのデバイスは、使用中に削除要求を無視する可能性があるため、動作は保証されません。ただし、これはスパースファイルのサイズには影響しません。

この一般的な場合(たとえば、基本物理デバイスに削除要求を送信したい場合など)、最も信頼できる方法はfstrim定期的に実行することです。

答え2

組み込みツールを使用したソリューションではありませんが、目的のタスクを実行するためにPythonスクリプトを作成しました。誰かが役に立つならここにあります。組み込みのソリューションがあれば、まだ探しています。

#!/usr/bin/python3.6
import os
import time
import sys

if len(sys.argv) != 2:
    print('''Usage: {} <file>

Fills a file/device with zeros, with efficiencies for sparse files.'''.format(sys.argv[0]))
    exit(1)

f = open(sys.argv[1], 'rb+', 0)

bs = 1024*1024 # block size
zb = b'\0'*bs  # a full block of zeros

lasttime = round(time.time())
block = f.read(bs)
while len(block) == bs:

    # IFF a block contains non-zero characters, zero it
    if block != zb:
        f.seek(-bs, os.SEEK_CUR)
        f.write(zb)
    block = f.read(bs)

    # Print the processed bytes every second
    # Could add a MB/s or % completed, but too lazy
    if round(time.time()) != lasttime:
        print(f.tell())
        lasttime = round(time.time())

# Hit EOF, might have missed bytes at the end
# Zero last block unconditionally, too lazy to check if its required
f.seek(-bs, os.SEEK_CUR)
f.write(zb)
f.close()

関連情報