Pada ext4
partisi sistem file saya, saya dapat menjalankan kode berikut:
fs="/mnt/ext4"
#create sparse 100M file on ${fs}
dd if=/dev/zero \
of=${fs}/sparse100M conv=sparse seek=$((100*2*1024-1)) count=1 2> /dev/null
#show its actual used size before
echo "Before:"
ls ${fs}/sparse100M -s
#setting the sparse file up as loopback and run md5sum on loopback
losetup /dev/loop0 ${fs}/sparse100M
md5sum /dev/loop0
#show its actual used size afterwards
echo "After:"
ls ${fs}/sparse100M -s
#release loopback and remove file
losetup -d /dev/loop0
rm ${fs}/sparse100M
yang menghasilkan
Before:
0 sparse100M
2f282b84e7e608d5852449ed940bfc51 /dev/loop0
After:
0 sparse100M
Melakukan hal yang sama pada tmpfs seperti dengan:
fs="/tmp"
hasil panen
Before:
0 /tmp/sparse100M
2f282b84e7e608d5852449ed940bfc51 /dev/loop0
After:
102400 /tmp/sparse100M
yang pada dasarnya berarti bahwa sesuatu yang saya harapkan hanya membaca data, menyebabkan file jarang "meledak seperti balon"?
Saya berharap itu karena dukungan yang kurang sempurna untuk file jarang di tmpfs
filesystem, dan khususnya karena ioctl FIEMAP hilang, tetapi saya tidak yakin apa yang menyebabkan perilaku ini? Bisakah Anda memberitahu saya?
ext4
tmpfs
sparse-files
humanityANDpeace
sumber
sumber
Jawaban:
Pertama, Anda tidak sendirian dalam kebingungan tentang masalah seperti ini.
Ini tidak hanya terbatas pada
tmpfs
tetapi telah menjadi perhatian yang dikutip dengan NFSv4 .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 filesystemFALLOC_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
:fallocate
beroperasi pada tingkat file meskipun dan ketika Anda menjalankanmd5sum
terhadap perangkat blok (meminta membaca berurutan) Anda tersandung pada kesenjangan yang tepat antara bagaimanafallocate()
syscall harus beroperasi. Kita bisa melihat ini dalam aksi:Dalam aksi, menggunakan contoh Anda, kami melihat yang berikut:
Sekarang ... itu menjawab pertanyaan dasar Anda. Moto umum saya adalah "menjadi aneh" jadi saya menggali lebih dalam ...
Anda melihat bahwa hanya tindakan melakukan yang
losetup
mengubah ukuran file jarang. Jadi ini menjadi kombinasi yang menarik dari manatmpfs
, mekanisme HOLE_PUNCHfallocate
,, dan blokir perangkat berpotongan.sumber
tmpfs
mendukung file jarang dan punch_hole. Itulah yang membuatnya sangat membingungkan -tmpfs
mendukung ini, jadi mengapa pergi dan mengisi lubang jarang ketika membaca melalui perangkat loop?losetup
tidak mengubah ukuran file, tetapi itu menciptakan perangkat blok, yang pada kebanyakan sistem kemudian dipindai untuk konten seperti: apakah ada tabel partisi? apakah ada sistem file dengan UUID? saya harus membuat / dev / disk / by-uuid / symlink? Dan pembacaan tersebut telah menyebabkan bagian dari file jarang dialokasikan, karena untuk beberapa alasan misterius , tmpfs mengisi lubang pada (beberapa) bacaan.loop.c
) dan melihat bahwa ada dua fungsi yang relevan :lo_read_simple
&lo_read_transfer
. Ada beberapa perbedaan kecil dalam bagaimana mereka melakukan alokasi memori tingkat rendah ...lo_read_transfer
sebenarnya meminta non-blocking io darislab.h
(GFP_NOIO
) saat melakukanalloc_page()
panggilan.lo_read_simple()
di sisi lain tidak tampilalloc_page()
.