
Linux でスパース ファイルを操作する関数は何ですか? (C で説明しますが、他のシステムに関するメモも大歓迎です) 例:
- ファイルの内側の一部を削って穴を開ける
- 構造を調査する。例えば、分離された連続したデータブロックの始まりと終わりを示すペアのシーケンスを生成する。
- ブロックの範囲を再割り当てすることで(つまり、実際のデータを移動せずに)、ある時点でファイルを 2 つに分割します。
- inode やその他の関連する側面を調査しますか? (コピーオンライト方式でいくつかのブロックを複数のファイルに割り当てることは可能でしょうか?)
コンテクスト:
私の頭に浮かんだ最初の質問は、次のオプションからでしman rsync
た--sparse
。
なぜrsync
の--sparse
オプションは と競合するのでしょうか--inplace
?
ファイルシステム呼び出し API の制限ですか?
データ構造の観点から、ソース スパース ファイルが連続していないデータ ブロックのシーケンスとして見られる場合、"r" 同期によって、ソースに存在しない範囲が宛先で割り当て解除され、不足している範囲が割り当てられ、残りはそれに応じて更新されると考えられます (標準の rsync ローリング ハッシュ アルゴリズムを使用して、残りのシーケンスをすべて 1 つとして扱うか、それぞれで個別に実行する場合でも)。
参照:
man rsync
-S, --sparse Try to handle sparse files efficiently so they take up less space on the destination. Conflicts with --inplace because it's
データをスパース方式で上書きすることはできません。
答え1
スパースファイルはユーザー空間に対して透過的に設計されています。つまり、未使用領域を探索することで穴が作成され、ゼロのブロックとして読み込まれます。少なくとも現時点では、標準のユーザー空間APIを使用して検出することはできません。指摘したによるステファン・シャゼラス少なくともSolarisとLinuxは、SEEK_DATA
およびをサポートしています。SEEK_HOLE
lseek(2)
ユーザ空間プログラムがホールを見つけるためのフラグであり、これらのフラグはPOSIXに追加ある時点で。
rsync
これは、 '--sparse
とオプションの非互換性を説明しています--inplace
。既存のファイルに書き込む場合ポータブル既存のデータに穴を作成することはできません。--sparse
ファイル全体を書き換えて、(長い)ゼロのシーケンスをスキップすることで機能し、その結果、スパース ファイルをサポートする OS およびファイル システム上でスパース ファイルが生成されます。
Linuxでは、ファイルのスパース性の詳細をfiemap
ioctl、 そしてe2fsprogs
'filefrag(8)
; 見るLinux 上の詳細なスパースファイル情報文章を書く際には、fallocate(2)
(そして便利なfallocate(1)
ユーティリティ) は、既存のファイルに穴を開け、その穴がブロック全体をカバーする場合はスパースにします。サポートはファイルシステムに依存します。現在、これらの操作をサポートしているのは XFS、btrfs、ext4、および tmpfs のみです。最近のカーネル (4.1 以降) およびとてもの最近のバージョンでは、util-linux
ファイルに穴を挿入し、穴の後のコンテンツをシフトする機能をサポートしています (fallocate -i
は、util-linux
まもなくリリースされる予定の 2.30 で導入されました)。
最後の2つの質問はファイルシステムの操作に関するもので、そのような操作を実行するための汎用システムコールやioctlがあるかどうかはわかりません。reflink
-互換ファイルシステムでは、ファイルの内容を共有できます。これは、およびioctlFICLONE
FICLONERANGE
。