web-dev-qa-db-ja.com

ファイル挿入システムコールがないのはなぜですか

私の理解では、ファイルを操作するためのLinuxのsys_write syscallは、ファイルの内容を上書きする(または、最後に拡張する)だけです。

Linuxのファイルにコンテンツを挿入または削除するためのシステムコールがないのはなぜですか?

現在のすべてのファイルシステムでは、ファイルを連続メモリブロックに格納する必要がないため、効率的な実装が可能です。 (ファイルは断片化されます。)

「書き込み時のコピー」または「透過的なファイル圧縮」などのファイルシステム機能では、コンテンツを挿入する現在の方法は非常に非効率的です。

11
dercolamann

最近のLinuxシステムでは実際に可能ですが、block(ほとんどの場合4096)で、byteの粒度ではなく、一部のファイルシステム(ext4およびxfs)。

fallocate(2) マンページからの引用:

int fallocate(int fd, int mode, off_t offset, off_t len);

[...]

ファイルスペースの縮小

modeFALLOC_FL_COLLAPSE_RANGEフラグ(Linux 3.15以降で使用可能)を指定すると、ホールを残さずにファイルからバイト範囲が削除されます。縮小されるバイト範囲はoffsetから始まり、lenバイト続きます。操作が完了すると、offset+lenの位置から始まるファイルの内容がoffsetの位置に追加され、ファイルはlenバイト小さくなります。

[...]

ファイルスペースの増加

modeFALLOC_FL_INSERT_RANGEフラグ(Linux 4.1以降で使用可能)を指定すると、既存のデータを上書きせずにファイルサイズ内に穴を挿入することにより、ファイルスペースが増加します。ホールはoffsetから始まり、lenバイト続きます。ファイル内に穴を挿入すると、offsetで始まるファイルの内容がlenバイトだけ上方に(つまり、より高いファイルオフセットに)シフトされます。ファイル内に穴を挿入すると、ファイルサイズがlenバイト増加します。

22
mosvy

現在のすべてのファイルシステムでは、ファイルを連続メモリブロックに保存する必要がないため、

ファイルシステムでは、ファイルを連続した領域に格納する必要がない場合があります(実際には非常に柔軟性がありません)が、通常、ファイルは固定サイズのブロック(または連続したブロックのシーケンス)に格納されます。そうすることで実装が簡単になり、ブロックは通常、基礎となるデバイスのブロックサイズの倍数になります。

したがって、任意の長さのブロックの挿入を実装すると、ファイルシステムのフォーマットと実装がかなり複雑になるか、大量のデータを移動する可能性があります。それらのどちらも本当に良いものではなく、複雑なデータ構造をファイルシステムAPIの上にあるユーザースペースに構築することができます。

9
ilkkachu