ファイルホールを別のファイルに割り当てることはできますか?

ファイルホールを別のファイルに割り当てることはできますか?

Unix環境の高度なプログラミングを参照すると、ファイルの終わりを見つけてそこに何かを書き込もうとすると、ファイルの脆弱性が生成されます。例えば、

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

上記の例を考慮し、ファイルに以前の内容があると仮定すると、現在のファイルオフセットはファイルの先頭の前のどこかにあります。次に、この関数を使用してファイルの終わりを見つけてlseek(上記の例のように)バッファに書き込みます。黄色いファイルサイズは100です。ご存知のように、ファイルに穴があります。

もしそうなら、Unixはこの脆弱性を他のファイルに割り当てることができますか?それとも、つまり、ホールを割り当てることができますか?

答え1

まず、ファイルの脆弱性とは何ですか?明示的に書き込まずにデータを0に設定します。seekファイルの終わりを超えて1639バイトを移動して100バイトを書き込むと、ファイルは実際には1639 + 100バイトだけ大きくなります。したがって、穴を作成しますが、穴は実際にゼロで埋められます。

脆弱性が十分に大きい場合、一部のファイルシステム(たとえばext)では、ディスクにそのブロックを割り当てないため、そのスペースを節約できます。つまり、seek1つ以上のゼロブロックを作成すると、そのブロックはディスクに割り当てられず、ファイルデータを含むブロックのリストに実際の穴があります。それが私たちが呼ぶものです。スパースファイル

ブロックのサイズはFSの形式によって異なります。これでext通常4096バイトです。つまり、1639バイトのナビゲーションを使用すると、スパースファイルは作成されず、1639個の0万ディスクに書き込まれます。 OTOH、4096バイトブロックの場合、少なくとも8191(2 * 4096 - 1)バイトを探している場合は、少なくとも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% /

ここでは、7GB以上の空き容量(まだ利用可能)があるパーティションにミリ秒で10TBファイル(すべて0)を作成しました。

関連情報