Files

我們可以將文件孔分配給另一個文件嗎?

  • August 25, 2017

參考 Unix 環境中的高級程式,當我們試圖越過文件末尾並在那裡寫一些東西時,就會創建文件漏洞。例如,

   int x = lseek(fd,1639,SEEK_END);
   int y = write(fd,buff,100);

如果您考慮上面的範例並假設文件以前有一些內容,那麼目前文件偏移量在文件開頭之前的某個位置。現在,我們使用lseek函式查找文件末尾(如上例所示),並將大小為 100 的緩衝區緩衝區寫入文件。如您所知,將在文件中創建一個孔。

那麼,Unix 可以將這個漏洞分配給其他文件嗎?或者,換句話說,這個洞是否可以分配?

首先,什麼是文件中的孔?它只是將數據設置為零而沒有明確寫成這樣。當您seek超過文件末尾 1639 個字節並在其中寫入 100 個字節時,您的文件實際上增長了 1639+100 個字節。因此,您創建了一個孔,但該孔實際上是用零填充的。

如果那個洞足夠大,某些文件系統(如ext)允許您通過不在磁碟上分配相應的塊來節省該空間。即,如果您seek要寫入一個或多個零塊,則不會在磁碟上分配這些塊,這將在包含文件數據的塊列表中創建真正的漏洞。這就是我們所說的稀疏文件

塊的大小取決於 FS 的格式化方式。現在ext它通常是 4096 字節。這意味著使用 1639 字節查找,您不會創建稀疏文件,並且 1639 個零只會寫入磁碟。OTOH,具有 4096 字節塊,如果您尋求至少 8191 (2 * 4096 - 1) 個字節,則可以確定至少創建一個。

由於實際上並未分配塊並用零填充,這使您的文件使用更少的磁碟空間並且您的寫入操作要快得多。當然,要回答您的問題,剩餘的磁碟空間可用於其他文件。

實際上,最好的展示不需要 C 程序:

$ df -h /tmp
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda4        38G   28G  7.5G  80% /

$ time dd of=/tmp/foo bs=1M seek=$((1024*1024*10)) count=0
0+0 records in
0+0 records out
0 bytes (0 B) copied, 4.741e-05 s, 0.0 kB/s

real    0m0.002s
user    0m0.000s
sys 0m0.000s

$ ls -lh /tmp/foo
-rw-r--r-- 1 xhienne xhienne 10T Aug 25 20:08 /tmp/foo

$ df -h /tmp
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda4        38G   28G  7.5G  80% /

在這裡,我在一個只有 7+ GB 可用空間(仍然可用)的分區上在幾毫秒內創建了一個 10 TB 的文件(全是零)。

引用自:https://unix.stackexchange.com/questions/388361