Pertama, Anda tidak sendirian dalam kebingungan tentang masalah seperti ini.
Ini tidak hanya terbatas pada tmpfs
tetapi telah menjadi perhatian yang dikutip dengan
NFSv4 .
Jika aplikasi membaca 'lubang' dalam file yang jarang, sistem file mengubah blok kosong menjadi blok "nyata" yang diisi dengan nol, dan mengembalikannya ke aplikasi.
Ketika md5sum
sedang mencoba untuk memindai file secara eksplisit memilih untuk melakukan ini dalam
urutan berurutan , yang masuk akal berdasarkan apa yang berusaha dilakukan md5sum.
Karena ada "lubang" pada dasarnya pada file, pembacaan berurutan ini akan (dalam beberapa situasi) menyebabkan operasi copy on write untuk mengisi file. Ini kemudian masuk ke masalah yang lebih dalam seputar apakah atau tidak fallocate()
seperti yang diterapkan dalam mendukung filesystem FALLOC_FL_PUNCH_HOLE
.
Untungnya, tidak hanya tmpfs
mendukung ini tetapi ada mekanisme untuk "menggali" lubang kembali.
Dengan menggunakan utilitas CLI fallocate
kita dapat dengan sukses mendeteksi dan menggali kembali lubang-lubang ini.
Sesuai man 1 fallocate
:
-d, --dig-holes
Detect and dig holes. This makes the file sparse in-place, without
using extra disk space. The minimum size of the hole depends on
filesystem I/O block size (usually 4096 bytes). Also, when using
this option, --keep-size is implied. If no range is specified by
--offset and --length, then the entire file is analyzed for holes.
You can think of this option as doing a "cp --sparse" and then
renaming the destination file to the original, without the need for
extra disk space.
See --punch-hole for a list of supported filesystems.
fallocate
beroperasi pada tingkat file meskipun dan ketika Anda menjalankan md5sum
terhadap perangkat blok (meminta membaca berurutan) Anda tersandung pada kesenjangan yang tepat antara bagaimana fallocate()
syscall harus beroperasi. Kita bisa melihat ini dalam aksi:
Dalam aksi, menggunakan contoh Anda, kami melihat yang berikut:
$ fs=$(mktemp -d)
$ echo ${fs}
/tmp/tmp.ONTGAS8L06
$ dd if=/dev/zero of=${fs}/sparse100M conv=sparse seek=$((100*2*1024-1)) count=1 2>/dev/null
$ echo "Before:" "$(ls ${fs}/sparse100M -s)"
Before: 0 /tmp/tmp.ONTGAS8L06/sparse100M
$ sudo losetup /dev/loop0 ${fs}/sparse100M
$ sudo md5sum /dev/loop0
2f282b84e7e608d5852449ed940bfc51 /dev/loop0
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 102400 /tmp/tmp.ONTGAS8L06/sparse100M
$ fallocate -d ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 0 /tmp/tmp.ONTGAS8L06/sparse100M
Sekarang ... itu menjawab pertanyaan dasar Anda. Moto umum saya adalah "menjadi aneh" jadi saya menggali lebih dalam ...
$ fs=$(mktemp -d)
$ echo ${fs}
/tmp/tmp.ZcAxvW32GY
$ dd if=/dev/zero of=${fs}/sparse100M conv=sparse seek=$((100*2*1024-1)) count=1 2>/dev/null
$ echo "Before:" "$(ls ${fs}/sparse100M -s)"
Before: 0 /tmp/tmp.ZcAxvW32GY/sparse100M
$ sudo losetup /dev/loop0 ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 1036 /tmp/tmp.ZcAxvW32GY/sparse100M
$ sudo md5sum ${fs}/sparse100M
2f282b84e7e608d5852449ed940bfc51 /tmp/tmp.ZcAxvW32GY/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 1036 /tmp/tmp.ZcAxvW32GY/sparse100M
$ fallocate -d ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 520 /tmp/tmp.ZcAxvW32GY/sparse100M
$ sudo md5sum ${fs}/sparse100M
2f282b84e7e608d5852449ed940bfc51 /tmp/tmp.ZcAxvW32GY/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 520 /tmp/tmp.ZcAxvW32GY/sparse100M
$ fallocate -d ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 516 /tmp/tmp.ZcAxvW32GY/sparse100M
$ fallocate -d ${fs}/sparse100M
$ sudo md5sum ${fs}/sparse100M
2f282b84e7e608d5852449ed940bfc51 /tmp/tmp.ZcAxvW32GY/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 512 /tmp/tmp.ZcAxvW32GY/sparse100M
$ fallocate -d ${fs}/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 0 /tmp/tmp.ZcAxvW32GY/sparse100M
$ sudo md5sum ${fs}/sparse100M
2f282b84e7e608d5852449ed940bfc51 /tmp/tmp.ZcAxvW32GY/sparse100M
$ echo "After:" "$(ls ${fs}/sparse100M -s)"
After: 0 /tmp/tmp.ZcAxvW32GY/sparse100M
Anda melihat bahwa hanya tindakan melakukan yang losetup
mengubah ukuran file jarang. Jadi ini menjadi kombinasi yang menarik dari mana tmpfs
, mekanisme HOLE_PUNCH fallocate
,, dan blokir perangkat berpotongan.