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


11

私の理解では、ファイルを操作するためのLinuxにはsys_write syscallしかありません。これはファイルの内容を上書きします(最後にある場合は拡張します)。

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

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

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


4
すべての手の込んだファイル操作と同様に、このような操作は実際には見かけよりもはるかに有用ではありません。このようなことの主な用途は、データベース、エミュレーターなどの非常に特殊なアプリケーションです。通常、ファイルを「編集」する方法は、新しいファイルを作成し、ユーザーが新しいファイルの名前を古いファイルに変更する「保存」操作を行うことです。
mosvy

3
@mosvyですが、それ自体が優れているため、またはシステムがより良い方法を提供しないために、「新しいファイルを作成して名前を変更する」という概念が使用されていますか?特に、「この行を変更する(長さを変更する)」または「ここにこれらの行を挿入する」などのテキストファイル操作はかなり一般的であるため、それらの正確な機能のファイルシステム操作が存在する場合に使用されると想定できます。もちろん、それらを持たないとfsの実装がはるかに簡単になります
...-ilkkachu

1
@meuh OpenVMSは、RMS(レコード管理サービス)を介して今でも実行しています。
RonJohn

1
UNIXは、ファイルシステム内にレコード管理システムを提供することから離れる動きを始めました。
user207421

1
@ilkkachuそれ自体は良いことです、間違いなく間違いありません;-)さらに、inodeが不変である場合、ブロック共有、バージョン管理、およびほとんどすべての実装がはるかに効率的になります(そして、推論するのがはるかに簡単になります)。すべてのスクリプト言語が不変の文字列に切り替わった方法を類推して考えてみてください。ただし、ここでは短くします。カフスからファイルシステムについて話すのは難しく、いんちきのようには聞こえません;-)
mosvy

回答:


22

最近のLinuxシステムでは実際に可能ですが、ブロック(ほとんどの場合4096)で、バイト単位ではなく、一部のファイルシステム(ext4およびxfs)でのみ可能です。

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

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

[...]

ファイルスペースの縮小

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

[...]

ファイルスペースを増やす

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


1
「ただし、バイト単位ではなくブロック(4096)を使用」 -4KiBブロックはext4で非常に一般的ですが、それは保証されていません。Ext4 は1KiB、2KiB、4KiBのブロックサイズをサポートしています。ext2の時代から、Alphaプロセッサでも8KiBがサポートされていたことを覚えています。ブロックが4KiBであると想定することはできません。
marcelm

1
4k(デフォルト)は1kと2kの倍数なので、ext4で4kと仮定しても問題はありません。xfsもデフォルトで4kになりますが、4kを超えるbs(最大64kまで)をサポートするはずですが、そのようなfs しか作成できませんでした-ENOSYSなしでマウントに失敗します。とにかく、あなたは何も仮定することはできません-この機能はすべてのfsでサポートされていないので、block = 4096と言う方が良いので、読者はそれを浮かせて人々にそれを何でも可能にするのではなく、ある程度の感覚を持たせます、さらに悪いことに、それは512バイトであるか、何らかの形でvmページサイズに関連しています。
mosvy

編集した後(通常は 4KiB と言います)、私は完全に同意します!私の問題は、以前は「ブロックは常に4KiBである」と簡単に読み取られていたということでした。
marcelm

9

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

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.